關於 PHP, Linux, Open Source 及個人生活記載的網誌。
RSS icon
  • PHP 取得用戶真實 IP

    Posted on December 12th, 2011 Sam Tang No comments

    要用 PHP 取得用戶的 IP 十分容易,只要用 $_SERVER['REMOTE_ADDR'] 變數就可以知道用戶的 IP,但如果用戶使用了 proxy server 上網的話,$_SERVER['REMOTE_ADDR'] 只會得到 proxy 的 IP 地址。

    以下方法會使用 $_SERVER["HTTP_CLIENT_IP"] 及 $_SERVER["HTTP_X_FORWARDED_FOR"] 解決這個問題:

    PHP:
    1. <?php
    2. if (!empty($_SERVER["HTTP_CLIENT_IP"])){
    3.     $ip = $_SERVER["HTTP_CLIENT_IP"];
    4. }elseif(!empty($_SERVER["HTTP_X_FORWARDED_FOR"])){
    5.     $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
    6. }else{
    7.     $ip = $_SERVER["REMOTE_ADDR"];
    8. }
    9.  
    10. echo $ip;
    11. ?>


  • PHP 的 is_file() 及 file_exists()

    Posted on December 9th, 2011 Sam Tang No comments

    PHP 的 is_file() 及 file_exists() 都是用作檢查檔案是否存在,它們的分別是 file_exists() 輸入的參數是目錄也會回傳 TRUE,而 is_file() 則只會對檔案回傳 TRUE:

    PHP:
    1. <?php
    2. $path ="/path/to/dir";
    3. if(file_exists($path)){
    4.     echo "File Exists";
    5. }else{
    6.     echo "File not Exists";
    7.  
    8. // 如果 /path/to/dir 目錄存在會回傳 TRUE
    9. ?>

    但如果用 is_file(),即使 /path/to/dir 目錄存在,仍然會回傳 FALSE:

    PHP:
    1. <?php
    2. $path ="/path/to/dir";
    3. if(is_file($path)){
    4.     echo "File Exists";
    5. }else{
    6.     echo "File not Exists";
    7.  
    8. // 如果 /path/to/dir 目錄存在會回傳 TRUE
    9. ?>


  • MySQL 的流程控制

    Posted on December 8th, 2011 Sam Tang No comments

    MySQL 有幾個流程控制的 functions,以下是它們的用法簡介:

    1. CASE
    它就如同其他程式語言的 switch:

    // Below will return zero
    SELECT CASE 0 WHEN 0 THEN 'zero' WHEN 1 THEN 'one' ELSE 'no one' END;

    // Below will return true
    SELECT CASE WHEN 5>2 THEN 'true' ELSE 'false' END;

    2. IF
    SELECT IF(expr1,expr2,expr3);

    // return yes
    SELECT IF(1<5,'yes','no');

    3. IFNULL
    SELECT IFNULL(expr1, expr2);

    // Return 5
    SELECT IFNULL(5,0);

    // Return 10
    SELECT IFNULL(NULL,10);

    4. NULLIF
    SELECT NULLIF(expr1,expr2);

    // Return NULL
    SELECT NULLIF(5,5);

    // Return 10
    SELECT NULLIF(10,4);


  • MySQL 的 Safe Update Mode

    Posted on December 6th, 2011 Sam Tang No comments

    最近要更新 MySQL 資料表內其中一個欄位的所有資料,只是用以下這個 SQL 指令:

    UPDATE table_name SET field_name=0;

    個 MySQL 回傳的錯誤訊息為:

    "You are using safe update mode and you tried to update a table without a WHERE clause that uses a KEY column."

    查看一些資料後,原來 MySQL 在沒有 WHERE 或 LIMIT 條件下會拒絕執行 UPDATE 或 DELETE querey,即使是沒有 KEY column 的 WHERE 條件也會拒絕執行。

    要解決就是將 MySQL 的 Safe Update Mode 關閉:

    SET SQL_SAFE_UPDATES=0;
    UPDATE table_name SET field_name=0;

    如果要重新啟用 Safe Update Mode,只要執行:

    SET SQL_SAFE_UPDATES=1;


  • Shell Script 輸出顏色文字

    Posted on August 24th, 2011 Sam Tang No comments

    Shell Script 可以控制輸出文字的顏色,做法與 html 相似,只是使用 ANSI escape codes 控制顏色輸出。顯示顏色文字的格式如下:

    \33[ 樣式 ; 文字顏色 ; 背景顏色 m
    輸出文字
    \33[0m

    以下是樣色、顏色及背景顏色的可供選項:

    文字樣式:
    0 一般樣式
    1 粗體
    4 加底線
    5 灰底
    7 文字及背景顏色對調

    文字顏色:
    30 黑色
    31 紅色
    32 綠色
    33 黃色
    34 藍色
    35 紫色
    36 青綠
    37 白色

    背景顏色:
    40 黑色
    41 紅色
    42 綠色
    43 黃色
    44 藍色
    45 紫色
    46 青綠
    47 白色

    以下是在 shell script 的使用方法:

    PHP:
    1. #!/bin/bash
    2. # This script echoes colors and codes
    3.  
    4. echo -e "\n\033[4;31mLight Colors\033[0m  \t\t\033[1;4;31mDark Colors\033[0m"
    5.  
    6. echo -e "\e[0;30;47m Black    \e[0m 0;30m \t\e[1;30;40m Dark Gray  \e[0m 1;30m"
    7. echo -e "\e[0;31;47m Red      \e[0m 0;31m \t\e[1;31;40m Dark Red   \e[0m 1;31m"
    8. echo -e "\e[0;32;47m Green    \e[0m 0;32m \t\e[1;32;40m Dark Green \e[0m 1;32m"
    9. echo -e "\e[0;33;47m Brown    \e[0m 0;33m \t\e[1;33;40m Yellow     \e[0m 1;33m"
    10. echo -e "\e[0;34;47m Blue     \e[0m 0;34m \t\e[1;34;40m Dark Blue  \e[0m 1;34m"
    11. echo -e "\e[0;35;47m Magenta  \e[0m 0;35m \t\e[1;35;40m DarkMagenta\e[0m 1;35m"
    12. echo -e "\e[0;36;47m Cyan     \e[0m 0;36m \t\e[1;36;40m Dark Cyan  \e[0m 1;36m"
    13. echo -e "\e[0;37;47m LightGray\e[0m 0;37m \t\e[1;37;40m White      \e[0m 1;37m"


  • PHP 透過 ip2country 查詢 ip 所屬國家

    Posted on August 1st, 2011 Sam Tang 1 comment

    用 PHP 查詢 ip 所屬國家可以用幾種不同的方法,以下會介紹使用 MaxMind 的函式實現,首先到以下網址下載 MaxMind 函式:

    http://geolite.maxmind.com/download/geoip/api/php/geoip.inc
    http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz

    將上面的 GetIP.dat.gz 解壓,然後可以用以下程式碼實現:

    PHP:
    1. <?php
    2. include("geoip.inc");
    3.  
    4. $test_ip = "123.123.123.123"; // 這是要查詢的 ip
    5.  
    6. $gi = geoip_open("GeoIP.dat", GEOIP_STANDARD);
    7. echo geoip_country_code_by_addr($gi, $test_ip);
    8.  
    9. geoip_close($gi);
    10. ?>

    I use ipchicken.com to get my IP address.


  • PHP 讀取 XML 檔案

    Posted on July 29th, 2011 Sam Tang 1 comment

    在 PHP4 時沒有專用函式讀取 XML 檔案,而PHP5 已經內建一個讀取 XML 檔案的函式,那就是 simplexml_load_file()

    PHP:
    1. <?php
    2. $xml = simplexml_load_file("test.xml"); //設定要讀取的 XML,也可以是 URL
    3.  
    4. print_r($xml);
    5. ?>


  • 幾個實用的 PHP Regular Expression

    Posted on July 28th, 2011 Sam Tang 1 comment

    Regular Expression 在程式開發時檢查及替換字串相當有用,以下是幾個很好用的 PHP Regular Expression 例子:

    1. 密碼檢查: 以下的 Regular Expression 會檢查密碼是否夠安全,會檢查密碼必需最少有 8 位,以及最少包括一個小寫字母、一個大寫字母及一個數字:

    PHP:
    1. <?php
    2. $password = "Fyfjk34sdfjfsjq7";
    3.  
    4. if (preg_match("/^.*(?=.{8,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$/", $password)) {
    5.     echo "Your passwords is strong.";
    6. } else {
    7.     echo "Your password is weak.";
    8. }
    9. ?>

    2. Email 地址檢查:

    PHP:
    1. <?php
    2. $email = firstname.lastname@aaa.bbb.com;
    3. $regexp = "/^[^0-9][A-z0-9_]+([.][A-z0-9_]+)*[@][A-z0-9_]+([.][A-z0-9_]+)*[.][A-z]{2,4}$/";
    4.  
    5. if (preg_match($regexp, $email)) {
    6.     echo "Email address is valid.";
    7. } else {
    8.     echo "Email address is <u>not</u> valid.";
    9. }
    10. ?>

    3. URL 檢查:

    PHP:
    1. <?php
    2. $websiteUrl = $_REQUEST['url'];
    3.  
    4. if (!preg_match("#^http(s)?://[a-z0-9-_.]+\.[a-z]{2,4}#i",$websiteUrl)) {
    5. echo "wrong url";
    6. } else {
    7. echo "ok";
    8. }
    9.  
    10. ?>


  • PHP Easter Egg

    Posted on January 27th, 2011 Sam Tang No comments

    在 PHP 頁面後面加上以下 GET 請求,便會顯示一幅 PHP 的圖片,例如:

    http://localhost/index.php?=PHPE9568F36-D428-11d2-A769-00AA001ACF42


  • 使用 PHP GZIP 使網頁提速

    Posted on February 22nd, 2010 Sam Tang No comments

    GZIP 是一種壓縮技術,是在伺服器上將頁面壓縮,傳到用戶的瀏覽器再解壓。在 PHP 實要 GZIP 壓縮可以這樣做:

    PHP:
    1. <?php
    2. if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')){
    3.     ob_start("ob_gzhandler");
    4. }else{
    5.     ob_start();
    6. }
    7. ?>


  • PHP 免費線上電子書 – Practical PHP Programming

    Posted on February 9th, 2010 Sam Tang No comments

    Practical PHP Programming 是 PHP 免費線上電子書,比較適合對 PHP 有基礎認識的朋友,以下為電子書目錄:

    1. Preface
    2. Introducing PHP
    3. Simple variables and operators
    4. Functions
    5. Arrays
    6. Objects
    7. HTML Forms
    8. Files
    9. Databases
    10. Cookies and Sessions
    11. Multimedia
    12. XML & XSLT
    13. Output Buffering
    14. Java and COM
    15. Networks
    16. Miscellaneous topics
    17. Security concerns
    18. Performance
    19. Writing PHP
    20. Writing extensions
    21. Alternative PHP uses
    22. Practical PHP
    23. Bringing it to a close
    24. Answers to Exercises
    25. The future of PHP
    26. Glossary


  • MySQL 微調技巧

    Posted on November 6th, 2009 Sam Tang No comments

    以下會介紹一些簡易的 MySQL 效能微調技巧,這些方法都是透過 my.cnf 的參數完成,而不需要重新編譯 MySQL。

    Key Buffer
    key buffer 是系統索引可用的緩存空間大小,對處理索引有很大的影響。設定 key buffer 的大小要根據自己的需要而定,而一個較簡單的方法是使用 25% 的記憶體空間作為 key buffer 使用。如果是獨立的資料庫伺服器可考慮使用更大的空間,例如 50%。
    通這設定 key buffer 的大小,可以減少硬碟 I/O 操作對 MySQL 的影響。

    以下是 key buffer 在 my.cnf 的設定方法:

    key_buffer = 512M

    Query Cache
    這是 SQL Query 的緩存,將 query 的查詢結果暫存在記憶體裡面,直至資料被更新為止。

    query_cache_size = 128MB
    query_cache_limit = 4MB

    Table Cache
    對於同時要存取多個資料表十分重要,這是設定同時可開啟資料表的數目。

    table_cache = 512

    Sort Buffers
    sort_buffer_size (在舊版本是 sort_buffer) 是設定 grouping 及 sorting 的緩存。

    sort_buffer_size = 32M
    myisam_sort_buffer_size = 32M


  • PHP 的日期計算

    Posted on September 12th, 2009 Sam Tang 1 comment

    在 PHP 內計算兩個日期之間的差距的話,可以先將日期轉成 Unix timestamp 的數值然後再作計算。例如要計算兩個日期 01/01/2009 及今天的日期差距,可以這樣做:

    PHP:
    1. <?php
    2. // 將日期以 "/" 附號分隔, 得出 日, 月, 年
    3. $time = explode("/", "01/01/2009");
    4.  
    5. // 將 01/01/2009 轉換成 Unix timestamp
    6. $unix_time = mktime(0, 0, 0, $time[0], $time[1], $time[2]);
    7.  
    8. // 計算 $unix_time 和現在的差距, 並除 86400 (一天有 86400 秒)
    9. $time_diff = (time() - $unix_time) / 86400;
    10. // 只擷取整數部份
    11. $time_diff = (int) $time_diff;
    12.  
    13. echo "01/01/2009 距離現在 "$time_diff . " 天.";
    14. ?>


  • 修改 MySQL 唯讀參數

    Posted on September 11th, 2009 Sam Tang No comments

    要修改 MySQL 唯讀參數,一般上也會修改 my.cnf 的內容,然後重新啟動 MySQL。但如果有一特殊需要也能重新啟動 MySQL 的話,可以用 Domas Mituzas Blog 上面的方法:「Evil replication management」

    例如在正常的情況下修改 log_slave_updates 參數,會出現這個 error:

    mysql> set global log_slave_updates=1;
    ERROR 1238 (HY000): Variable 'log_slave_updates' is a read only variable

    而文章內所提供的是非正規方法,所以閣下使用時要自行承擔風險,方法如下:

    mysql> system gdb -p $(pidof mysqld) -ex "set opt_log_slave_updates=1" -batch

  • 用 mysqldump 擷取部份樣本資料

    Posted on September 9th, 2009 Sam Tang No comments

    如果需要將 mysql server 的小部份資料匯入到測試主機上測試,可以配合 mysqldmp 的 -where="true LIMIT X" 選項,上的的 X 是想擷取的資料數量,例如:

    # mysqldump --opt --where="true LIMIT 10000" mydb > mydb.sql

    以上的指令會將 mydb 內所有資料表各自匯出 10000 筆資料

    這個方法可以很容易匯出較小的資料樣本件測試用途。