Php教學文件

壹、基本說明
貳、基本動作
參、資料
一、資料與算符
(一)資料型別
(二)算符
(三){}的各種用法
二、常數與變數
(一)常數
(二)變數
三、字串
四、陣列
五、類別與物件
六、參照
肆、控制結構
伍、載入程式及定義函數
陸、檔案
柒、函式
捌、設定
玖、SAPI
拾、PEAR

壹、基本說明

  1. PHP:
    1. Personal Home Page Tools。
    2. 巢狀的縮寫名稱:Hypertext Preprocessor,打開縮寫還是縮寫。
  2. PHP是一種「伺服器端嵌入式的跨平台描述性語言」
    1. 在伺服器端執行。伺服器的功能:提供網路服務。
    2. 嵌入網頁中,在中的部分,執行成HTML語法,丟給瀏覽器端。*.php是指內含php語法的html檔,不是指通篇都是php的檔(也可以通篇是php);注意.php中,非的部分,伺服器端和瀏覽器端看到的是一樣的;的部分,伺服器端和瀏覽器端看到的是不一樣的,前者看到是php語法,後者看到的是輸出的html。perl,c不是嵌入式,ASP、PHP是嵌入式。
    3. 跨平台。
    4. 描述性語言,無須先編譯成二進位檔,就能執行。
  3. 變數分大小寫,保留字不分大小寫。
  4. 保留字可以做變數名(因前有$),不能做常數名、函式名、類別名,因為之前沒有$和保留字做區隔。

貳、基本動作

參、資料

一、資料與算符

(一)資料型別

  1. PHP共有四種純量資料型別:
    1. 整數(integer)。
    2. 浮點數(float)。
    3. 布林(boolean)。
    4. 字串(string)。
  2. PHP共有兩種複合資料型別:
    1. 陣列(array)。
    2. 物件(object)。
  3. PHP共有兩種特殊資料型別:
    1. NULL:只有一值null。
    2. 資源 (resource):檔案的handle,MySQL請求的結果。
  4. 變數的資料型別取決於指派給它的值,可以隨時指派新型別的資料,來改變變數的資料型別。
  5. 轉換型別:$新變數=(新型別)$原變數;。如$a=0;$b=(double)$a:$a是整數0,$b是浮點數0。
  6. gettype(變數串);取得變數型別:nuknow type,boolean,integer,double,string,array,object,NULL,resource,傳回值是字串。
  7. settype(變數串,資料型別);設定變數的資料型別。還有:
    1. intval(變數串):傳回整數。
    2. floatval(變數串):傳回浮點數,會處理掉變數中的特殊字元及$號。
    3. doubleval(變數串):傳回倍浮點數,會處理掉變數中的特殊字元及$號。
    4. strval(變數串):傳回字串。但變數串不能是陣列或物件。
  8. 測試變數型別,是傳回真,不是傳回偽:
    1. is_integer()同is_int()同is_long()。
    2. is_double()同is_float()同is_real()。
    3. is_string()。
    4. is_array()。
    5. is_object()。
    6. is_null()。
  9. isset(變數串);變數存在。
  10. unset(變數串);刪除變數。
  11. empty(變數串);變數存在且為0或空值。
型別實字資料生成指令帶型別資料指標=○ =&○
NULLnull不可使用 純量派值不可
整數1234 (integer)值
浮點1.23 (float)值
布林true (boolean)值
字串1.23 (string)值
陣列array(…)(array)null,(array)5,(array)array(5,6),(array)值向量
物件new 類別(object)null,(object)5,(object)值指標複製(PHP4)
參照(PHP5)
參照
函式回傳值非實字mysql_query(…)傳回值待查
資源
變數非實字var $名稱以上皆可複製(除了
PHP5中的物件)
「帶型別資料」欄中的值可為實字可為變數;「=○」「=&○」前六列中的○,均代表該型別的實字。

(二)算符

  1. 指派:=。如$b=6+($a=5);
  2. 四則:加(+),減(-),乘(*),除(/)。php 的整數四則只支援到 32 bit 的整數,更大的整數會被當作浮點數處理而損失精準度。如要算更大的數就要用BC高精準度函式(BC Math)(Binary Calculator)。
  3. 餘數(%):A%B,A,B先取整數,再取A除以B的餘數。
  4. 二元算符:$x+=2是$x=$x+2;$x-=2是$x=$x-2;$x/=2是$x=$x/2;$x*=2是$x=$x*2;$x%=2是$x=$x%2;$x.=$y是$x=$x.$y;
  5. 遞增遞減算符:++$x是$x=$x+1;$y=$x++是指定$x的值給$y,再將$x的值加1。
  6. 參考算符(&):
    1. $a=5;$b=$a;,當$a=7;時,$b還會維持5。
    2. $a=5;$b=&$a;,當$a=7;時,$b會同步變成7。$b隨時參考$a的值為其值,$b之值隨$a之值變化而變化。
  7. 數值比較算符:傳回真(1)、偽(0),有<,>,==(相等),===(全等:值等且型別相同),<=,>=,!=,<>
  8. 字串連結算符(.):字串一.字串二.字串三…。
  9. 邏輯算符(可處理數值、字串):AND(&&)、OR(||)、NOT(!)、XOR(任一為真且僅一為真)。非零為真,零為偽。如10||0得出1;10&&0得出0;!10得出0;!0得出1。
  10. 位元算符:會先將浮點數轉換成整數,再將整數轉換換成二進位,再進行以下操作:
    1. &:位元以AND運算。
      例如:○○○○,由左數來代表8,4,2,1四個位。○●○○代表4,左起第2位為1,其他三位為0。「(整數&4)===4」或「(整數&4)==4」的條件(即「?●??&○●○○→○●○○」),會挑出左起第2位為1的所有值,包括:12,13,14,15,4,5,6,7。原因是左起第2位以外的其他三位,不管其值是0或1,&0之後都會得0。而左起第2位原值如為0,&1之後還得0;左起第2位原值如為1,&1之後還得1。
    2. |:位元以OR運算。
    3. ^:位元以XOR運算。
    4. ~:位元以NOT運算。
    5. <<:位元左移。
    6. >>:位元右移。
    如3&7為0011AND0111得出0011,即得3。如7>>1為0111右移一位得出0011,即得3。
  11. 逗號算符:分隔函數參數與其他表列事項。
  12. 陣列算符:[]。
  13. 依條件傳回:
    1. 三元算符?::條件 ? 為真時 : 為偽時。
    2. PHP 5.3+:$expr1 ?: $expr2,$expr1 為真,傳回 $expr1,否則傳回 $expr2。
      例:expr0 ?: expr1 ?: expr2 ?: expr3…:expr0 不成立就判斷 expr1 ,也不成立就判斷 expr2 ,再不成立就判斷 expr3 …
    3. PHP 7:$expr1 ?? $expr2,$expr1 不為 null,傳回 $expr1,為 null 時傳回 $expr2。等價於isset($expr1) ? $expr1 : $expr2
      例:expr0 ?? expr1 ?? expr2 ?? 'empty',expr0,expr1,expr2一個個查下去,非 null 就傳回並結束,若為 null 就查下一個,均為 null ,就傳回 'empty'。
    ?: 與 ?? 兩者差異在於:
    ?: 是用 if($x) (也就是 if(!empty($x))),判斷是否為 true
    ?? 是用 if(isset($x) (也就是 if (!is_null($x)),判斷是否不為 null
    請留意 empty() 和 isset() 的差異
  14. 抑制錯誤算符@
  15. 執行算符`:PHP會執行夾在兩個`之間的作業系統命令,如Linux的`ls`或微軟的`dir c:`
  16. new:依類別定義製造一個物件。
  17. ->:取物件的屬性或方法。
  18. 算符優先順位在p30。

(三){}的各種用法:

  1. 將多個獨立語句合併為一個複合語句,例如 if … else …中經常如此使用
  2. 在變數間接引用中進行定界,避免歧義。例如 ${$my_var[8]}與${$my_var}[8]的區分
  3. 指示字串變數中的單個字元(下標從0開始),例如:「$my_str="1234"; $my_str{1}='5';」現在 $my_str 內容為'1534'
    此用法為PHP 5之後的特性,用於消除使用中括號引起的歧義。
  4. 界定變數的名稱:「$var='sky'; echo "{$var}boy";」

二、常數與變數

  1. 兩者都是要得到「資料」。
  2. 常數代表的資料經定義不再改變。常數是全域的。
  3. 變數可用算符改變內容。變數有範圍(scope)。

(一)常數

(二)變數

三、字串

(一)單引號字串:

  1. 變數名當成普通字串,不代入變數值。
  2. \':單引號

(二)雙引號字串:

  1. 變數名以變數值代入。
  2. \n:換行
  3. \r:歸位
  4. \t:定位字元TAB
  5. \s:空白
  6. \':反斜+單引號等雙字元
  7. \":雙引號
  8. \\:反斜
  9. \$:錢號,處理變數時很重要。
  10. \一到三位數字:以8進位指定字元
  11. \x一到二位數字:以16進位指定字元

(三)自訂引號(Heredoc):

  1. 「<<<自訂引號名稱,換行…引號內…換行,自訂引號名稱;」。
    $str = <<<EOS

    EOS;
    請注意,自訂引號名稱跟<<<之間沒有空格。
  2. 自訂引號字元串,須以字母開頭,可用字母、數字、_。
  3. 變數名以變數值代入。
  4. \n:換行
  5. \r:歸位
  6. \t:定位字元TAB
  7. \\:反斜
  8. \$:錢號,處理變數時很重要。
  9. \一到三位數字:以8進位指定字元
  10. \x一到二位數字:以16進位指定字元

(四)字串索引

  1. $字串變數名[整數字]:字串的第幾byte,utf-8算3byte。
  2. $字串變數名[非整數]:非整數捨去小數變整數,字串的第幾byte,utf-8算3byte。
  3. $字串變數名[字串]:字串的第幾0byte,utf-8算3byte。

(五)字串函式

  1. ord(字串):傳回字串首字元的ASCII碼。
  2. chr(數字):將ASCII碼轉為字元。
  3. trim():去頭尾空白,換行,含\n和\r。
  4. ltrim():去頭部空白。
  5. chop():去尾部空白。
  6. nl2br():將"\n"換行改成<br>。
  7. strip_tags(字串,不去除的標籤):除去HTML及PHP標籤。
  8. parse_url(url字串):依「scheme://user:pass@host:port/path?query#fragment」格式解析url,並傳回陣列,其元素索引為scheme、user、pass、host、port、path、query、fragment。
  9. parse_str(query字串):將query字串解析成諸變數。如「first=value&second[]=this+works&second[]=another」,傳回$first=value;second[0]="this works";second[1]="another"。
  10. print():同作用同echo,但print是函式,傳回布林值。
  11. printf():格式化字串,傳回整數。
  12. sprintf(規格,字串):格式化字串。
    轉換規格%[顯示寬度][-][][.小數位數]型別:有-代表向左靠齊,沒-代表向右。
    1. %b:將變數解釋為整數,並以二進位顯示。
    2. %c:將變數解釋為整數,並以字元顯示。
    3. %d:將變數解釋為整數,並以十進位顯示。
    4. %f:將變數解釋為浮點數,並以浮點數顯示。
    5. %o:將變數解釋為整數,並以八進位顯示。
    6. %s:將變數解釋為字串,並以字串顯示。
    7. %x:將變數解釋為整數,並以十六進位顯示,用a-f。
    8. %X:將變數解釋為整數,並以十六進位顯示,用A-F。
  13. AddSlashes():若有反斜時,加上Slash,讓輸入字串若含特殊字元時,加上逸出字元\,以免存入資料庫時衝碼。Q3上引數為變數時,做完此運算立刻存回此變數,導致變數值改變;較新的版本,引數為變數時,做完此運算不會導致變數值改變。
  14. StripSlashes():若有反斜時,去掉Slash,使資料庫取出資料還原。Q3上引數為變數時,做完此運算立刻存回此變數,導致變數值改變;較新的版本,引數為變數時,做完此運算不會導致變數值改變。
  15. strtoupper():轉大寫。uppercase大寫。
  16. strtolower():轉小寫。lowercase小寫。
  17. ucfirst():字串首轉大寫。
  18. ucwords():字串中每個Word的字首轉大寫。
  19. explode("分隔字元",字串[,最多傳回幾個元素]):將字串以分隔字元拆成一個個元素,變成陣列。分隔字元可以是多byte,如「=>」。
  20. implode("分隔字元",$陣列):將陣列元素以分隔字元串成字串,又叫join()。分隔字元可以是多byte,如「=>」。
  21. strtok(字串,"分隔字元"):擷取字串的前面到分隔字元為止,分隔字元可以用中文單字不能用字串,如用英文字串,當成英文字串的首字元。注意 : 只有在第一次呼叫strtok( )時,才使用字串參數,之後的呼叫只要使用分隔字元,它會記錄目前的字串。要切開另一個新的字串時,你只需要再一次呼叫 strtok( )和字串參數即可。你可以在分隔字元參數中放置多樣的分隔字元,當找到任何參數中的字元時,字串將會被切開。如<? $string = "I will be back";$tok=strtok($string," ");while ($tok){echo "Word=$tok<br>";$tok=strtok (" ");} ?>依次傳回I will be back。
  22. substr(字串,開始字元,長度):擷取子字串,第一字元算0;長度省略則取到字尾。
    開始字元為負,為從字串尾倒數,字尾算-1,仍往下取到字尾,不是逆向取字。例如:
    1. echo substr('abcde',-1);:會輸出 e,因為從字尾開始算,取至字尾。
    2. echo substr('abcde',-2);:會輸出 de,因為從字尾倒數2開始算,取至字尾。

    長度為負則先依開始字元取到字尾,再從其中的字尾開始扣除長度。例如:
    1. echo substr('abcd',-3,1);:會輸出 b,因為從字尾開始算,先取三個字母為 bcd,接著長度在從 bcd 取 1 位。
    2. echo substr('abcdef',0,-1);:會輸出 abcde,函式先從零開始取整段字串,長度再由字串尾扣掉一個。
    3. echo substr('abcdef',2,-1);:會輸出 cde,函式先從第二個字元開始,取得 cdef 這幾個字,再由取得的字串尾扣掉一個。
    4. echo substr('abcdef',5,-2);:會回傳 false,因為程式一開始先取得 f,然後扣掉兩個字元,就 false 了!
    5. echo substr('abcdef',-4,-2);:會輸出 cd,因為程式先取得 cdef 這四個字元,再從其中的字尾開始扣掉兩個字元。

    中文字每字算3字元,如切在一個字3byte中間,會切破字出?。
    專處理utf-8的擷取子字串函式mb_strcut(字串,開始字元,長度[,'編碼']):省略編碼(utf-8)時,切破字出?;有編碼(utf-8)時,每個中文字長度算3,切到字中間時,被切到的字要取。
    專處理utf-8的擷取子字串函式mb_substr(字串,開始字元,長度[,'編碼']):省略編碼(utf-8)時,切破字出?;有編碼(utf-8)時,每個中文字長度算1,所以不可能切破字。
    mb是指multi-byte 多字節字的意思
  23. strcmp(字串一,字串二):比較兩字串,相等為0,正為字串一ASC碼大,負數為字串二ASC碼大。
  24. strcasecmp(字串一,字串二):同上,但不分大小寫。
  25. strrev(字串):顛倒字串。
  26. strlen(字串):字串長度,UTF-8中文字長度算3。mb_strlen(字串,'UTF8'),UTF-8中文字長度算1。中英文混排字串的佔位寬度為(strlen(字串)+mb_strlen(字串,'UTF8'))/2。
  27. str_pad(字串,位數[,補什麼[,補法]]):補齊位數。補什麼預設值為空白,補法:STR_PAD_RIGHT補右邊(預設)、STR_PAD_LEFT補左邊、STR_PAD_BOTH左右兩邊平均補。
  28. strstr(字串,子字串)?substr(字串,0,strpos(字串,子字串)):字串:取子字串之前的部分(不含子字串),找不到傳回原字串。
  29. strstr(字串,子字串):找到傳回子字串「第一次」出現以後之剩餘字串(含子字串),找不到傳回「假」。自PHP 5.3 增加第三參數 strstr(字串,欲找之子字串[,是否傳回欲找字串之前的段落]),「是否傳回欲找字串之前的段落」的預設值為 false ,即傳回子字串「第一次」出現以後之剩餘字串(含子字串);若設為 true 則傳回子字串「第一次」出現以前的段落(不含子字串),兩者合起來恰為原字串。
  30. strstr(字串,欲找之子字串)?substr(strstr(字串,欲找之子字串),strlen(欲找之子字串)):字串:找到傳回子字串「第一次」出現以後之剩餘字串(不含子字串),找不到傳回原字串。
  31. strchr(字串,欲找之子字串):同上。
  32. stristr(字串,欲找之子字串):同上,但不分大小寫。
  33. strrchr(字串,欲找之子字串):找到傳回子字串「最後一次」出現以後之剩餘字串,找不到傳回「假」。
  34. strpos(字串,欲找之子字串,指定蒐尋之起始位置):找到傳回子字串「第一次」出現的位置,找不到傳回「假」。字串首位置算0,省略蒐尋起點時,從字串首開始找。但是「假」傳回值是0,字首位置傳回值也是0,會混淆。可以用if(傳回值===false)測,如果成立傳回值代表「假」,如果不成立傳回值代表位置0。
  35. strrpos(字串,欲找之子字串,指定蒐尋之起始位置):找到傳回「子字串字首字元」「最後一次」出現的位置,找不到傳回「假」。字串首位置算0,省略蒐尋起點時,從字串首開始找。
  36. str_repeat(字串,重覆次數):重覆字串若干次。
  37. str_replace(蒐尋字串,代換字串,字串堆):在字串堆中找到「蒐尋字串」並用「代換字串」換掉它們。
  38. substr_replace(字串堆,代換字串,起點,長度):在字串堆指定的起點及長度,用代換字串換掉它們。起點為0或正,由字串堆頭起算;起點為負,由字串堆尾起算。長度未指定,則換到字串堆尾;長度為0,則插入原字串;長度為正,則取代幾個字串數;長度為負,則自尾端開如取代,停於長度。
  39. mb_convert_kana(字串,轉換方式):假名轉換。
  40. iconv("來源編碼","目的編碼",字串):轉碼,編碼代名:big5、utf8。
  41. chunk_split(字串,切的長度,每段末尾加):切成小段,切的長度預設為76,每段末尾預設加\r\n。
  42. quoted_printable_decode(qp編碼字串):將 qp 編碼字串轉成 8 位元字串。
  43. base64_decode(編碼字串):以MIME base64解碼。
  44. base64_encode(字串):以MIME base64編碼。只包含英文字母大小寫、阿拉伯數字、加號與反斜線,共 64 個基本字符。HTML標籤可以寫成:
    <img src='data:image/png;base64,圖的編碼字串' />
  45. htmlspecialchars(字串[,引號格式[,字元集]]):將字串中&(和)轉成 &amp;、< (小於) 轉成 &lt;、> (大於) 轉成 &gt;,引號:
    1. 如果轉義,雙引號轉為「&quot;」,單引號轉為「&#039;」。
    2. 引號格式雙引號單引號
      預設
      ENT_QUOTES
      ENT_NOQUOTES
  46. htmlspecialchars_decode(字串[,引號格式]):將字串中 &amp; (和)轉成 &、 &lt; (小於)轉成 < 、 &gt; (大於) 轉成 > ,引號:
    1. 如果轉義,「&quot;」轉為雙引號,「&#039;」轉為單引號。
    2. 引號格式雙引號單引號
      預設
      ENT_QUOTES
      ENT_NOQUOTES
  47. htmlentities(字串[,引號格式[,字元集]]):將字串中100種ASCII碼轉碼,將轉碼的ASCII如下表
    換成換成換成換成換成換成換成換成換成換成換成換成換成換成換成換成
    A0&nbsp; A1&iexcl;¡A2&cent;¢A3&pound;£A4&curren;¤A5&yen;¥A6&brvbar;¦A7&sect;§A8&uml;¨A9&copy;©AA&ordf;ªAB&laquo;«AC&not;¬AD&shy;­AE&reg;®AF&macr;¯
    B0&deg;°B1&plusmn;±B2&sup2;²B3&sup3;³B4&acute;´B5&micro;µB6&para;B7&middot;·B8&cedil;¸B9&sup1;¹BA&ordm;ºBB&raquo;»BC&frac14;¼BD&frac12;½BE&frac34;¾BF&iquest;¿
    C0&Agrave;ÀC1&Aacute;ÁC2&Acirc;ÂC3&Atilde;ÃC4&Auml;ÄC5&Aring;ÅC6&AElig;ÆC7&Ccedil;ÇC8&Egrave;ÈC9&Eacute;ÉCA&Ecirc;ÊCB&Euml;ËCC&Igrave;ÌCD&Iacute;ÍCE&Icirc;ÎCF&Iuml;Ï
    D0&ETH;ÐD1&Ntilde;ÑD2&Ograve;ÒD3&Oacute;ÓD4&Ocirc;ÔD5&Otilde;ÕD6&Ouml;ÖD7&times;×D8&Oslash;ØD9&Ugrave;ÙDA&Uacute;ÚDB&Ucirc;ÛDC&Uuml;ÜDD&Yacute;ÝDE&THORN;ÞDF&szlig;ß
    E0&agrave;àE1&aacute;áE2&acirc;âE3&atilde;ãE4&auml;äE5&aring;åE6&aelig;æE7&ccedil;çE8&egrave;èE9&eacute;éEA&ecirc;êEB&euml;ëEC&igrave;ìED&iacute;íEE&icirc;îEF&iuml;ï
    F0&eth;ðF1&ntilde;ñF2&ograve;òF3&oacute;óF4&ocirc;ôF5&otilde;õF6&ouml;öF7&divide;÷F8&oslash;øF9&ugrave;ùFA&uacute;úFB&ucirc;ûFC&uuml;üFD&yacute;ýFE&thorn;þFF&yuml;ÿ
    22&quot;"3C&lt;<3E&gt;>26&amp;&
    1. 未下引號格式:雙引號轉為「&quot;」,單引號不轉
    2. 引號格式為ENT_QUOTES:雙引號轉為「&quot;」,單引號轉為「&#039;」
    3. 引號格式為ENT_NOQUOTES:單雙引號不轉。
    用法如htmlentities($str,ENT_NOQUOTES,'utf-8')。使用本函式常造成中日韓文多字節字產生亂碼。
  48. get_html_translation_table([表型[,引號格式]]):產生翻譯表陣列,索引為原字元,值為轉換後字元。表型有HTML_ENTITIES, HTML_SPECIALCHARS兩種,前者有100個元素,後者有4個元素。如果省略表型,則為後者。
  49. strtr(字串,欲翻字串,轉換字串)或strtr(字串,翻譯陣列):將字串翻譯並回傳。翻譯陣列諸元素,索引為原字串,值為轉換後字串。使用陣列時,凡遇到陣列中有的元素就翻譯。

(六)正規表示式(regular expression)

PHP支援兩種正規表示式,POSIX和Perl。POSIX內建,Perl語法須將PCRE(Perl-compatible regular expression)程式庫編譯進來。正規表示式比字串慢,儘量用字串。

括號

  1. ():括住子表示式,通常為字串或字串選項。
  2. []:中括號內表示某「字元」或某字元之選項。諸選擇項目中,有任一選項相符,皆算相符。
  3. {}:括住重覆次數說明。

字元表示(可能在中括號內也可能在中括號外)

  1. \:跳脫字元。
  2. .在中括號外:除\n以外的單一字元。如.at相符於cat,sat,mat。
  3. \.在中括號外,.與\.在中括號內皆表示:字元.。
  4. \-與-中括號內外皆表示:字元-。但-在中括號內也有區間的含意。
  5. \\:\。
  6. \/:/。在preg_match及preg_replace中,即使在中括號內,也一定要用\/來表示字元/,因為此時/還代表樣式開始與樣式結束。
    -----反斜字母-----
  7. \s:代表分隔字元:[\n\t\f\r\v]。
  8. \S:非分隔字元[^\n\t\f\r\v]。
  9. \n:換行。
  10. \r:歸位。
  11. \f:換頁。
  12. \t:Tab。
  13. \v:垂直Tab。
  14. \c:控制字元。
  15. \d:代表數字,[0-9]。
  16. \D:代表非數字,[^0-9]。
  17. \w:代文字包,含字母、數字、底線。
  18. \W:代表非文字。
  19. \u:後面跟的是UTF十六進位編碼。
  20. [a-z]、[^a-z]:a到z、非a-z。
  21. [aeiou]:五個母音字中的一個。
  22. [a-zA-Z]:字母。
  23. 字元的單字表示法:
    1. [[:alpha:]]:字母。
    2. [[:alnum:]]:字母及數字。
    3. [[:lower:]]:小寫字母。
    4. [[:upper:]]:大寫字母。
    5. [[:digit:]]:數字字元。
    6. [[:xdigit:]]:16進位數字字元。
    7. [[:punct:]]:標點。
    8. [[:blank:]]:跳格及空白。
    9. [[:space:]]:空白。
    10. [[:cntrl:]]:控制字元。
    11. [[:print:]]:所有可視字元。
    12. [[:graph:]]:除空白字元外所有可視字元。

次數

  1. ?:重複0次或1次,等價於{0,1}。
  2. *:表示該樣式會出現0或0次以上,等價於{0,}。如(very )*large:相符於large、very large、very very large。
  3. +:表示該樣式會出現1或1次以上,等價於{1,}。如[[:alpha:]]+表示至少會有一個英文字母。
  4. {3}:重複三次。
  5. {2,4}:重複二到四次。
  6. {2,}:重複兩次以上。

字串首、字串尾

  1. ^(表示式),表示式須出現在被蒐尋字串首才算相符。如^bob。
  2. (表示式)$,表示式須出現在被蒐尋字串尾才算相符。如com$。
  3. ^(表示式)$,首尾所夾必須與表示式相符才算比對成功。如^[a-z]$,字串頭尾之間,出現a-z任一字元就算相符。

多重選擇「|」(讀成OR)

  1. (選項一)|(選項二)|(選項三):多選一都符合

非補獲比對

補完本段須參考:
http://www.ttwen.info/article/1309019 《php正則表達式詳解》中「3.6 選擇」「3.7 後向引用」,「轉義符」
http://www.isnowfy.com/regular-expression-negative/ 《正则表达式中的不匹配》中找「(?=a)和(?!a)」
http://j796160836.pixnet.net/blog/post/29514227-[轉貼]常用的php正規表示式 《常用的PHP正規表示式》有大量實用的整理
http://ccckmit.wikidot.com/regularexpression 《正規表示式》有語法的表格整理
https://tw.answers.yahoo.com/question/index?qid=20130515000016KK01196 《電子郵件帳號中間有空格怎麼辦》「根據維基百科的說明,電子郵件地址中若含有空格,是不能單獨存在的,得用引號括住,且空格也只能是半型。」

中括號內

  1. \:跳脫字元。與中括號外相同。
  2. ^:否定。與中括號外不同。
  3. -:既代表字元-如[-.\/],又表示字元範圍如[1-9]。要看其前後是不是可以構成範圍。

運用

函式:
  1. ereg(正規表示式,被蒐尋字串,陣列名):在被蒐尋字串中找符合於正規表示式的子字串,陣列第0元素放原字串,之後每找到合條件的字串就放進陣列,成為一個元素。傳回真假(1,0)。陣列名可省略,省略陣列名,則只是單純地比對,找到則傳回值為 true。
  2. eregi(正規表示式,被蒐尋字串,陣列名):同ereg,但不分大小寫。
  3. ereg_replace(正規表示式,取代字串,被蒐尋字串):在被蒐尋字串中找到表示式,用取代字串換掉。PHP7已用preg_replace取代,比如:
    ereg_replace("正規表示式", 取代字串, 被蒐尋字串)
    // 修改後應為:
    preg_replace("/正規表示式/",取代字串,被蒐尋字串)
    「/」代表樣式開始及樣式結束
  4. eregi_replace(正規表示式,取代字串,被蒐尋字串):同ereg_replace,但不分大小寫。
  5. split(正規表示式表述之分隔字串,被切割字串,傳回元素上限):用分隔字串,將被切割字串,切成一段段,成為陣列中一個個元素。傳回陣列。
  6. preg_match(規則樣式,欲比對字串,傳回陣列):比對成功傳回真,否則傳回假;比對到的字串放入傳回陣列。
    以樣式的規則來剖析欲比對字串。比對結果用陣列傳回,陣列[0]放原字串、陣列[1]為第一個合乎規則的字串、陣列[2]就是第二個合乎規則的字串,餘類推。若省略陣列參數,則只是單純地比對,找到則傳回值為 true。
    preg_match("/^(INSERT INTO|CREATE TABLE|ALTER TABLE|UPDATE)(\s)+([`]?)([^`\s]+)\\3(\s)+/siU", $query, $matches)
    /               pattern開始
    ^(…)           行首為(INSERT INTO|CREATE TABLE|ALTER TABLE|UPDATE)四者之一             第一截
    (\s)+           至少一個空白                                                            第二截
    ([`]?)          ` 0或一次                                                               第三截
    ([^`\s]+)       非`及空白至少一次 表名                                                  第四截
    \\3             重做第三截
    (\s)+           至少一個空白                                                            第五截
    /               pattern結束
    siU             不分大小寫

    preg_match("/^(DROP TABLE)(\s)+([`]?)([^`\s]+)\\3(\s)?$/siU", $query, $matches)
    /               pattern開始
    ^(…)           行首為 DROP TABLE       第一截
    (\s)+           至少一個空白            第二截
    ([`]?)          ` 0或一次               第三截
    ([^`\s]+)       非`及空白至少一次 表名  第四截
    \\3             重做第三截
    (\s)?$          行尾0或一個空白         第五截
    /               pattern結束
    siU             不分大小寫
  7. preg_replace(規則樣式,輸出,欲比對字串):依規則樣式剖析欲比對字串,然後輸出。
    下例傳回值為 $startDate = 6/19/1969
    $patterns = array("/(19|20)(\d{2})-(\d{1,2})-(\d{1,2})/", "/^\s*{(\w+)}\s*=/");
    $replace = array("\\3/\\4/\\1\\2", "$\\1 =");
    print preg_replace($patterns, $replace, "{startDate} = 1969-6-19");
    比對樣式分為兩組
    /(19|20)(\d{2})-(\d{1,2})-(\d{1,2})/  找到「1969-6-19」,其中\\1為19、\\2為69、\\3為6、\\4為19,輸出「6/19/1969」
      \\1    \\2     \\3       \\4
    /^\s*{(\w+)}\s*=/                     找到「{startDate} =」其中\\1為startDate,輸出「$startDate =」。
    	   \\1
  8. 在preg_match與preg_replace中,「/」代表樣式開始及樣式結束,「siU」不分大小寫,「\\3」為第三截。
模式修飾符(在patterns結束的斜線之後)
  1. i (PCRE_CASELESS):不分大小寫
  2. m (PCRE_MULTILINE):多行。預設為單行。如果目標字串中沒有 "\n" 字元,或者模式中沒有出現 ^ 或 $,設定這個修飾符不產生任何影響。
  3. s (PCRE_DOTALL):點號元字元匹配所有字元,包含換行符。如果沒有這個修飾符,點號不匹配換行符。一個取反字元類比如 [^a] 總是匹配換行符,而不依賴於這個修飾符的設定。
  4. x (PCRE_EXTENDED):忽略未經過轉義或不在字元類中的空白數據字元,並且位於一個未轉義的字元類外部的#字元和下一個換行符之間的字元也被忽略。這使被編譯模式中可以包含註釋。注意:這僅用於數據字元。空白字元還是不能在模式的特殊字元序列中出現,比如序列 (?( 引入了一個條件子組(譯註: 這種語法定義的 特殊字元序列中如果出現空白字元會導致編譯錯誤。比如(?(就會導致錯誤)。
  5. e (PREG_REPLACE_EVAL):已停用。如果設定了這個被棄用的修飾符, preg_replace() 在進行了對替換字串的後向引用替換之後,將替換后的字串作為 php 程式碼評估執行(eval 函式方式),並使用執行結果作為實際參與替換的字串。單引號、雙引號、反斜線(\)和 NULL 字元在後向引用替換時會被用反斜線轉義。
  6. A (PCRE_ANCHORED):強制為"錨定"模式,也就是說約束匹配使其僅從目標字串的開始位置搜索。
  7. D (PCRE_DOLLAR_ENDONLY):模式中的元字元美元符號僅僅匹配目標字串的末尾。如果這個修飾符 沒有設定,當字串以一個換行符結尾時, 美元符號還會匹配該換行符(但不會匹配之前的任何換行符)。如果設定了修飾符m,這個修飾符被忽略。
  8. S:執行額外的分析。當一個模式需要多次使用的時候,爲了得到匹配速度的提升,值得花費一些時間對其進行一些額外的分析。僅僅適用於非錨定模式的匹配(即沒有單獨的固定開始字元)。
  9. U (PCRE_UNGREEDY):使量詞預設為非貪婪的,通過量詞后緊跟? 的方式可以使其成為貪婪的。同樣可以使用模式內修飾符設定 (?U) 進行設定,或者在量詞后以問號標記其非貪婪(比如.*?)。
  10. X (PCRE_EXTRA):打開了 PCRE 與 perl 不相容的附件功能。模式中的任意反斜線後就 ingen 一個沒有特殊含義的字元都會導致一個錯誤,以此保留這些字元的向後相容性。預設情況下,在 perl 中,反斜線緊跟一個沒有特殊含義的字元被認為是該字元的原文。
  11. J (PCRE_INFO_JCHANGED):內部選項設定(?J)修改本地的PCRE_DUPNAMES選項。允許子組重名,(譯註:只能通過內部選項設定,外部的 /J 設定會產生錯誤。)
  12. u (PCRE_UTF8):模式和目標字串都被認為是 utf-8 的。無效的目標字串會導致 preg_* 函式什麼都匹配不到;無效的模式字串會導致 E_WARNING 級別的錯誤。HP 5.3.4 後,5位元組和6位元組的 UTF-8 字元序列被考慮為無效。以前就被認為是無效的 UTF-8。
常見的正規表示式:
  1. 日期:
    ^(19|20)(\d{2})[-.\/]?(0?[1-9]|1[012])[-.\/]?(0?[1-9]|[12][0-9]|3[01])$:最佳,開頭為19或20,接著數字重複2次,分隔字元不出現或出現1次,月份為01~12,分隔字元不出現或出現1次,日期為01~31。
    ^([0-9][0-9]+)[-.\/]?([0-1]?[0-9])[-.\/]?([0-3]?[0-9])$:開頭為0-9,數字須重複一次以上,分隔字元不出現或出現1次,月分為一或兩位第一位為0到1,分隔字元不出現或出現1次,日期為一或兩位第一位為0到3。
    ^([0-9]{4})-([0-9]{2})-([0-9]{2})$:開頭為數字重複4次,中間為數字重複兩次,末段為數字重複兩次。
  2. email:
    ^[/w.-%]+@([0-9a-z][0-9a-zA-Z-]+\.)+[a-zA-Z]{2,4}$:檢查是否合法的email,開頭須mail可用字元,字元須1個以上,含@,@之後(兩字母以上,再加.)之段落須重複1次以上,字尾須為2至4個英文字母。
    ^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$:較不嚴格檢查是否合法的email,開頭為\w代表字母和數字,字元須1個以上,含@,@之後被.分成兩段落以上。
  3. 用戶密碼:
    ^[a-zA-Z]\w{5,17}$,開頭必須為大小寫字母,跟著5到17位的字母或數字或底線。
    ^(?=^.{8,}$)((?=.*[A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z]))^.*$,先正向預查長度必須有八碼,再正向預查:是否含數字或字母、是否含小寫字母、是否含大寫字母,其他條件則不太管,只要有一個字元就好。
  4. 只能輸入漢字:^[\u4e00-\u9fa5]{0,}$,一到龥等20901個漢字。
  5. 網址:^((http|https|ftp):\/\/)?([\w-]+\.)+[\w-]+(\/[\w-.\/?%&=~+]*)?$,開頭須三協定之一,並且跟://,但協定也可以省略;帶.的字串須一次以上,之後再跟一個字串,最後面加「/路徑」若干次,其中須限網址列許可之諸字元。
  6. IP:^((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))*$。
  7. 電話號碼:^(\d{3,4}-)?\d{7,8}$。適用”XXX-XXXXXXX”、”XXXX-XXXXXXXX”、”XXX-XXXXXXX”、”XXX-XXXXXXXX”、”XXXXXXX”和”XXXXXXXX”。
  8. 驗證中國身份證號(15 位或 18 位數字):^\d{15}|\d{18}$。
  9. 信用卡檢查:^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6011[0-9]{12}|622((12[6-9]|1[3-9][0-9])|([2-8][0-9][0-9])|(9(([0-1][0-9])|(2[0-5]))))[0-9]{10}|64[4-9][0-9]{13}|65[0-9]{14}|3(?:0[0-5]|[68][0-9])[0-9]{11}|3[47][0-9]{13})*$

四、陣列

(一)陣列值

  1. $陣列名=array(值一,值二,值三…);完全等價於這一種寫法:$陣列名=array(0=>值一,1=>值二,2=>值三…);兩者元素序相同,元素之註標索引也相同。
  2. $陣列名=array(值一,值二,值三…);不完全等價於另一種寫法:$陣列名=array(1=>值二,0=>值一,2=>值三…);兩者註標索引雖相同,但元素序不同。
    $陣列名=array(1=>值二,0=>值一,2=>值三…);的$陣列名[0]還是「值一」,但是已是此陣列的第二個元素,第一個元素已經是「1=>值二」了。
  3. $陣列名[0]=值一; $陣列名[1]=值二; $陣列名[2]=值三;,
  4. 將值指給一個原先並不存在的陣列元素,將建立一個新元素。如陣列原有四個元素(標註0-3),你卻使用標註6,則標註4,5的元素值為null,標註6用你指的值,變成七個元素。
  5. $陣列名=range(1,10);將1到10派給陣列。
  6. 多維:$陣列名=array(array(…),array(…),…);其元素以$陣列名[i][j]代表,餘類推。
  7. 多維:$陣列名=array(array(引一=>值一,引二=>值二,引三=>值三…),…);其元素以$陣列名[i][引數]代表,餘類推。
  8. for($i=0;$i<某數;$i++){while(list($key,$value)=each($陣列名)){echo "|$value";}echo "<br>";},將上項二維陣列逐行印出。
  9. 陣列間不知如何比大小,所以多元陣列,很難排序,只能用usort()自行定義排序p83。

(二)陣列之索引

  1. 凡陣列之元素必有索引(key)與值(value)。
  2. 索引可為註標索引,key為數值,不加引號;索引可為字串索引,key為字串,加引號。
  3. 標註不等於元素序。

甲、註標索引陣列

  1. 在指定元素時,同時指定key和value,寫成0=>值一。key可自由指定,但key相同算一個元素,且以後面設定的值為值。註標如果不連續,缺註標處就沒元素,count元素個數時不算,也無法用註標取值。
  2. 如果給元素時,只給值,沒給key,預設key為註標,PHP系統會自派key給元素,從0開始派,已被其他元素用掉的註標跳過;依元素序派,已有key的元素跳過。如array(1=>200,0=>100,400,3=>300),其中400會被派2為key,而元素序在100之後300之前。
  3. 按索引找不到元素值時,只送出空值,不會有錯誤或警告訊息,程式也照樣執行。

乙、字串索引陣列(又稱雜湊Hash、組合陣列、關聯式陣列)(

  1. $雜湊名=array('引一'=>值一,'引二'=>值二,'引三'=>值三…);
  2. $雜湊名['引一']=值一; $雜湊名['引二']=值二; $雜湊名['引三']=值三;
  3. 字串索引的元素,用標註是找不出值的。

丙、註標字串混合索引陣列

  1. key有引號是字串索引,key沒有引號是標註索引。
  2. 如果給元素時,只給值,沒給key,預設key為註標,PHP系統會自派key給元素,從0開始派,已被其他元素用掉的註標跳過;依元素序派,已有key的元素跳過。如array('aa'=>200,0=>100,400,'3'=>300),其中400會被派1為key,而元素序在100之後300之前。
  3. each($陣列名)傳回的四個元素就是混合索引,依序為(1=>元素值,'value'=>元素值,0=>元素索引,'key'=>元素索引),為的是讓人又可以用註標取值,又可以用字串索引取值。
  4. mysql_fetch_array(結果ID)取回2N(N為欄數)個元素的陣列也是混合索引,依序為(註標=>欄值,'欄名'=>欄值,註標=>欄值,'欄名'=>欄值…),為的是讓人又可以用註標取值,又可以用字串索引取值。

(三)陣列函數

  1. in_array(元素,$陣列名):檢查陣列中是否有此一元素。
  2. array_search(值, $陣列名,[TRUE]):PHP 4 >= 4.0.5,找陣列中之值,找到傳回其key,找不到4.2.0之前傳回NULL,之後傳回FALSE。第三參數為TRUE時,還要檢查陣列中元素的型別和欲找之值符不符。
  3. reset($陣列名):將指標移到第一個元素並傳回。
  4. end($陣列名):將指標移到最後一個元素並傳回。
  5. next($陣列名):先將指標移到下一個元素,再傳回新的元素。
  6. prev($陣列名):先將指標移到上一個元素,再傳回新的元素。
  7. current($陣列名):傳回陣列中目前的元素。
  8. pos($陣列名):傳回陣列中目前的元素值,就是current()。
  9. each($陣列名):針對陣列目前的元素,傳回(0=>元素key,1=>元素值,'key'=>元素key,'value'=>元素值)等四個元素構成的陣列;並將指標移到下一個元素。如$A=each($陣列);,則$A[0]和$A['key']為目前元素的key,$A[1]和$A['value']為目前元素的值。
    1. 如此元素本身為一陣列,其值為'Array',$A[1]和$A['value']傳回'Array'這個字串。
    2. 如此元素為某「字串索引陣列」的一個元素,$A[0]和$A['key']傳回索引字串,$A[1]和$A['value']傳回元素值。
    3. 如此元素為某「非字串索引陣列」的一個元素,$A[0]和$A['key']傳回元素key,一般為元素序,$A[1]和$A['value']傳回元素值。
  10. key($陣列名):傳回目前元素的key。
  11. list($變數名1,$變數名2…)=$陣列名;將陣列中的各個元素派給一系列的變數。
  12. list($變數名1,$變數名2)=each($雜湊名);將陣列中目前元素的key和值派給兩個變數。
  13. while($變數名=each($雜湊名)){echo $變數名["key"];echo "-";echo $變數名["value"];echo "
    ";}:迴圈中會將雜湊中每一個元素的引數及值都列出來。
  14. while($變數名=each($雜湊名)){echo $變數名[0];echo "-";echo $變數名[1];echo "
    ";}:同上。
  15. while(list($變數名1,$變數名2)=each($雜湊名)) echo "$變數1-$變數2
    ":同上。
  16. range(小值,大值):產生連續整數陣列。
    sort、rsort、asort、arsort、natsort、natcasesort、ksort、krsort、usort、uasort、uksort均改變原陣列排序,並且不會傳回陣列。所謂改變排序是指影響的是reset、end、next、prev、pos的順序。
  17. sort($陣列名):洗去索引(不管註標還是字串索引),按各元素值的ASCII值或數字大小升冪排序,重派一套註標索引。
  18. rsort($陣列名):洗去索引,按各元素的ASCII值或數字大小逆向排序,原陣列改變排序。
  19. asort($雜湊名):維持索引和元素的對應關係(不管註標還是字串索引),按各元素的「值」排序。
  20. arsort($雜湊名):維持索引和元素的對應關係,按各元素的「值」逆向排序。
  21. natsort($陣列名):維持索引,自然排序,會分離出字母中的數字,然後按數字「大小」排,2是排在1之後,不是1、10、11…之後。原陣列改變排序。
  22. natcasesort($陣列名):自然排序,不分大小寫。原陣列改變排序。
  23. ksort($雜湊名):按各元素的「引數」排序。
  24. krsort($雜湊名):按各元素的「引數」逆向排序。
  25. usort($陣列名,自訂比較函式之函式名):自行定義排序,函式名加引號,洗去原索引。p83。
  26. uasort($陣列名,自訂比較函式之函式名):自行定義排序,函式名加引號,維持原索引。
  27. uksort($陣列名,自訂比較函式之函式名):自行定義函式,依索引排序,函式名加引號,維持原索引。
  28. shuffle($陣列名):隨機排序(洗牌法)。
  29. array_reverse($陣列名):產生一個新陣列但次序相反。
  30. array_merge($陣列名,$陣列名,…):合併諸陣列。
  31. array_push($陣列名,新元素):把新元素加到陣列最後一個元素,元素個數加一。
  32. array_pop($陣列名):取出並傳回陣列最後一個元素,元素個數少一。
  33. array_map(函式,陣列1,[,陣列2...]):將陣列1,2的諸元素代入函式,得到一個新陣列。
  34. array_walk($陣列名,自訂函式,可選用之函式參數):陣列元素之字串處理函式。
  35. array_keys(陣列):取回陣列所有元素之索引,成為新陣列。新陣列為註標索引(原陣列可能為字串索引)。
  36. array_values(陣列):取回陣列所有元素之值,成為新陣列。新陣列為註標索引(原陣列可能為字串索引)。
  37. array_sum(陣列):計算並傳回陣列中所有值的和。
  38. $陣列名=file("路徑檔名"):將檔內資料一行為一元素存入陣列。
  39. count($陣列名):計數元素個數。
  40. sizeof($陣列名):計數元素個數,同上。
  41. value($陣列名):傳回雜湊,key是陣列中的單一值,value是各單一值在陣列中的出現次數(頻率)。
  42. extract($雜湊名,可選用的淬取型別,prefix字串):把每一key全部變成變數,變數名是key,變數值是其value。淬取型別:
    1. EXTR_OVERWRITE:當重覆發生時,覆寫。
    2. EXTR_SKIP:當重覆發生時,略過。
    3. EXTR_PREFIX_SAME:當重覆發生時,產生新變數容納新值,變數名為"$prefix字串_重覆之key"。
    4. EXTR_PREFIX_ALL:全部取新變數容納新值,變數名為"$prefix字串_重覆之key"。
  43. array compact(許多字串或陣列):傳回陣列,各元素索引為變數名、值為變數值,值可以是陣列、字串或其他資料型別。引數若為字串則此字串代表變數名,傳回陣列多一元素:其索引為變數名、值為變數值;引數若為陣列則遞迴處理至元素的value為變數名為止。但引數不能是超全局變數。如:
    $city='SanFrancisco';$state='CA';$event='SIGGRAPH';
    $location=array('city','state');
    $oneArray=array(1,2,3,4);
    $result=compact('event','nothing_here','oneArray',$location);
    則$result之值為:
    array('event'=>'SIGGRAPH','oneArray'=>array(1,2,3,4),'city'=>'San Francisco','state'=>'CA')
    nothing_here因為沒有任何變數名相符,所以沒作用。
  44. max(許多數值或陣列):傳回諸數值中或陣列中,數值最大者。如:max(2,3,1,6,7)傳回 7 ;max(array(2, 4, 5))傳回 5 。
  45. min(許多數值或陣列):傳回諸數值中或陣列中,數值最小者。如:min(2,3,1,6,7)傳回 1 ;min(array(2, 4, 5))傳回 2 。

    五、類別與物件

    (一)定義類別

    1. class 類別名{                           // 定義一個類別(class)
        var $屬性1;                           // 類別內本地變數為屬性
        var $屬性2;                           // 類別內函式為方法
        function 類別名(){                    // 方法名若為類別名,當產生物件時就先執行此方法
      	echo "start!!";
        }
        function 方法2(){
      	echo $this->屬性1+$this->屬性2;     // 類別內稱自身物件為this,取物件之屬性或方法:物件名->
        }
      }
    2. class 子類別 extends 父類別 {}:子類別擁有父類別的全部屬性和方法,可以進一步修改原有屬性和方法,也可再增加屬性和方法。
    3. 類別::方法:不用new物件,直接執行類別中的某方法。
    4. 物件的屬性不一定要在類別中定義,也可以在物件形成後再用「$物件->屬性=值;」來添加。
    5. 在類別定義內用this直接引用物件內其他屬性及方法做事,很獨立也很方便。
    6. $this->xxx為屬性,用動態變數代表函式名時,不能使用 $$this->xxx() 或 ${$this->xxx}(),必須分兩行撰寫:「$temp=$this->xxx;$temp();」。但可以使用 $this->$xxx() 。因為 $this 已是一個須代入物件名稱的變數。

    (二)重要提示

    1. 有一預設的類別StdClass毋須定義,「new StdClass;」等價於「(object)null」。可以不去定義類別先產生空物件後,再用「$物件->屬性=值;」去添加此物件的屬性。
    2. 使用物件的方法和屬性時,方法名和屬性名可以使用變數以增加彈性,如「$o->$a」、「$o->$b()」。

    六、參照

    (○)觀念

    記憶體上的位置 記憶體上的資料
     ↓     ↙
    0xF3A2型別
    變數表:
    變數名位址
    a0xF3A2
    $b參照$a
    變數名位址
    a0xF3A2
    b0xF3A2
    1. 參照是指「指定位址上的對應資料,包含型別和值」。
    2. 指標型的資料:變數、物件、函式傳回值,才可以直接使用參照。參照後其資料型別與被參照者的資料型別一樣。

    (一)三種可以使用參照的資料

    1. 參照變數:「$b = & $a;」$b是參照變數,PHP存取參照變數時,會存取記憶體位置上對應的資料。所以當$a變動時,$b也跟著變動;而$b變動時$a也跟著變動。
    2. 物件:
      • PHP4時,一new 類別就產生一個物件,此時用「$bar=new fooclass();」會再拷貝一個物件然後指派給$bar;而「$bar=&new fooclass();」則讓$bar成為參照變數,實際只產生一個物件。這樣能減少記憶體消耗和提高性能。
      • PHP5時,只要等號右邊是物件,「=」便代表參照而非拷貝,和「=&」等價。要拷貝須用「= clone 物件」。此意味著,寫程式必須區別物件與非物件資料型態,降低了 PHP 的泛型能力,也造成了語言陷阱(trick)。
    3. 資源:「$bar=&mysql_query(…);」因為資源型的資料也是靠記憶體指標來存取,所以也可以用參照來節省資源。
    ※foo、bar、foobar是技術文件中常用的函式、類別或變數名,foo源於中文的「福」。

    (二)傳址呼叫(Passing by Reference)函式

    1. 一般函式的引數不加&,稱為「傳值呼叫」。作法是在函式內拷貝一份變數,函式運算作用在拷貝變數上,不影響原變數。因為有變數的複製所以速度慢。
    2. 「function foo(&$var){$var++;} $a=5;foo($a);」將使$a的值由5變成6。foo($a)是直接將$a記憶體位址上的變數內容,直接交給函式操作(加1)。因為沒有變數的複製所以速度快。注意在函式呼叫時沒有參照符號,只有函式定義中有。
    3. 在傳址呼叫函式內部,操做的是位址上面的內容,無法對位址進行存取和操作。
      「$bar=5;$GLOBALS["baz"]='6';」如果:
      • 「function foo(&$var){$var=&$GLOBALS["baz"];}」則「foo($bar);」將無法使$bar的值成為6,$bar的值仍維持為5。因為:foo($bar)呼叫函式時,只會直接把$bar位址上的內容交給函式操作,不會將$bar的位址交給函式操作,所以函式內部並不知道的$bar的位址,也無法透過修改$bar的位址,將$bar參照到$GLOBALS["baz"]。所以沒有辦法透過參照機制,在函式內部對傳入變數重新進行參照綁定。
      • 「function foo(&$var){$var=$GLOBALS["baz"];}」則「foo($bar);」將使$bar的值成為6,型別也轉換成string。
    4. 送給傳址呼叫的引數除了不能是非指標型的6類實字之外,可以是其他指標型資料如變數。如要傳非指標型的實字,可以先將用派值敘述將實字派給變數,再將此變數送給傳址呼叫:(例子中的foo是一個傳址呼叫函式,function foo (&$var){…})
      1. 送變數:例如foo($a)。
      2. 送派值式:如foo($a = 5),先把5派給變數$a,再把$a代入函式。
      3. 送New 語句:例如 foo(new StdClass)。
      4. 另一函式的傳回值。PHP4晚期之後,所有函式的傳回值都帶指標,都可以用於傳址呼叫的參數。但早期不是:
        • 可以使用「函數傳回參照」:例如「function &bar(){$a=5;return $a;}function foo(&$b){echo $b;}foo(bar());」會得到5。bar()傳回的是傳回值的參照,foo函式依定義需要傳入參照,而函式內運算的是參照位址上的內容。
        • 不能使用非函數傳回參照的傳回值:如「function bar(){$a=5;return $a;}foo(bar());」
      以下方式不合法:
      • 送6類非指標實字:如foo(5)。

    (三)函數傳回參照(Returning References)

    1. PHP4後期,所有函式回傳值均帶有記憶體位址及其內容,均可以用於傳值呼叫與傳址呼叫。所以已經不再需要在定義函式時,在函式名稱前加「&」。
    2. 早期:定義時如果函式名加了&,則函式傳回的是指定位址及其位址上的內容,即參照。這樣傳回的參照才能用於傳址呼叫,讓傳址呼叫函式直接對位址上的內容進行操作,省去複製變數,提升效能。

    (四)取消參照

    unset 一個參照變數,只是斷開了變數名和變數內容之間的綁定。這並不意味著變數內容被銷毀了。例如: 「$a=1;$b=&$a;unset ($a);」不會 unset $b,只是 $a。過程如下:
    1. 變數表中記下變數名a及其位址,並在此位址上放入1。
    2. 變數表中增加變數名b,其位址抄自a變數的位址。
    3. 刪去變數表中的a變數。

    (五)其他參照

    1. 宣告一個全域變數「global $var;」等價於「$var =& $GLOBALS["var"];」,這意味著 unset $var 不會 unset 全域變數。
    2. 在一個物件的方法中,$this 永遠是呼叫它的物件的參照。

    肆、控制結構

    ○、敘述區塊

    1. 敘述區塊:{}中間放可執行的的敘述。區塊結束處不必加';',但區塊內每個動作末尾均要加';'
    2. 單行條件:當敘述區塊只有一道敘述時,可省略{}。

    一、if

    1. if(條件一){做一}elseif(條件二){做二}elseif(條件三){做三}…else{做其他}

    二、switch

    1. switch(變數) {case 值一 : 做一;break;
      case 值二 : 做二;break;
      case 值三 : 做三;break;…
      default :做其他;break;
      }

    三、迴圈while

    1. while (條件) {合條件時做的事}
    2. while可以用來設計無窮迴圈,檢查錯誤,或要求直到做對為止。
    3. do{…}while(條件):先至少做一次,合條件繼續做。
    4. while (條件) {合條件時做的事}
    5. while ($xxx=each($陣列)) {每個元素做一輪,用$xxx[0]或$xxx['key']代表每個元素的鍵,用$xxx[1]或$xxx['value']代表每個元素的值;}

    四、for

    1. for(執行敘述;條件;反覆敘述){…}:先做執行敘述,再判斷條件,合條件則做{}中及反覆敘述。
    2. for (設初值;條件;設下一值) {合條件就做,做到不合條件} 等價於 設初值;while(條件){做;設下一值}
    3. for($num2=1;$num2<=5;$num2++){echo $num2."<br>";}

    五、foreach

    1. 陣列中每個元素做一輪。
    2. foreach($陣列 as 變數代表元素的值){使用前面的變數制作敘述;}
    3. foreach($陣列 as 用變數1代表元素的鍵=>用變數2代表元素的值){使用前面的變數製作敘述;}
    4. 和while ($xxx=each($陣列)) 比較,foreach可以用一個變數名稱代表元素值,也可用兩個變數名稱代表元素的鍵和值;而while只要用掉一個變數名稱,就能代表元素的鍵和值。特別是只要用一個變數名稱代表元素的鍵時,只能用while。
    5. 自php 5 起,foreach 還可以遍曆物件內的諸子物件。
    6. foreach 不支援用「@」來抑制錯誤資訊的能力。

    六、控制敘述

    1. continue;跳過迴圈中以後的部分,跳到迴圈頭再進行條件判斷。
    2. break;跳出迴圈由迴圈的下一道敘述開始做。
    3. exit;跳離開PHP行程。

    伍、載入程式及定義函數

    1. include("含程式之檔名"):是include被執行到才會執行載入動作。有傳回值,可以通知其他程式的其他部分,載入是否成功。
      載入順位如下:
      1. 完整的路徑+檔名
      2. 只有檔名無路徑:找 include_path 指定的目錄
      3. 只有檔名無路徑:找檔案所在的目錄
      4. 只有檔名無路徑:找目前工作目錄
      都找不到發出一條警告(E_WARNING)。
    2. require("含程式之檔名"):是母程式被解析是就會執行載入動作。
    3. include_once("含程式之檔名")、require_once("含程式之檔名"):只載入一次。
      requireinclude
      母程式被解析是就會執行載入動作被執行到才會執行載入動作
      出錯時產生 E_COMPILE_ERROR 級別的錯誤有傳回值,可以通知其他程式的其他部分,載入是否成功
      引入檔有錯,會顯示錯誤,立刻終止程式,不再往下執行引入檔有錯,會顯示警告,不會立刻停止

    陸、檔案

    1. 檔案代碼=fopen("檔名","w"):開檔,並傳回檔案代碼。指定用途r為讀,w為重寫,a為接著寫,r+,w+,a+為可讀寫,b指定為二進位檔,這是當作業系統的文字及二進位檔不同時採用,unix不需要。
    2. 檔案代碼=popen("檔名","w"):單向開檔,並傳回檔案代碼。只能用於讀或寫,指定用途r為讀,w為重寫。
    3. fread(檔案代碼,讀取位元組數):讀回指定長度的位元組或到檔尾 EOF(省略長度時)。
    4. 檔案如果未鎖定,即使某甲開檔了,持續寫入中,某乙都可以再對同一檔案進行寫入,使檔案變成兩個人寫入的交雜(像麻花一樣)。即使他們之間相互破壞也可以,要管必須由寫程式的人構思去管。這個特性使多行程共用日誌檔成為可能。
      例如:某甲啟動「$fp=fopen("temp.txt","a+");fwrite($fp,str_repeat('abc',25));sleep(100);fwrite($fp,str_repeat('abc',25));fclose($fp);」結果在sleep的100秒間,某乙又啟動「$fp=fopen("temp.txt","a+");fwrite($fp,str_repeat('def',50));fclose($fp);」
      結果是temp.txt由25個abc接著50個def再接著25個abc。
    5. fgets(檔案代碼,讀取位元組數):從檔案指標所指的行,並從該行傳回指定長度;未指定長度時傳回字串長度為行的長度減一,不含換行。 如檔案代碼指向 php://stdin 在命令列模式下會等待使用者輸入;但在瀏覽器下不會等待輸入。
    6. fwrite(檔案代碼,字串[,長度指標]):寫入字串。
    7. fputs(檔案代碼,字串[,長度指標]):將字串寫到檔案指標處。
    8. fclose(檔案代碼):關檔,把檔案代碼還給系統。
    9. pclose(檔案代碼):關檔,把檔案代碼還給系統。配合popen()使用。
    10. filesize(檔名):傳回檔案位元組數。傳回值放在快取,非常省資源。
    11. readfile(檔名):傳回檔案位元組數,並將檔案內容送至標準輸出裝置,若有錯誤傳回 false。檔名可用http://、ftp://
    12. file(檔名):傳回陣列,每元素為檔中一行。檔名可用http://、ftp://。
    13. 檔案指標函數:feof()、rewind()、fseek()、flock(),須先以fopen()函數開啟指定的檔案,再確認檔案是否成功開啟後才可使用。
      • feof(檔案代碼):判斷檔案是否已經到檔案結尾,若到結尾傳回True;反之傳回False。
      • rewind(檔案代碼):將指標移到檔案最前面,若到最前面傳回True;反之傳回False。
      • fseek(檔案代碼,移動位元數,起始位置參數):將檔案指標由某一位置移到另一位置,並可指定要移動的位元數,若成功執行,傳回True;反之傳回False。移動位元數:正數,表指標往右移動;負數,指標往左移動。透過URL 所開啟的檔案,無法使用fseek()函數來移動檔案指標。
        起始位置的參數:SEEK_SET:從檔案開頭算起,這是預設值,沒設即此值;SEEK_CUT:從目前指標所在位置算起;SEEK_END:由檔案結尾算起。
      • flock(檔案代碼,鎖定參數):當多人要同時存取同一檔案時,為了確保資料的正確性,要寫入資料時,可以先將該檔案鎖住,等寫完資料再解開。
        鎖定參數:LOCK_SH:鎖定檔案讀取;LOCK_EX:鎖定檔案寫入;LOCK_UN:解除鎖定。

    柒、函式

    PHP學習誌中有各種PHP指令清單的扼要解說與範例。
    1. 函式是整合諸敘述的算符。
    2. 定義函式:function 函式名 ($引數[=初值],&$引數){含$引數之諸敘述}。函式名不可用數字開頭,函式名不可以用保留字如「list」,函式名可以使用中文,可以使用變數。函式名之前可以加&,使傳回值為參照供另一個傳址呼叫函式之用。但PHP4後期已經改為所有函式的傳回值均為指標型資料(帶記憶體位址),所以在函式名之前加&已無必要。
      引數前不加&為傳值呼叫,在函式內複製一個變數,函式對此變數進行操作,函式結束收回變數空間。引數前加&,為傳址呼叫,不必在函式內複製一個變數,而是讓函式直接操作位址上的內容。所以引用函式時傳入的資料須是指標型的資料。如果要傳入實字(非指標)要先轉化成變數(指標),如foo($a=5)。
      傳址呼叫會改變傳入變數的值,要確定對該變數進行操作時才應使用。
      引數為物件或陣列時,傳址呼叫能有較大的好處;引數為變數但非物件或陣列時,好處較小;引數為實字時,傳址呼叫沒有好處。
      傳值函式定義時引數前不加&不影響輸入值函式內只能操作複製的輸入值變數,不能操作輸入值的內容或指標
      傳址函式定義時引數前加&直接改變輸入值內容函式內只能操作輸入值的內容,不能操作輸入值的指標
    3. 引用函式時,函式名可用變數$xxx()、$this->$xxx(),函式引數中的預設值不可用函式,可用變數。
    4. 遞迴函式:function 函式名 {… 函式名()…},時一定要設定停止點,不然會陷入無窮迴圈。
    1. 連結MySQL
      1. mysql_pconnect("機器", "使用者", "通行碼"):連上MySQL。連成,傳回連結ID,失敗傳回false。傳回的是一個「持續連結」,不會在程式結束或mysql_close()時結束。下次再用pconnect,會先去看有沒有已開啟的持續連結可用,如有就用,不會再去開新的持續連結。
      2. mysql_connect("機器", "使用者", "通行碼"):連上MySQL。連成,傳回連結ID,失敗傳回false。傳回的是「非持續連結」,連結在程式結束或mysql_close()時結束。misqli為mysqli_connect("機器", "使用者", "通行碼","資料庫名");
      3. mysql_close(連結ID):關閉一個「非持續連結」。沒啥用,持續連結不能關,非持續連結到程式結束時會自動關閉。mysqli為mysqli_close(連結ID)。
      4. mysql_select_db("資料庫名",[連結ID]):使用資料庫,可指定資料庫連結,如果沒指定,會使用最後一個被開啟的連結。如果沒指定連結,也沒有已開啟的連結,會去叫mysql_connect()來開啟連結。
      5. $result = mysql_query(命令字串,[連結ID]):下命令給MySQL,並將結果傳回給指定變數。可指定資料庫連結,如果沒指定,會使用最後一個被開啟的連結。如果沒指定連結,也沒有已開啟的連結,會去叫mysql_connect()來開啟連結。傳回結果ID,失敗時傳回false。mysqli為mysqli_query(連結ID,命令字串)
      6. $result = mysql_db_query(資料庫名,命令字串,[連結ID]):mysql_select_db()和mysql_query()的組合。
      7. mysql_insert_id([連結ID]):傳回AUTO_INCREMENTED欄位最所產生的id,如果省略連結ID則假定是最後所開啟的連結。如果AUTO_INCREMENTED的欄位是bigint(64bit)會因為傳回的位數太大而出錯,php的整數只到32bit,此時就要用MySQL自己的函數 LAST_INSERT_ID([expr]) 來取值。
      8. mysql_num_rows(結果ID):查傳回的筆數。
      9. mysql_data_seek(結果ID,跳過筆數):將筆指針下移幾筆,之後用mysql_fetch_array,取出的是下移後的首筆。如果結果中本沒就沒筆,會傳回false。
      10. $row = mysql_fetch_array(結果ID,傳回索引型態):傳回索引型態可省略,有三值MYSQL_ASSOC、MYSQL_NUM、MYSQL_BOTH,預設為MYSQL_BOTH。
        MYSQL_BOTH:結果集合若有n欄,取出結果集合中的一筆資料,丟進一個陣列,此陣列有2n個元素,(0=>欄值,'欄名'=>欄值,1=>欄值,'欄名'=>欄值…)。可用$row['欄名']來取各欄之值,也可用$row[0],$row[1]…來取各欄之值。
        MYSQL_ASSOC:傳回n欄,以欄名為字串索引。即mysql_fetch_assoc()。
        MYSQL_NUM:傳回n欄,註標索引,即mysql_fetch_row()。
      11. $row = mysql_fetch_assoc(結果ID):結果集合若有n欄,取出結果集合中的一筆資料,丟進一個陣列,此陣列有n個元素,('欄名'=>欄值,'欄名'=>欄值,'欄名'=>欄值…)。用$row['欄名']…來取各欄之值。
      12. $row = mysql_fetch_row(結果ID):結果集合若有n欄,取出結果集合中的一筆資料,丟進一個陣列,此陣列有n個元素,(0=>欄值,1=>欄值,2=>欄值…)。用$row[0],$row[1]…來取各欄之值。
      13. $row = mysql_fetch_object(結果ID):取出結果集合中的一筆資料,丟進一個物件,每一欄是一性質。用$row->欄名,來取各欄之值。
      14. $row = mysql_result(結果ID,筆次,'欄名'):取出結果集合中的某欄、某筆資料。筆次是結果集合中的筆次,不是資料表中的筆次。
      15. mysql_affected_rows():最後一次查詢,MySQL受影響的筆數。
      16. mysql_num_fields (結果ID):共幾欄。
      17. mysql_field_table(結果ID,第幾欄):查該欄所屬的資料表,如果該表有代稱,傳回的是代稱。
      18. mysql_field_name (結果ID,第幾欄):查欄名。
      19. mysql_field_type (結果ID,第幾欄):查欄型。
      20. mysql_field_len (結果ID,第幾欄):查欄長。
      21. mysql_field_flags(結果ID,第幾欄):查欄旗。
        MySQL php查回欄型(欄長)[欄旗] 適合的物件
        text blob(65535*3)[not_null blob] XoopsFormTextArea
        blob blob(65535) [not_null blob binary] XoopsFormFile
        char string(*) [not_null] XoopsFormText
        enum string(元素之字元和)[enum]
        set string(元素組合之字元和)[set]
        float real(*) [not_null] XoopsFormText
        int int(*) [not_null] XoopsFormText
        bool int(1) [無] XoopsFormRadioYN
        timestamptimestamp(19)[not_null unsigned zerofill binary timestamp]XoopsFormText
        year year(4) [not_null unsigned zerofill] XoopsFormText
        datetime datetime(19) [not_null binary] XoopsFormText
        date date(10) [not_null binary] XoopsFormText
        time time(8) [not_null binary] XoopsFormText

        欄旗 含意
        not_null 不可為null
        欄旗無值,而不是null 可null時
        primary_key 有主鍵或唯一索引鍵其中之一
        primary_key unique_key兼有主鍵及唯一索引鍵
        multiple_key 有一般索引鍵
        blob 區塊
        unsigned 無正負數值
        欄旗無值,而不是signed有正負數值,預設
        zerofill 必為unsigned
        binary 二進位值
        enum enum欄
        set set欄
        auto_increment 自動加一,數值欄才行
        timestamp 時間戳記
        預設值怎麼查還不知道,但phpmyadmin查得到。
      22. mysqli連結沒有 mysqli_field_name 等函式,是用 mysqli_fetch_field_direct(結果ID,第幾欄) 得回物件,此物件的 name 屬性為欄名、 table 屬性為表名,詳述如下:
        1. name - 欄名
        2. orgname - 原始的欄名(如果指定了別名)
        3. table - 表名
        4. orgtable - 原始的表名(如果指定了別名)
        5. def - 該欄的預設值
        6. max_length - 欄的最大寬度
        7. length - 在表定義中規定的欄寬度
        8. charsetnr - 欄的字符集號
        9. flags - 欄的位標誌
        10. type - 用於欄的數據類型
        11. decimals - 整數欄,小數點後的位數
      23. mysql_free_result(結果ID):放掉儲存這個結果的記憶體。mysqli為mysqli_free_result(結果ID)。
      24. mysql_create_db("資料庫名",[連結ID]):建立資料庫,可指定資料庫連結,如果沒指定,會使用最後一個被開啟的連結。成功傳回true,失敗傳回false。
      25. mysql_drop_db("資料庫名",[連結ID]):刪除資料庫,可指定資料庫連結,如果沒指定,會使用最後一個被開啟的連結。成功傳回true,失敗傳回false。
      26. mysql_error():傳回與 MySQL 互動最近的錯誤訊息。
      27. mysql_errno():傳回與 MySQL 互動最近的錯誤代碼。未連接資料庫即提出請求的錯誤代碼是1045。
        代碼列表如下:
        1005:建立資料表失敗
        1006:建立資料庫失敗
        1007:建立資料庫失敗,原因:資料庫已存在
        1008:刪除資料庫失敗,原因:資料庫不存在
        1009:刪除資料庫失敗:不能刪除資料庫文件
        1010:刪除資料庫失敗:不能刪除資料目錄
        1011:刪除資料庫文件失敗
        1012:不能讀取系統表中的記錄
        1020:記錄已被其他用戶修改
        1021:硬碟可用空間不足,請加大硬碟可用空間
        1022:關鍵字重複,更改記錄失敗
        1023:關閉時發生錯誤
        1024:讀文件錯誤
        1025:更改名字時發生錯誤
        1026:寫入文件錯誤
        1032:記錄不存在
        1036:資料表是唯讀,不能進行修改
        1037:系統記憶體不足,請重新啟動資料庫或伺服器
        1038:用於排序的記憶體不足,請加大排序緩衝區
        1040:已達資料庫最大連接數,請加大資料庫可用連接數
        1041:系統記憶體不足
        1042:無效的主機名稱
        1043:無效的連接
        1044:目前所使用的用戶無訪問資料庫的權限
        1045:無法連接資料庫,原因:用戶名稱或密碼錯誤
        1048:字段不能為空
        1049:資料庫不存在
        1050:資料表已存在
        1051:資料表不存在
        1054:字段不存在
        1065:無效的SQL 語句,原因:SQL 不能為空
        1081:不能建立 Socket 連接
        1114:資料表已滿,不能容納任何記錄
        1116:開啟的資料表太多
        1129:資料庫出現異常,請重新啟動資料庫
        1130:連接資料庫失敗,原因:無連接資料庫權限
        1133:資料庫用戶名稱不存在
        1141:目前用戶身分無權限訪問資料庫
        1142:目前用戶身分無權限訪問資料表
        1143:目前用戶身分無權限訪問資料表中的字段
        1146:資料表不存在
        1147:未定義用戶對資料表的訪問權限
        1149:SQL 語法錯誤
        1158:網路錯誤,出現讀取錯誤,請檢查網路連線狀態
        1159:網路錯誤,讀取時間超時,請檢查網路連線狀態
        1160:網路錯誤,出現寫入錯誤,請檢查網路連線狀態
        1161:網路錯誤,出現寫入超時,請檢查網路連線狀態
        1062:字段值重複,寫入資料庫失敗
        1169:字段值重複,更新記錄失敗
        1177:打開資料表失敗
        1180:提交事務失敗
        1181:回復事務失敗
        1203:超過資料庫最大連接數,請加大可用的資料庫連線數或重新啟動資料庫
        1205:加鎖超時
        1211:目前用戶沒有建立用戶的權限
        1216:外鍵約束檢查失敗,更新子表記錄失敗
        1217:外鍵約束檢查失敗,刪除或修改主表記錄失敗
        1226:目前用戶使用的資源已超過所允許的資源,請重新啟動資料庫或重新啟動伺服器
        1227:權限不足,您無權進行此操作
        1235:MySQL 版本過舊,不具此功能。
      28. mysqli_connect_errno(連結ID):mysqli 連結的錯誤代碼。省略連結ID則指最近一次連結。沒錯傳回 0 。
      29. mysqli_connect_error(連結ID):mysqli 連結的錯誤訊息。
    2. 連結DBASE
      1. 編輯資料表最佳方式,還是以Excel編dbf檔,可以靈活搬移筆。
      2. 在windows下:
        1. 找到php\extensions下,確實有php_dbase.dll。
        2. 在windows下找到php.ini。
        3. 改extension_dir = ./ =>extension_dir = c:\php\extensions
        4. 改;extension=php_dbase.dll,將行首分號去掉,改抑制為啟動。
        5. 重新啟動apache。
    3. 連結Socket
      1. 要--enable-sockets,才有諸socket常數及函式可用,此點可在phpinfo()中Configure Command欄查出來。如美國的GoDaddy.com租賃網站就不能用,而戰國策可用。
      2. $socket=socket_create(AF_INET, SOCK_STREAM, SOL_TCP);:建立一個插頭。
      3. socket_connect($socket,'ip',port):該插頭對伺服器建立一個連線。
      4. $command="GET /程式?變數 HTTP/1.0\nhost:伺服器\n\n";:造一個 HTTP 請求,第一行交代通道、目的程式、HTTP版本,三者用空白間隔開;然後換行交代伺服器(無http://);然後換行兩次,表示請結束。
      5. socket_write($socket,$command,strlen($command)):經通道送一個命令給伺服器。
      6. socket傳回值時,通常一次只能讀2k,所以要用迴圈讀取。如:while($response=socket_read(socket連線代碼,1024)){$temp.=$response;}
      7. socket_close($socket):關閉連線
      8. socket_bind($socket,'ip',port):和socket_connect功能類似,但卻是用來配合socket_listen()。
      9. socket_listen($socket[,佇列數]):可以開始聽取客戶端請求,不一定會接受(可能請求太多,無法每個都接受)
      10. socket_accept($socket):接受客戶端連線進來,並分配一個代表客戶端的代碼。如果沒有客戶端要連進來,就等到有,或出現錯誤為止。
      11. fsockopen(伺服器,port,錯誤號的接受變數,錯誤提示的接受變數,超時時間):將返回一個檔案代碼,之後可以被其他檔案類函數調用(例如:fgets(),fgetss(),fwrite(),fclose()還有feof())。如果調用失敗,將返回FALSE。
        fsockopen()函數比fopen()函數的優點:fopen()只會在PHP中已經將allow_url_fopen設置為真時才能使用,而fsockopen()並沒有限制。
        fsockopen()可以用來發送 HTTP 請求(HTTP Client實作),其範例程式在丁丁各伺服器的 study 資料夾下的 fsockopen.php,GetTimeWebService.php ,內容是參考 https://blog.toright.com/posts/2721/php-如何透過-fsockopen-發送-http-request-http-client實作.html 。
        另一個可用來發送 HTTP 請求的函式是 file_get_contents(URL) 。
      12. 用 socket 編寫一個簡單的HTTP Server,請參考:https://codertw.com/程式語言/110155/
    4. 檔案格式轉譯函式,如:JSON,CSV
      1. json_decode(json字串[,傳回陣列,解析的遞迴深度(預設512層),位掩碼]):對 JSON 格式的字符串進行解碼。
        json字串,代入實字時,最外層必須以單引號(')包絡區隔,內部使用雙引號區分字串;不能以雙引號(")包絡區隔,內部使用單引號(')區分字串。代入變數則內部須使用雙引號區分字串。
        傳回陣列若true,傳回陣列,若false傳回物件,預設為假(false)。
        位掩碼(bitmask),預設0即:將大整數轉換為浮點數。目前的選用值只有 JSON_BIGINT_AS_STRING ,若選用,大整數視為字串,不視為浮點數。
      2. json_last_error():傳回 json_decode 過程中發生的錯誤代碼,0代表沒錯:
        0:JSON_ERROR_NONE
        1:JSON_ERROR_DEPTH
        2:JSON_ERROR_STATE_MISMATCH
        3:JSON_ERROR_CTRL_CHAR
        4:JSON_ERROR_SYNTAX
        5:JSON_ERROR_UTF8
        6:JSON_ERROR_RECURSION
        7:JSON_ERROR_INF_OR_NAN
        8:JSON_ERROR_UNSUPPORTED_TYPE
      3. json_encode(resource型別以外的資料[,二進制掩碼]):傳回 json 字串,傳回值使用雙引號區分字串。
        資料只接受 UTF-8 編碼。
        位掩碼代表常數如下:
        JSON_HEX_TAG => 1
        JSON_HEX_AMP => 2
        JSON_HEX_APOS => 4
        JSON_HEX_QUOT => 8
        JSON_FORCE_OBJECT => 16
        JSON_NUMERIC_CHECK => 32
        JSON_UNESCAPED_SLASHES => 64
        JSON_PRETTY_PRINT => 128
        JSON_UNESCAPED_UNICODE => 256
        JSON_PARTIAL_OUTPUT_ON_ERROR => 512
        JSON_PRESERVE_ZERO_FRACTION => 1024
      4. fgetcsv(檔案代碼[,行的最大長度,分界符,環繞符]):從檔案指針處中讀入一行並解析 CSV 字串傳回陣列;出錯或碰到文件結束時傳回FALSE。
        行的最大長度必須大於 CVS 文件內最長的一行,預設為0,即長度沒有限制,但會影響執行效率。
        分界符(只允許一個字符)預設為逗號「,」。
        環繞符只允許一個字符)預設為雙引號「"」。
        常用的讀取手法「while(!feof(檔案代碼)){$陣列[]=fgetcsv(檔案代碼);}」
    5. 時間
      1. time():1970年到當下的秒數再減時區秒數。
      2. mktime(時,分,秒,月,日,年):1970年至此時的秒數再減時區秒數。
      3. date(格式,秒數):將秒數加時區秒數,再換讀為日期時間。格式:年月日時分秒YmdHis,星期幾(0-6)w,年月第幾日z,是否閏年L,該月共幾日t,秒數U,時區秒數Z。因為時間格式中有用到B,r,所以換行只能寫成<bR>。
        PHP MySQL 含意
        date(格式,秒數) DATE_FORMAT('年-月-日 時:分:秒',格式)
        格式不加% 格式加%
        a "am" 或 "pm"
        A %p "AM" 或 "PM"
        B 網際網路時間樣本
        d %d 幾日,例如:" 01" 到 " 31"
        D %a 星期幾,以3個英文字表示,例如:" Fri "
        %W 星期幾 (Sunday..Saturday)
        F %M 幾月,以英文全名表示,例如:January..December
        g %l 小時,12小時制不足2位數不補0,例如:" 1 " 到 " 12 "
        G %k 小時,24小時制不足2位數不補0,例如:" 0 " 到 " 23 "
        h %h,%I 小時,12小時制,例如:" 01 " 到 " 12 "
        H %H 小時,24小時制,例如:" 00 " 到 " 23 "
        i %i 幾分,例如:" 00 " 到 " 59 "
        I (大寫的 i) "1" if Daylight Savings Time, "0" otherwise.
        j %e 幾日,不足2位數不補0,例如:" 1" 到 " 31"
        l (小寫的 L) 幾日,以英文全名表示,例如:"Friday"
        L 布林值,判斷是否為閏年,例如:" 0" 或 " 1"
        m %m 幾月,例如:" 01" 到 " 12"
        M %b 幾月,以3個英文字表示,例如:"Jan"
        n %c 幾月,不足2位數不補0,例如:" 1" 到 "12"
        r 全部,例如:"Thu, 1 Jan 1970 08:00:00 +0800"
        %r 時分秒,12 小時 (hh:mm:ss [AP]M)
        %T 時分秒,24 小時 (hh:mm:ss)
        s %S,%s 幾秒,例如:" 00" 到 " 59"
        S 幾日,以英文後2個字表示,例如:"th","nd"
        %D 幾日,有英文後綴的某月的第幾天 (0th, 1st, 2nd, 3rd, etc.)
        t 當月的天數,例如:" 28" 到 " 31"
        T 這個機器的時間區域設定,例如 :"MDT"
        U 總秒數
        W %u,%v 本年的第幾週,逢週一換新週,一年首週為第1週。
        %U,%V 本年的第幾週,逢週日換新週,一年首週為第0週。
        w %w 以數字表示星期幾,例如:0=Sunday..6=Saturday
        Y %Y,%X,%x 幾年,以4位數表示,例如:" 1999"
        y %y 幾年,以2位數表示,例如:"99"
        z 一年中的第幾天,例如:" 0" 到 " 365"
        %j 一年中的第幾天,例如:001..366
        Z 在短時間內時間區域補償(timezone offset) ,例如:"-43200" to "43200"
        %% 一個文字「%」
      4. date和mktime的時區因素會互相抵消。date("Y-m-d-H:i:s",mktime(0,0,0,1,1,1970))還是會得出1970-01-01-00:00:00,不論在那一個時區。用date("Y-m-d-H:i:s",mktime())可求出目前的系統時間。
      5. int checkdate(int月,int日,int年):檢查日期是否有效,true有效,false無效。可查閏年。
      6. strtotime(日期時間規定字串,計算基準時間戳記):返回新的時間戳記,省略引數內的時間戳記會引用目前的時間。可用的日期時間規定字串如下:
        • 'now'
        • 某日期如'2017-09-05'
        • 某日期時間如'2017-09-05 13:25:00'
        • 某日期如'15 October 1980'
        • 某日期.'+1 day'
        • '+1 day +1 hour +1 minute':可用year(年),month(月),day(日),hour(小時),minute(分),second(秒)
        • '+5 hours'
        • '+1 week'
        • '+1 week 3 days 7 hours 5 seconds'
        • 'next Monday'
        • 'last Sunday'
      7. sleep(秒數):等待幾秒。javasript無類似的函式,要使用者自己寫:
        function sleep(numberMillis){
          var now=new Date();
          var exitTime=now.getTime()+numberMillis;
          while(true){now=new Date();if(now.getTime()>exitTime) return;}
        }
      8. time_nanosleep(秒數,納秒數):等待幾秒加幾納秒。1納秒為十億分之一秒。兩參數均須為整數。本函數未在 Windows 平台下實現。
    6. 寄信
      1. mail(給誰,主旨,內容,額外標頭):傳回布林值,寄mail。前提是必須使用一個不用驗證即可寄信的 SMTP 。
      2. 加附檔,先將附檔讀入變數 $data=fread(代碼,大小) ,將其編碼再切成76字元一小段 $data = chunk_split(base64_encode($data)) ,然後將 $data 包於下列字串中:
          $內容 .= "--分隔字串\n" .
        	       "Content-Type: 檔案型別;\n" .
        	       " name=\"檔名\"\n" .
        	       // "Content-Disposition: attachment;\n" .
        	       // "filename=\"{$fileatt_name}\"\n" .
        	       "Content-Transfer-Encoding: base64\n\n" .
        	       $data . "\n\n" .
        	       "--分隔字串--\n";
    7. 收信(IMAP,已打開的某個IMAP流,在本段中簡稱為$imap)
      1. imap_8bit(字串) - 將8位元字串轉換為帶引號的可打印字串
      2. imap_alerts - 返回發生的所有IMAP警告郵件
      3. imap_append - 將字串附加到指定的郵箱
      4. imap_base64(字串) - 解碼BASE64編碼的文本
      5. imap_binary(字串) - 將8位元字串轉換為base64字串
      6. imap_body - 閱讀郵件正文
      7. imap_bodystruct - 讀取特定郵件的指定正文部分的結構
      8. imap_check - 檢查當前郵箱
      9. imap_clearflag_full - 清除郵件標誌
      10. imap_close($imap,[常數CL_EXPUNGE]) - 關閉IMAP流。如給出常數CL_EXPUNGE,則在關閉連結前先清理電子信件信箱。
      11. imap_create - imap_createmailbox的別名
      12. imap_createmailbox - 創建一個新郵箱
      13. imap_delete($imap,幾封信) - 將郵件標記為從當前郵箱中刪除
      14. imap_deletemailbox - 刪除郵箱
      15. imap_errors - 返回發生的所有IMAP錯誤
      16. imap_expunge - 刪除標記為刪除的所有郵件
      17. imap_fetch_overview - 閱讀給定郵件標題中郵件的概述
      18. imap_fetchbody($imap,區段序,區段數目) - 獲取郵件正文內的指定區段
      19. imap_fetchheader - 返回郵件的標題
      20. imap_fetchmime - 為郵件的特定部分獲取MIME標頭
      21. imap_fetchstructure($imap,資訊數) - 讀取特定郵件的結構
      22. imap_fetchtext - imap_body的別名
      23. imap_gc - 清除IMAP緩存
      24. imap_get_quota - 檢索每個郵箱的配額級別設置和使用率統計郵件
      25. imap_get_quotaroot - 檢索每個用戶的配額設置
      26. imap_getacl - 獲取給定郵箱的ACL(存取權控制清單)
      27. imap_getmailboxes - 閱讀郵箱列表,返回每個郵箱的詳細郵件
      28. imap_getsubscribed - 列出所有訂閱的郵箱
      29. imap_header($imap,郵件數) - 讀取郵件的標題,省略郵件數,代表全部
      30. imap_headerinfo - imap_header的別名
      31. imap_headers - 返回郵箱中所有郵件的標題
      32. imap_last_error - 獲取此頁面請求期間發生的最後一次IMAP錯誤
      33. imap_list - 閱讀郵箱列表
      34. imap_listmailbox - imap_list別名
      35. imap_listscan - 返回與給定文本相匹配的郵箱列表
      36. imap_listsubscribed - imap_lsub的別名
      37. imap_lsub - 列出所有訂閱的郵箱
      38. imap_mail_compose - 根據給定的信封和正文部分創建MIME郵件
      39. imap_mail_copy - 將指定的郵件複製到郵箱
      40. imap_mail_move - 將指定的郵件移動到郵箱
      41. imap_mail - 發送電子郵件
      42. imap_mailboxmsginfo - 獲取有關當前郵箱的郵件
      43. imap_mime_header_decode - 解碼MIME標題元素
      44. imap_msgno - 獲取給定UID的郵件序列號
      45. imap_num_msg - 獲取當前郵箱中的郵件數量
      46. imap_num_recent - 獲取當前郵箱中最近郵件的數量
      47. imap_open(server,username,password) - 打開一個IMAP流(本段中簡稱$imap)到郵箱
      48. imap_ping - 檢查IMAP流是否仍處於活動狀態
      49. imap_qprint(字串) - 將帶引號的可打印字串轉換為8位元字串
      50. imap_rename - imap_renamemailbox的別名
      51. imap_renamemailbox - 將舊郵箱重命名為新郵箱
      52. imap_reopen - 重新打開IMAP流到新郵箱
      53. imap_rfc822_parse_adrlist - 分析地址字串
      54. imap_rfc822_parse_headers - 從字串解析郵件標題
      55. imap_rfc822_write_address - 根據郵箱、主機和個人郵件,返回格式正確的電子郵件地址
      56. imap_savebody - 將特定的正文部分保存到文件中
      57. imap_scan - imap_listscan的別名
      58. imap_scanmailbox - imap_listscan的別名
      59. imap_search - 此函數返回與給定搜索條件匹配的郵件陣列
      60. imap_set_quota - 為給定郵箱設置配額
      61. imap_setacl - 設置給定郵箱的ACL(存取權控制清單)
      62. imap_setflag_full - 設置郵件標誌
      63. imap_sort - 獲取和排序郵件
      64. imap_status - 返回郵箱的狀態郵件
      65. imap_subscribe - 訂閱郵箱
      66. imap_thread - 返迴線程郵件樹
      67. imap_timeout - 設置或獲取imap超時
      68. imap_uid - 此函數返回給定郵件序列號的UID
      69. imap_undelete - 取消標記為已刪除的郵件
      70. imap_unsubscribe - 取消訂閱郵箱
      71. imap_utf7_decode - 解碼已修改的UTF-7編碼字串
      72. imap_utf7_encode - 將ISO-8859-1字串轉換為修改後的UTF-7文本
      73. imap_utf8 - 將MIME編碼的文本轉換為UTF-8
    8. 數學
      1. bindec(二進位字串):二進位轉十進位。如:bindec('00110')。
      2. bin2hex(ASCII字串):二進位轉十六進位。如:bin2hex('chengdu')。
      3. octdec(八進位字串):八進位轉十進位。如:boctdec('010')。
      4. decbin(整數):十進位轉二進位。如:decbin(50)。
      5. decoct(整數):十進位轉八進位。如:decoct(50)。
      6. dechex(整數):十進位轉十六進位。如:dechex(50)。只能處理無符號整數,負整數會以無符號來處理。
      7. hex2bin(十六進位字串):十六進位轉二進位。如:hex2bin('6368656e67206475')。
      8. hexdec(十六進位字串):十六進位轉十進位。如:hexdec('that')會忽略t,h,傳回整數10。
      9. base_convert(數值字串,2~36間的整數(輸入值進位制),2~36間的整數(傳回值進位制)):任意進位制轉換,傳回字串。
      10. deg2rad(數):角度轉徑度。
      11. sin(徑度):正弦。
      12. abs(數):取絕對值。
      13. ceil(數):進位。
      14. floor(數):捨去小數。
      15. round(數,小數位數):四捨五入。
      16. pi():圓周率。
      17. sqrt(數):開平方。
      18. pow(底,次方):求次方值,底,次方可為非整數。如果次方是分數,即涉及開方,則底必須為非負數,如-1開三方即不允許,會回應NAN(並非一個數值)。此非為數學上的定義,同樣的情形Excel就許可運算。但負數開偶次,會得出i,PHP和Excel皆不允許。
      19. exp(數):取自然對數為底的次方值。
      20. log(數,底):對數,如省略底即為自然對數。
      21. log10(數):以10為底的對數。
      22. mt_rand(最小整數值,最大整數值):傳回介於兩值間的一個整數亂數,不指定範圍,則從0到常數RAND_MAX間找一亂數。使用馬其賽特旋轉 (Mersenne Twister) 演算法,比 libc 計算速度至少快四倍。實測值和 rand() 函式速度差不多。
      23. mt_srand(整數種子):設定亂數種子seed。無傳回值。
      24. rand(最小整數值,最大整數值):傳回介於兩值間的一個整數亂數,不指定範圍,則從0到常數RAND_MAX間找一亂數。
      25. srand(整數種子):設定亂數種子seed。無傳回值。
    9. 變數
      1. empty(變數們):傳回(01)變數是否為空值。
      2. gettype(變數們):傳回(字串)變數型態。
      3. get_defined_vars():傳回(陣列)所有變數。
      4. intval(變數們[, int base]):傳回整數值。
      5. is_array(變數們):判斷是否為陣列。
      6. is_bool(變數們):判斷是否為布林值。
      7. is_double(變數們):判斷是否為倍浮點數。
      8. is_float(變數們):判斷是否為浮點數。
      9. is_int(變數們):判斷是否為整數。
      10. is_integer(變數們):判斷是否為整數。
      11. is_long(變數們):判斷是否為整數。
      12. is_null(變數們):判斷是否為空值。
      13. is_numeric(變數們):判斷是否為數字或數字的字串。
      14. is_object(變數們):判斷是否為物件。
      15. is_real(變數們):判斷是否為實數。
      16. is_resource(變數們):判斷是否為資源。
      17. is_string(變數們):判斷是否為字串。
      18. isset(變數們):測試是否為存在。
      19. print_r(函式們):列出敘述句之資訊。
      20. unset(變數們[, mixed var [, ...]]):刪除變數。
    10. 函數處理
      1. function_exists(string function_name):檢查函數是否已經定義過。
      2. get_defined_functions():傳回所有已定義過函數。
    11. 類別和物件
      1. call_user_method_array(方法,物件[, array paramarr]):以陣列參數呼叫指定的方法。
      2. call_user_method(方法,物件[, mixed paramarr [, mixed ...]]):在一個指定的物件上呼叫指定的方法。
      3. class_exists(類別);檢查類別是否已經定義。
      4. get_class(物件):傳回物件中的類別名稱。
      5. get_class_methods(類別):傳回類別中方法的名稱。
      6. get_class_vars(類別):傳回類別預設的屬性。
      7. get_declared_classes():傳回聲明的類別的名稱。
      8. get_object_vars(物件):傳回物件的屬性。
      9. get_parent_class(物件):傳回物件的父類別名稱。
      10. is_subclass_of(物件,子類別):判斷物件是否屬於類別的子類別,如果物件 obj是屬於 superclass的子類別時,此函式會傳回 true,否則傳回 false。
      11. method_exists(物件,方法):檢查類別的方法是否存在。
    12. URL
      1. base64_decode(編碼字串):以MIME base64解碼。見字串函式。
      2. base64_encode(字串):以MIME base64編碼。見字串函式。
      3. parse_url(url字串):見字串函式。
      4. urldecode(字串):傳回解碼後的url字串。
      5. urlencode(字串):傳回url編碼字串。
    13. 檔案系統(待充實)
      1. dirname(路徑檔名):傳回完整的目錄名稱。如dirname(__FILE__)。
      2. basename(路徑檔名):傳回路徑檔名最後一個「/」之後的名字。如basename(dirname(__FILE__))。
      3. pathinfo(路徑檔名,常數):依四種不同常數傳回不同字串,可用常數如下:
        • PATHINFO_DIRNAME:取得資料夾路徑
        • PATHINFO_BASENAME:取得整個檔名(主+副)
        • PATHINFO_FILENAME :取得主檔名
        • PATHINFO_EXTENSION:取得副檔名
        此函式遇多數的中文檔名、路徑名都沒問題,但對少數中文檔名、路徑名抓不到,如「菊」。所以還有以下幾種抓副檔名的方法,依執行速度排列如下:
        1. substr(strrchr($filename,'.'),1)
        2. substr($filename,strrpos($filename,'.')+1)
        3. preg_replace('/^.*\.([^.]+)$/D','$1',$filename)
        4. end(explode('.',$filename))
        5. $exts=split("[/\\.]",$filename);
          $n=count($exts)-1;
          $ext=$exts[$n];
      4. copy(來源檔名,目的檔名):複製檔案。copy完原檔案還是會在。
      5. chmod(檔名,權限):複製檔案。權限參數由 4 個數字組成:
        • 第一個數字永遠是 0
        • 第二個數字規定所有者的權限
        • 第三個數字規定所有者所屬群組成員的權限
        • 第四個數字規定其他所有人的權限
        可能的值(如需設置多個權限,請對下面的數字進行總計):1(執行權限)、2(寫權限)、4(讀權限)。
      6. is_uploaded_file(暫存檔名):檢查檔案是不是由 HTTP POST 上傳的暫存檔。
      7. move_uploaded_file(暫存檔名,目的檔名):安置上傳暫存檔到正式位置。在 4.0.3 以前的 PHP 中,常用 if(file_exists($_FILES['file']['tmp_name'])){copy($_FILES['file']['tmp_name'],目的檔名);}來處理上傳檔。但 $_FILES 可能被偽造,所以後來改用 is_uploaded_file() 加 move_uploaded_file() 來處理上傳檔。
      8. unlink(檔名[,context]):刪除檔案。context引數是PHP 5.0.0 添加的,相關說明請參考 CXLI. Stream Functions 。delete(檔名)為無用的函式,不能做事。
      9. rmdir(目錄名):刪除目錄。欲刪除的路徑必須是空的目錄,且權限必須要合乎要求。發生錯誤則傳回 0。
      10. file_exists(檔名):檔案是否存在。
      11. is_dir(路徑):路徑是否存在,該路徑存在且為一個目錄,返回 true ,否則返回 false 。
      12. is_file(檔名):辨別檔名是否為正規的檔案。
      13. is_link(檔名):辨別檔名是否為連結。
      14. fileatime(檔名):檔案最後存取的時間戳記。
      15. filemtime(檔名):檔案最後寫入異動的時間戳記。
      16. filectime(檔名):檔案最後權限異動的時間戳記。
      17. filegroup(檔名):檔案所屬群組的id。
      18. fileowner(檔名):檔案所有者的id。
      19. fileinode(檔名):檔案實際存放的節點位址。
      20. fileperms(檔名):檔案的權限。
      21. filesize(檔名):檔案的大小(bytes數)。
      22. filetype(檔名):傳回file、dir、link、block、char、fifo、unknown等7種可能的值。
      23. glob('模式',常數):傳回合模式條件的檔名陣列。樣板如:「'./temp/*.txt'」
        • GLOB_MARK:資料夾最後面加上斜線「/」
        • GLOB_NOSORT:保持 inode 原來的順序
        • GLOB_NOCHECK:若找不到匹配的項目,傳回原模式
        • GLOB_NOESCAPE:反斜不代表轉義
        • GLOB_BRACE:將 {a,b,c} 視為搜尋 'a', 'b', 或 'c',如「glob("/path/{*.gif,*.jpg,*.png}", GLOB_BRACE)」
        • GLOB_ONLYDIR:只列出資料夾路徑
        • GLOB_ERR:發生讀取錯誤時停止動作(像是無法讀取的資料夾),預設是「忽略錯誤」
        • 以上常數可以用管線 | 串起來,如「GLOB_ONLYDIR | GLOB_MARK」
      24. scandir(路徑):傳回路徑下的諸檔名組成之陣列,含「.」「..」。
      25. mkdir(路徑及目錄名,mode值,是否遞迴):建立目錄。mode預設值為0777。
      26. chdir(路徑及目錄名):變更PHP現在目錄到指定目錄。無法變更目錄時則傳回false,否則則傳回ture。
      27. dir(路徑及目錄名):製造一個物件,兩屬性,三方法。path屬性放輸入的路徑檔名,handle屬性放傳回的資源代碼。read()方法自資源代碼中取出一個檔案條目,close()方法繳還資源代碼,rewind()將指標調回目錄開始處。
        例如「$d=dir(".");while($entry=$d->read()){echo $entry."\n";}$d->close();」
      28. opendir(路徑及目錄名):開啟一個目錄處理流程,取回資源代碼。如不能打開目錄傳回 FALSE 並產生一個 PHP 錯誤訊息。可以在 opendir() 前面加上「@」符號來抑制錯誤訊息的輸出。
      29. readdir(資源代碼):從目錄傳回下一個檔案條目的檔案名稱,傳回時不依照任何特殊順序。
        例如 「$handle=opendir('.');while($file=readdir($handle)){echo $file."
        \n";}closedir($handle);」
      30. closedir(資源代碼):繳還資源代碼。
      31. rewinddir(資源代碼):重設資源代碼指示的目錄流到目錄的開始處。
      32. $陣列名=file("路徑檔名"):將檔內資料一行為一元素存入陣列。
      33. file_get_contents(路徑檔名,include_path,context,start,max_length):逐byte傳回檔案內容
        • include_path,可選。如果也想在 include_path 中搜尋檔案的話,將該參數設為 1
        • context,可選。是一套可以修改「資料流」行為的選項。若使用 null,則忽略。
          一個合法的context資源是由stream_context_create(指示陣列)函式所建立,指示陣列如:
          array( 'http'=>array('method'=>'GET','header'=>"Accept-language:en\r\n"."Cookie:foo=bar\r\n"))。
          請參考 php.net/manual/zh/context.php
        • start,可選。規定在檔案中開始讀取的位置。
        • max_length,可選。規定讀取的byte數。
        ➀本函數可安全用於二進制對象。
        ➁路徑檔名可以是 URL 網址,能叫回wiki頁供嵌入用,如:
         $content=file_get_contents('http://quality-learning.net/MediaWiki/index.php/首頁?action=render');
         $content=file_get_contents('https://zh.wikipedia.org/wiki/QR碼?action=render');
      34. file_put_contents(路徑檔名,data,mode,context):逐byte將內容送入檔案
        • 路徑檔名,必需。規定要寫入數據的檔案。如果檔案不存在,則創建一個新檔案。
        • data,可選。規定要寫入檔案的數據。可以是字符串、陣列或數據流。
        • mode,可選。可選。規定如何打開/寫入文件。可能的值:
          1. FILE_USE_INCLUDE_PATH
          2. FILE_APPEND
          3. LOCK_EX
        • context,可選。是一套可以修改「資料流」行為的選項。若使用 null,則忽略。
    14. PHP選項與資訊
      1. phpinfo():傳回當前 PHP 的全部相關訊息。要php.ini中關閉「disable_functions」(預設為空值),才出得來。而且「disable_functions」不能用ini_set()改設定。可用參數如下:
        名稱 數值 簡介
        INFO_GENERAL 1 一般資訊
        INFO_CREDITS 2 開發人員的資料
        INFO_CONFIGURATION 4 目前 PHP 命令的 local 和 master 值。
        INFO_MODULES 8 載入的模組和設定。
        INFO_ENVIRONMENT 16 環境變數的資料
        INFO_VARIABLES 32 顯示預定變數的資料
        INFO_LICENSE 64 PHP 的授權合約
        INFO_ALL -1 顯示全部資料,預設值
      2. ini_get_all([設定分組字串]):傳回各設定項目的global_value、local_value 、access (存取階層)。省略設定分組字串,傳回所有178項配置設定之值。設定分組字串例舉如下:
        • date:日期時間支援的相關設定,如時區、日光能源時間等。
        • exif:照片exif資訊支援的相關設定。
        • gd:繪圖相關設定。
        • iconv:轉碼相關設定。
        • ldap:LDAP相關設定。
        • mbstring:準確地分割多字元文字(multi-byte)的相關設定。
        • mime_magic:各類mime檔案偵側方法的相關設定。
        • mysql:mysql模組的相關設定。
        • mysqli:mysqli模組相關設定。
        • odbc:開放資料庫互連(Open Database Connectivity)相關設定。
        • pdo:資料庫訪問抽像層的相關設定。「資料庫訪問抽像層」,作用是統一各種資料庫的訪問介面,與mysql和mysqli的函數庫相比,PDO讓跨資料庫的使用更具有親和力;與ADODB和MDB2相比,PDO更高效。
        • session:連線會期的相關設定。
        • zlib:資料壓縮函式庫的相關設定。
      3. ini_get('設定項目'):傳回各設定項目之值。
      4. ini_set('設定項目','值'):改設定項目的值,在執行後生效,腳本結束時設置也失效。否則所有的設定項目都能被改。那些值能夠改設定,請查手冊中的列表。
        • display_error、error_reporting就能改,方便除錯;
        • max_execution_time能改延長程式執行時間,但如 php 在安全模式下執行,就不能用 ini_set 改此項目而只能在 php.ini 中才能改;網頁伺服器的其他超時設定,也可能會中斷PHP執行:Apache有一個Timeout指令,IIS有一個CGI超時函數,兩者的預設值為300秒。
        • ini_set('include_path',ini_get('include_path').':/your_include_dir:')可以擴充預設載入路徑。
      5. ini_restore('設定項目'):回復預設值。
    15. 雜項
      1. constant(常數名稱):傳回常數值。
      2. define(常數名稱,值[, int case_insensitive]):定義常數名稱。
      3. defined(常數名稱):檢查常數是否存在。
      4. $constants=get_defined_constants(true):傳回所有常數構成的陣列。其中:
        $constants['json']有所與json有關的常數,其中有九個常數是json解碼發生錯誤的錯誤代碼:
        JSON_ERROR_NONE => 0
        JSON_ERROR_DEPTH => 1
        JSON_ERROR_STATE_MISMATCH => 2
        JSON_ERROR_CTRL_CHAR => 3
        JSON_ERROR_SYNTAX => 4
        JSON_ERROR_UTF8 => 5
        JSON_ERROR_RECURSION => 6
        JSON_ERROR_INF_OR_NAN => 7
        JSON_ERROR_UNSUPPORTED_TYPE => 8
      5. sha1(字串):傳回sha1雜湊值,用於線上金流。
      6. die(訊息字串):輸出訊息並終止程式。
      7. exit(訊息字串):輸出訊息後終止目前程式。同die。
      8. eval(敘述式):將字串之中的變數值代入,字串要由雙引號包起來,同時在結尾處要有分號。
        範例:
          $string = '杯子';
          $name = '咖啡';
          $str = '這個 $string 中裝有 $name.<br>';
          echo '1.'.$str;                   // 顯示「1.這個 $string 中裝有 $name.」
          echo '2.'."$str";                 // 顯示「2.這個 $string 中裝有 $name.」
          eval('$str="$str";');
          echo '3.'.$str;                   // 顯示「3.這個 $string 中裝有 $name.」
          eval("\$str = \"$str\";");
          echo '4.'.$str;                   // 顯示「4.這個 杯子 中裝有 咖啡.」
          
      9. get_browser([string user_agent]):識別使用者瀏覽器。
      10. uniqid(前置字元):依據當時的毫秒以及指定的前置字串產生一個獨一無二的字串。參數 prefix 為前置的字串,最多可達 114 字元。
      11. serialize(各種資料):傳回字串,將資源以外的資料型別轉化為字符串化,以便傳輸、儲存。例如session就是使用此格式。
        • 整數:i:數字;
        • 浮點數:d:數字;
        • 字串:s:長度:"字串";。big5中文每字兩byte,utf8中文每字3byte。
        • 布林值:b:1;為真,b:0;為假。
        • 陣列:a:元素個數:{索引;值;索引;值;…}。整個陣列{}後無分號;但{}中諸元素後有分號;。
        • 物件:o:類別名長度:"類別名":屬性個數:{屬性名;屬性值;…}。物件字符串化,所有的方法均消失,只留下屬性值。那怎麼還原呢?運用同類別時,方法跨物件,但屬性不跨物件的原理。還原時先用類別做出新物件,此物件會含各種方法,將取回之前儲存的各屬性,即得回原物件。請看以下示範:
        • <?php
          // classa.inc:
          class a
          {
           var $one = 1;
           function show_one()
           {
            echo $this->one;
           }
          }
          // page1.php:
          include("classa.inc");
          $a = new a;
          $s = serialize($a);
          // 將 $s 存在某處使 page2.php 能夠找到
          $fp = fopen("store", "w");
          fputs($fp, $s);
          fclose($fp);
          // page2.php:
          // 為正常解字串化需要這一行
          include("classa.inc");
          $s = implode("", @file("store"));
          $a = unserialize($s);
          // 現在可以用 $a 物件的 show_one() 函式了
          $a->show_one();
          ?>
        • 在PHP5中當對物件字符串化時,會去找類別中的__sleep()方法並執行,且傳回一個包含必須字符串化的陣列,其元素即為要字符串化的屬性。同理unserialize(字符串)時,會先去找__wakeup()並執行。
    16. 錯誤處理及記錄
      1. error_log(錯誤訊息,message_type 0~3 [, string destination [, string [extra_headers]]):第二個參數 message_type 為整數值:0 表示送到作業系統的 log (UNIX 在 syslog、Windows NT 記錄到事件記錄);1 則使用 PHP 的 Mail() 函式,送訊息到某 E-Mail 處,第四個參數 extra_headers 亦會用到;2 則將錯誤訊息送到 TCP 埠,此時第三個參數 destination 表示目的地 IP 及 Port;3 則將訊息存到檔案 destination 中。
      2. error_reporting(int [錯誤碼]):指定PHP程式只需要回報的錯誤等級其他的一律忽略。參看常數一節,各種錯誤碼的含意。PHP4中預設值為E_ALL & ~E_NOTICE,即除注意以外的一切訊息均顯示,PHP3不支持位元操作,錯誤碼預設值為7。
      3. restore_error_handler():恢復先前的錯誤處理函數。
      4. set_error_handler(錯誤處理函式的函式名稱):指定使用者自定錯誤處理函數。此函式很重要,因為預設的錯誤處理函式會洩露出錯腳本的路徑、行數和原因。對駭客來說,路徑可是非常重要資訊。將PHP配置檔中的display_errors設置為Off是一種解決之道,自定錯誤處理函式,將原始的錯誤訊息過濾或重導向是另一種解決之道。
      5. trigger_error(錯誤訊息[, int error_type]):產生使用者自訂的錯誤、警告、注意訊息。可以與內建的錯誤處理器一同使用,也可以與由 set_error_handler() 函數創建的使用者自定義函數使用。
      6. user_error(錯誤訊息[, int error_type]):產生使用者等級的錯誤、警告、注意訊息。
    17. 繪圖
      1. header('Content-type:image/png或jpeg或gif'); 送出http header,通知以下輸出的圖。
      2. imagecreate(寬點數,高點數):開圖,傳回圖代碼。左上為原點。
      3. imagepng(圖代碼[,檔名]):送出png圖到瀏覽器或是檔案。
      4. imagegif(圖代碼[,檔名]):送出gif圖到瀏覽器或是檔案。
      5. imagejpeg(圖代碼[,檔名]):送出jpg圖到瀏覽器或是檔案。
      6. imagedestroy(圖代碼):還回 ImageCreate() 所產生圖代碼,省略也可不會怎麼樣。
      7. imagecolorallocate(圖代碼,紅值,綠值,藍值):配一色,傳回色代碼。
      8. imagecolortransparent(圖代碼,色代碼):將顏色轉為透明背景色,並傳回新的色代碼。
      9. imagestring(圖代碼,字型代碼,x座標,y座標,字串,色代碼):畫一水平字串。
      10. imagestringup(圖代碼,字型代碼,x座標,y座標,字串,色代碼):畫一垂直字串。
      11. imagettftext(圖代碼,字大小之像素值,從水平算起逆時鐘整數角度採360度制,起點x,起點y,色代碼,字型檔,輸出字串):用ttf輸出字串到圖中,常用於中文。
        對red hat的linux,楷書在/usr/share/fonts/zh_TW/TrueType/bkai00mp.ttf,細明體在/usr/share/fonts/zh_TW/TrueType/bsmi00lp.ttf。
      12. imagesetpixel(圖代碼,x座標,y座標,色代碼):畫點。
      13. imageline(圖代碼,起點x,起點y,終點x,終點y,色代碼):畫直線。
      14. imagedashedline(圖代碼,起點x,起點y,終點x,終點y,色代碼):畫虛線。
      15. imageellipse(圖代碼,圓心x,圓心y,水平軸長,垂直軸長,色代碼):畫橢圓。
      16. imagearc(圖代碼,圓心x,圓心y,水平軸長,垂直軸長,起始角度,結束角度,色代碼):畫橢圓弧,角度是360度制,以右方水平為0度,順時鐘計算角度。
      17. imagefilledarc(圖代碼,圓心x,圓心y,水平軸長,垂直軸長,起始角度,結束角度,色代碼,樣式常數):橢圓弧內部著色,角度是360度制,以右方水平為0度,順時鐘計算角度。
        • 預設:畫弧,內部填滿。
        • 常數IMG_ARC_PIE:中心至始、終點連線,及弧。
        • 常數IMG_ARC_CHORD:將以弦代弧。和IMG_ARC_PIE互斥,兩者皆用IMG_ARC_CHORD生效。
        • 常數IMG_ARC_NOFILL:僅弧或僅弦。
        • 常數IMG_ARC_EDGED:附屬於IMG_ARC_NOFILL,畫出起始和結束點與中心點之連線。「IMG_ARC_NOFILL|IMG_ARC_EDGED」畫出餅狀圖輪廓。
      18. imagerectangle(圖代碼,角x,角y,對角x,對角y,色代碼):畫矩形。
      19. imagefilledrectangle(圖代碼,角x,角y,對角x,對角y,色代碼):矩形內部著色。
      20. imagepolygon(圖代碼,頂角座標陣列,頂角數,色代碼):畫多邊形,可能開口,可能封閉,封閉時首尾頂角座標相同。
      21. imagefilledpolygon(圖代碼,頂角座標陣列,頂角數,色代碼):多邊形著色。
      22. imagefill(圖代碼,x座標,y座標,色代碼):將該點區域著色。
      23. imagefilltoborder(圖代碼,x座標,y座標,邊界色代碼,著色代碼):在x,y座標點周圍,在邊界色的包圍範圍內,著上指定色。
      24. imageloadfont(字型檔名):載入使用者自訂的字型檔,其0-3bytes為檔案中字元的數目;4-7bytes為字型的啟始 ASCII 字元,例如從 ASCII 32 的空白開始;8-11bytes為字元的寬度,12-15bytes為字元的高度;16byte以後為各字元的位元值,也就是點陣的內容。
      25. imagepsloadfont(PS字型檔名):載入PS字型檔,傳回字型碼。
      26. imagepsfreefont(字型碼):還回字型碼及記憶空間。
      27. imagepstext(圖代碼,字串,字型代碼,字大小之像素值,前景色碼,背景色碼,左下角x,左下角y,文字間隔,單字間的緊密度,浮點數之角度,邊緣鋸齒狀修正等級範圍為4至16):畫PS字到圖中,傳回一維陣列四值,左下角座標及右上角座標。
      28. imagecreatefromjpeg(來源圖)、imagecreatefrompng(來源圖)、imagecreatefromgif(來源圖)、imagecreatefromstring(file_get_contents(來源圖)),由檔案或 URL 創建一張新圖。以下程式碼等於 Red_square.png 這張圖:
        $im=imagecreatefromstring(file_get_contents('Red_square.png'));
        header('Content-Type:image/png');
        imagepng($im);
        ※imagecreatefrom後會可以是jpeg或png或gif或string
      29. imagecopyresized(目的圖代碼,來源圖代碼,目的圖開始x座標,目的圖開始y座標,來源圖開始x座標,來源圖開始y座標,目的圖寬度,目的圖高度,來源圖寬度,來源圖高度):製作縮圖。程式碼如下:
        $src=imagecreatefromjpeg(來源圖);
        $src_w=imagesx($src);
        $src_h=imagesy($src);
        $thumb_w=300;
        $thumb_h=intval($src_h/$src_w*300);
        $thumb=imagecreatetruecolor($thumb_w,$thumb_h);
        imagecopyresized($thumb,$src,0,0,0,0,$thumb_w,$thumb_h,$src_w,$src_h);
        imagejpeg($thumb,目的圖路徑);
    18. HTTP
      1. header(字串):送出http header。
      2. headers_sent():判斷標頭是否已送出。
      3. setcookie('變數名',變數值,存活到何時,有權存取之路徑,有權存取之網域,是否保密):由HTTP存在客戶端的變數,經由標頭傳送,在建立cookie還抓不到要換頁才抓得到。
    19. FTP
      1. FTP上傳期間,如果是覆寫遠端的舊檔,上傳前會先刪掉遠端的舊檔,傳送完成或傳送中斷,遠端的檔案才會產生。所以上傳期間,遠端的目的檔案是不能讀寫的,因為不存在。很簡單的檔案讀寫鎖定機制。
      2. ftp_connect(string host [, int port]):開啟FTP連結。
      3. ftp_login(int ftp_stream, string username, string password):登入FTP連結。
      4. ftp_pwd(int ftp_stream):傳回目前的目錄名稱。
      5. ftp_cdup(int ftp_stream):回到父目錄。
      6. ftp_chdir(int ftp_stream,目錄):切換到指定的目錄。
      7. ftp_mkdir(int ftp_stream,目錄):建立新目錄。
      8. ftp_rmdir(int ftp_stream,目錄):移除目錄。
      9. ftp_nlist(int ftp_stream,目錄):傳回給予的目錄中檔案的列表。
      10. ftp_rawlist(int ftp_stream,目錄):傳回給予的目錄中檔案的詳細列表。
      11. ftp_systype(int ftp_stream):傳回遠端FTP伺服器的系統型態identifier
      12. ftp_pasv(int ftp_stream, int pasv):開啟或關閉被動模式。
      13. ftp_get(int ftp_stream, string local_file, string remote_file, int mode):從FTP伺服器下載檔案。mode,0是文字檔,1是二元檔。
      14. ftp_fget(int ftp_stream, int fp, string remote_file, int mode):從FTP伺服器下載檔案並且儲存到開啟的檔案。
      15. ftp_put(int ftp_stream, string remote_file, string local_file, int mode):上傳檔案到FTP伺服器。
      16. ftp_fput(int ftp_stream, string remote_file, int fp, int mode):從開啟的檔案上傳到FTP伺服器。
      17. ftp_size(int ftp_stream, string remote_file):傳回檔案的大小。
      18. ftp_mdtm(int ftp_stream, string remote_file):傳回檔案的最後修改時間。
      19. ftp_rename(int ftp_stream, string from, string to):將FTP伺服器上的檔案重新命名。
      20. ftp_delete(int ftp_stream, string path):刪除FTP伺服器上的檔案。
      21. ftp_site(int ftp_stream, string cmd):送出site命令給伺服器。
      22. ftp_quit(int ftp_stream):結束FTP連結。
    20. 安全執行外部命令
      1. EscaPeShellCmd(命令字串):將命令字串中可能騙過Shell而去執行另外一個命令的字元的「轉義」,如分號;,重定向>和從文件讀入<。
      2. EscaPeShellArg(命令參數):給定的字串兩邊加上單引號,並把字串中的單引號轉義,這樣這個字串就可以安全地作為命令的參數。
      3. `外部命令`:代表命令執行的結果。如:「echo "<Pre>";echo `ls -l`;echo "</Pre>";」。
      4. system(外部命令[,放回傳狀態碼的變數名]):執行外部命令並輸出返回結果。system()等函數要等命令的輸出結果後才返回,這肯定會引起PHP腳本的超時。解決的辦法是把命令的輸出用「>」重定向到另外一個檔或流中。
      5. exec(外部命令[,傳回結果陣列[,狀態碼的變數名]]):執行外部命令不輸出返回結果,而將返回結果的最後一行放進結果陣列的最後一個元素。回傳陣列可能放前個執行命令的回傳結果。
      6. Passthru(外部命令[,狀態碼的變數名]):執行外部命令不返回結果,而把結果原樣地直接輸出到標準輸出設備上。適合處理圖片流。如:
        header("Content-tyPe: image/gif");
        Passthru(".PPmtogif hunte.PPm");
      7. pOpen(外部命令,'w'或'r')。上面的方法只能簡單地執行外部命令,卻不能與外部命令互動。pOpen則打開一個管道來執行給定的外部命令,返回一個檔案控制碼,後續就可以持續對檔案控制碼讀和寫了,其操作宛如對待檔案。 與外部命令持續互動的例子:
        $fP=@pOpen(外部命令,'w');
        @fPuts($fP,用字串回應外部程式);
        @Pclose($fP);
      8. 安全模式下,只有在特定目錄中的外部程式才可以被執行,對其他程式的調用將被拒絕。這個目錄可以在PhP.ini 檔中用safe_mode_exec_dir指定。

    捌、設定

    一、php.ini中的重要項目

    (一)與檔案上傳相關(以群暉DS218+為例)

    1. memory_limit = 128M ,一個指令碼所能夠申請到的最大記憶體。設為 -1:不需要任何記憶體上的限制。
      在執行縮圖函式時,如果母圖太大會產生「Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate xxxxx bytes)」此時可以去調 php.ini 中的設定;也可以在整個程式的最前面加「ini_set('memory_limit','oooM');」。
    2. file_uploads = 1,即On
    3. upload_max_filesize = 32M ,上傳檔案的最大大小。
    4. max_file_uploads = 60 ,最多一次上傳檔案個數。
    5. max_execution_time = 240 ,每個腳本最長執行時間,單位秒。
    6. max_input_time =60 ,每個腳本花在解析請求數據上的最長時間,單位秒。
    7. post_max_size = 32M ,POST數據所允許的最大大小。要上傳大檔案,該值必須大於 upload_max_filesize。
    其他輔助設定:
    1. 系統常數:PHP_VERSION
    2. my.ini:max_allowed_packet = xxM ,BLOB進行二進制檔案儲存的上限。
    3. .htaccess 或 httpd.conf:LimitRequestBody ,限制使用者送出的 HTTP 請求內容

    (二)其他設定

    1. magic_quotes_gpc = Off
    2. default_socket_timeout = 60
    3. mysql.connect_timeout = 60
    4. error_reporting = E_ALL
    5. display_errors = On
    6. log_errors = On
    7. log_errors_max_len = 1024

    二、httpd.conf中的相關項目

    1. Timeout 120
    2. AddDefaultCharset UTF-8
    3. ErrorLog logs/error_log
    4. Alias /error/ "/var/www/error/"

    三、PHP 5.3 以上的設定改變

    (一)移除 magic_quotes_gpc

    1. get_magic_quotes_gpc() 函式隨之停用
    2. 但可以在 php.ini 中設定 filter.default = magic_quotes 取代 magic_quotes_gpc=on ,對所有站台都生效。
    3. 如果是有的站台需要,有的站台不需要,可以在該站台的 apache <VirtualHost> 設定內,加上「php_value filter.default magic_quotes」設定值,就會只作用在這個站台而已。
    4. 也可以在 apache 的 <Directory> 或 <Files> 來包住「php_value filter.default magic_quotes」,只讓特定目錄裡的 php 或特定 php 程式會有 magic_quotes 的效果。
    5. 也可以在該目錄的 .htaccess 中加「php_value filter.default magic_quotes」

    玖、SAPI(Server Application Programming Interface,服務端應用編程端口)

    一、版本、檔案和基本區別

    CGI(Common Gateway Interface);CLI(命令列執行,Command Line Interface)

    Linux windows
    PHP4.3 /usr/bin/php(CGI) php.exe cli/php.exe
    PHP5 /usr/bin/php(CLI) php-cgi.exe php.exe php-win.exe(不輸出)
    PHP 7.3 的 CLI 在 /usr/local/bin/php73

    查CGI或CLI的方法:

    1. 命令列php -v
    2. 命令列模式查常數PHP_SAPI得CLI或CGI,透過瀏覽器查得「apache2handler」。
    3. 命令列模式由php_sapi_name()傳回CLI或CGI,透過瀏覽器傳回「apache2handler」。

    CLI和CGI的基本區別:

    • CLI不能產生HTTP headers,所以沒有-q參數,但用了也不會錯,以便和舊的CGI腳本相容。
    • CLI不會把工作目錄改為腳本的當前目錄,所以沒有-C參數。但用了也不會錯,以便和CGI腳本相容。
      例如在腳本中開一個檔做寫入動作時,因為執行者可能在很多不同的路徑來執行這一個腳本,因此最好用絕對路徑來表達欲寫入之檔案的所在位置。但腳本檔中如有 includ 指令並使用相對路徑時,則是指從使用 include 的腳本檔出發的相對路徑。
    • CLI出錯時輸出純文本的錯誤資訊(非 HTML 格式)。CLI SAPI 強制更改了 php.ini 中的某些設置,因為這些設置在shell環境下是沒有意義的。以下被更改的 php.ini 設置選項:
      1. html_errors:無意義的 HTML 標記符會使得出錯資訊很凌亂,所以在shell下閱讀報錯資訊是十分困難的。因此將該選項的預設值改為 FALSE。
      2. implicit_flush:在命令行模式下,所有來自 print() 和 echo() 的輸出將被立即寫到輸出端,而不作任何地緩衝操作。如果您希望延緩或控制標準輸出,您仍然可以使用 output buffering 設置項。
      3. max_execution_time:鑒於在shell環境下使用 PHP 的無窮的可能性,最大運行時間被設置為了無限長。為 WEB 開發的應用程式可能只需運行幾秒鐘時間,而shell應用程式的運行時間可能會長的多。
      4. register_argc_argv:由於該設置為 TRUE,您將總是可以在 CLI SAPI 中取得到 argc(傳送給應用程式參數的個數) 和 argv(包含有實際參數的陣列)。對於 PHP 4.3.0,在使用 CLI SAPI 時,PHP 變數 $argc 和 $argv 已被註冊並且設定了對應的值。而在這之前的版本,這兩個變數在 CGI 或者 模組 版本中的建立依賴於將 PHP 的設置選項 register_globals 設為 on。除了版本和 register_globals 設定以外,您可以隨時通過調用 $_SERVER 或者 $HTTP_SERVER_VARS來取得它們。例如︰$_SERVER['argv']
    • 這些設定無法在 php.ini 或任何指定的其它文件中被初始化為其它值。這些預設值是在所有配置文件(如php.ini)被解析後才改變。不過,它們的值可以在程式運行的過程中被改變(儘管對於該運行過程來說,這些設置項是沒有意義的)。

    二、輸入/輸出流

    (一)PHP的輸入/輸出流:

    1. php://stdin
    2. php://stdout
    3. php://stderr,預設送入標準輸出。
    4. php://output
    5. php://input
    6. php://filter (PHP 5.0.0以後可用)
    7. php://memory (PHP 5.1.0以後可用)
    8. php://temp (PHP 5.1.0以後可用)

    範例:「"$stdout=fopen('php://stdout','w');fwrite($stdout,'Hello');fclose($stdout);"」會將Hello送往標準輸出裝置,瀏覽器看不到。
    「$stdin=fopen('php://stdin','r');echo 'Please Enter your Name :';$mystr=fgets($stdin,100);echo 'Your Name Is :';echo $mystr;fclose($stdin);」
    「$stderr=fopen('php://stderr','w');fwrite($stderr,'There was an Error');fclose($stderr);」

    (二)STDIN、STDOUT、STDERR:

    1. 當shell用「php 腳本檔」執行時,PHP自動定義三常數STDIN、STDOUT、STDERR,代表標準輸入、標準輸出、標準錯誤裝置的handle。以下範例會和使用者互動:
      <?php
      fwrite(STDOUT, "Enter your name: ");
      $name = trim(fgets(STDIN));
      fwrite(STDOUT, "Hello, $name!");
      ?>
    2. 當shell用「php -r PHP程式碼」時,PHP程式碼中STDIN、STDOUT、STDERR當成已定義的常數。
    3. 當用瀏覽器透過網頁伺服器請求腳本檔時,PHP則將STDIN、STDOUT、STDERR當成未定義的常數。
    4. 其實STDIN就是fopen 'php://stdin'所得的handle,STDOUT就是fopen 'php://stdout'所得的handle,STDERR就是fopen 'php://stderr'所得的handle。

    (三)$argv、$argc:

    1. $argv變數,它將命令行中傳遞給PHP腳本的參數保存為單獨的陣列。如果是腳本檔,註標0的元素放腳本檔的檔名。
    2. $argc變數,放上述陣列的元素個數。

    三、選項及參數

    (一)CGI程式在命令列模式執行

    1. 用法php [-q] [-h] [-s] [-v] [-i] [-f <腳本檔>]
      php <腳本檔> [-- 腳本檔參數]
    2. 諸php選項解釋如下:
        -a               互動式執行。php5良好;php4,在windows中不能用,在linux中。
        -C              *不改變目錄至腳本檔目錄
        -c | 指定一個放置 php.ini 文件的目錄,或者直接指定一個自定義的 INI 文件,其文件名可以不是 php.ini。
        -n               不用 php.ini
        -d 變數[=值]     自行設置 php.ini 中變數的值
        -e               為 除錯器/過濾器 生成擴展資訊。
        -f         解譯 。-f可加可不加。預設使用安靜模式。
        -h               命令行參數的列表
        -i               調用 phpinfo() 函數。
        -l               語法檢查。不能和 -r 並用。該參數將無法檢查致命錯誤(如未定義函數),如要檢測致命錯誤,請使用 -f 參數。如果成功,則向標準輸出寫入   No  syntax  errors  detected  in    字串,並且shell返回值為 0。如果失敗,則  Errors  parsing    以及內部解析器錯誤資訊會一起被寫入到標準輸出,同時shell返回值將別設置為  255。
        -m               顯示已編譯之 PHP 及 Zend 模組。
        -q              *安靜模式:抑制輸出 HTTP Header。
        -s               顯示有語法高亮色彩的 HTML 原始檔,包在  [...]  之間,並將結果寫到標準輸出,不包含任何的  HTML  頭。
        -v               將 PHP、PHP SAPI 及 Zend 的版本寫到標準輸出。
        -w               顯示除去了註釋和空格的 HTML 原始檔,不可以和-r並用。
        -z         加載 Zend 擴展庫。如果僅給定一個文件名,PHP 將試圖從您系統擴展庫的默認路徑(在 Linux 系統下,該路徑通常由 /etc/ld.so.conf 指定) 加載該擴展庫。如果您用一個絕對路徑指定文件名,則系統的擴展庫默認路徑將不會被使用。如果用相對路徑指定的文件名,PHP 則僅試圖加載相對於當前目錄的擴展庫。
    3. 設定腳本檔參數:
      #  以下命令將不會運行  PHP  代碼,而只顯示  PHP  命令行模式的使用說明︰
      $  php  -r  "var_dump($argv);"  -h
      Usage:  php  [options]  [-f]    [args...]
      [...]
      #  以下命令將會把「-h」參數傳送給腳本程式,PHP不會顯示命令行模式的使用說明︰
      $  php  -r  "var_dump($argv);"  --  -h
      array(2)  {
      	[0]=>
      	string(1)  "-"
      	[1]=>
      	string(2)  "-h"
      }

    (二)CGI程式在命令列模式執行

    1. 最好跳到php根目錄去執行.\CLI\php這樣各項函式庫、套件才能順利找到。
    2. 用法php [諸選項] [-f <腳本檔>] [腳本檔參數]
      php [諸選項] -r "php程式碼" [腳本參數]:注意php程式碼在windows中必須用"包起來,不能用'包起來。在Linux中用"和'包程式碼都可以,但如用"其中的$變數會以變數值代入,所以要用\$;
      php [諸選項] [-- 腳本檔參數]
    3. 選項大多數和CGI一樣
      但是沒有 -C 和 -q多了
      -r :直接執行php命令不需要腳本檔標籤「
      -- 諸腳本參數:參數送到腳本檔。當第一次參數開始或是指令來自標準輸入(stdin)

    四、和Linux的shell結合

    檔案與資料夾處理權限:
    1. PHP的執行權限是由HTTP daemon(通常是Apache)來決定的,所以多半只有Apache執行者的權限。權限不夠就無法上傳檔案或是利用mkdir()建目錄。
    2. SELinux會因為安全性的設定,而禁止httpd來控制檔案或目錄。所以,不管你PHP怎麼調整,目錄權限怎麼設定,通通都不會有作用的。只有「Disable Selinux protection for httpd daemon」才能解決問題。
    3. shell腳本:第一行以 #!/usr/bin/php 開頭,在其後加上以 PHP 開始和結尾標記符包含的正常的 PHP 代碼,然後為該腳本檔設置正確的運行屬性。
      #!/usr/bin/php
      <?php
      	    var_dump($argv);
      ?>
    4. 用shell指令「exec /usr/bin/php -C -d include_path=/usr/share/pear -d output_buffering=1 腳本檔 "$@"」來執行,執行完控制權交回shell。
    5. 腳本檔中可以用php語法再執行shell指令。

    五、以WinBinder寫桌面程式

    1. 只支援windows不能支援Linux。
    2. 只做到2006.1.19的0.46.0版。
    3. 正式版只支援到PHP5.1,PHP5.2要下載新的php_winbinder.dll,並且取消winbinder.php中的版本檢查。
    4. 要在ext中加php_winbinder.dll、freeimage.dll,另外四個php_pdo.dll、php_mysql.dll、php_pdo_sqlite.dll、php_sqlite.dll用PHP5原來的即可。
    5. 要用調過的php.ini(待研究),其中含
      「extension_dir = "./ext/"
        extension=php_winbinder.dll」
    6. 要改windows的登錄:
      [HKEY_CLASSES_ROOT\.phpw]
      @="WinBinder script"
      [HKEY_CLASSES_ROOT\WinBinder script\DefaultIcon]
      @="J:\\Copy\\php5\\phpcode\\resources\\wb.ico"
      [HKEY_CLASSES_ROOT\WinBinder script\Shell\Open\Command]
      @="\"J:\\Copy\\php5\\php-win.exe\" \"%1\""
    7. phpw檔和includ資料夾相對位置要對。
    8. minimal.phpw說明:
      // 載入 WinBinder 的函式庫,它幫我們預先了許多建立視窗元件的函式。
      include "../include/winbinder.php";
      // 用 wb_create_window 建立了一個 480x320 的視窗,其標題為「 Hello Word! 」。
      wb_create_window(NULL, PopupWindow, "Hello world!", 480, 320);
      // 用 wb_main_loop 來讓程式等待使用者的操作。
      wb_main_loop();
    9. 可以用php.exe、php-cgi.exe、php-win.exe執行,用php.exe、php-cgi.exe會開cmd視窗,php-cgi.exe還會在視窗中送出http head,用php-win.exe不開cmd視窗。
    10. 手冊在 英文 http://winbinder.org/manual/index.html
    11. 也可以下載安裝檔,直接裝。其中server要選NCHC(Taiwan)
    12. 參考http://timteam.org/?TIM=FORUM&FORUM=84、http://timteam.org/?TIM=FORUM&FORUM=84&ShowDocument=13400、http://blog.roodo.com/jaceju/archives/983477.html(介紹PPForm)

    六、以PHP-GTK寫桌面程式

    1. 參考http://blog.roodo.com/rocksaying/archives/3400303.html、http://bbs.phpres.com/thread-6299-1-1.html、
    2. http://gtk.php.net/、http://translate.google.com.tw/translate?hl=zh-TW&sl=en&u=http://gtk.php.net/&sa=X&oi=translate&resnum=1&ct=result&prev=/search%3Fq%3Dphp-gtk%26complete%3D1%26hl%3Dzh-TW%26lr%3D%26sa%3DG

    七、以PPForm寫桌面程式

    1. 參考http://blog.roodo.com/rocksaying/archives/3400303.html、http://bbs.phpres.com/thread-6299-1-1.html、
    2. http://gtk.php.net/、http://translate.google.com.tw/translate?hl=zh-TW&sl=en&u=http://gtk.php.net/&sa=X&oi=translate&resnum=1&ct=result&prev=/search%3Fq%3Dphp-gtk%26complete%3D1%26hl%3Dzh-TW%26lr%3D%26sa%3DG

    拾、PEAR(PHP Extension and Application Repository,PHP擴充與應用程式庫)

    以CentOS為例。

    一、諸程式庫:

    1. 在/usr/share/pear之下,通常一套件為一支php或一個資料夾。
    2. 如能改 php.ini 可將 pear 的絕對路徑加到 php.ini 設定檔中「include_path = ".:/usr/share/pear:"」。諸路徑在UNIX中用:間開,在windows用;間開。
    3. 如不能改 php.ini ,直接在php程式中加「ini_set('include_path',ini_get('include_path').'/var/www/vhosts/某DN/httpdocs/PEAR:');」指向上傳的PEAR資料夾。
    4. chown -Rf 擁有者:群組 /usr/share/pear # 將 pear 資料夾及其子資料夾(-R)的擁有者及群組改成適應Apache讀寫的情形。
    5. 在PHP腳本檔中直接載入即可,如「require_once "DB.php";」

    二、套件管理程式

    1. shell的腳本檔為/usr/bin/pear,屬性755,內容為:
      exec /usr/bin/php -C -d include_path=/usr/share/pear -d output_buffering=1 /usr/share/pear/pearcmd.php "$@" 再將參數傳給pearcmd.php
    2. 較新版的/usr/bin/pear將路徑改為變數,先自環境變數中查找,是很好的範例。

    三、套件管理指令:

    1. pear list:查看 pear 已安裝的套件版本。
    2. pear remote-list:目前pear網站上所有可取得pear程式庫列表
    3. pear list-upgrades:列出可以升級的套件
    4. pear install 套件名:從網路下載套件並安裝。
    5. pear download 套件名、pear download-all:下載套件但不安裝。
    6. pear install filename.tgz:安裝已下載的套件。
    7. pear upgrade 套件名、pear upgrade filename.tgz、pear upgrade-all:更新套件。
    8. pear uninstall 套件名:移除套件。
    9. pear help:查看 pear 指令

    四、套件說明

    (一)DB.php

    在DB.php中放入口靜態的公用方法,在DB/common.php放抽象層,在DB/mysql.php中放實體層
    名詞「資料來源名稱」(Database Source Name):資料庫種類://帳號:密碼@機器/選用資料庫。例如:mysql://john:pass@localhost/my_db。

    DB類別諸方法
    1. factory(型):建DB物件指令資料庫類別,但不連上資料庫。
    2. connect(DSN):建DB物件並連上資料庫。
    3. apiVersion():傳回版本。
    4. isError(傳回值):檢查是否有錯。
    5. isConnection(傳回值):檢查是已連上資料庫。
    6. isManip(查詢句):檢查查詢句是否為資料操作指令(如INSERT,UPDATE,DELETE…)或資料定義指令(CREATE,DROP,ALTER,GRANT…),傳回真假。
    7. errorMessage(傳回值):由錯誤碼傳回錯誤訊息。
    8. parsedsn(DSN):解析DSN並傳回陣列。
    9. getdsnstring(DSN,是否隱藏密碼):將DSN陣列或字串,轉換成DSN字串,並依指示處理密碼段。
    DB_result類別諸方法
    1. db_result(DB物件,結果id,結果選項):實體化。不回傳。
    2. setOption(鍵,值):設定結果選項limit_from或limit_count之值。不回傳。
    3. fetchRow(模式,筆數):以物件或陣列傳回結果數據。
    4. fetchInto(陣列,模式,筆數):將若干筆數據放進指定陣列。
    5. numCols():傳回欄數。
    6. numRows():傳回筆數。
    7. nextresult():傳回下一個結果。當批次執行多個查詢句時。
    8. free():釋放結果資源。
    9. tableInfo(模式):
    10. getQuery():傳回查詢句。
    11. getRowCounter():傳回現在正在處理那一筆。
    DB_row類別只有一方法:DB_row(陣列):參考代表一筆數據的陣列生成一物件並回傳,諸欄名轉為屬性名。
    DB_Error類別繼承PEAR類別後加一方法:DB_Error(錯誤碼,模式,程度,除錯訊息):不回傳。
    抽象層DB_common類別繼承PEAR類別後加以下方法:
    1. db_common():叫「$this->PEAR('DB_Error');」,不回傳。
    2. __sleep():當serialize()時,傳回一組該字符串化的屬性。
    3. __wakeup():unserialize()時,重新連線。
    4. __toString():PHP5時自動轉換,傳回PEAR DB的描述。
    5. toString():傳回__toString()的傳回結果id。
    6. quoteString(字串):安全處理查詢句中的單引號並回傳。使用quote()。
    7. quote(字串):安全處理null及單引號並回傳。
    8. quoteIdentifier(字串):將字串內的「"」換成「""」並在字串前後均加「"」。
    9. quoteSmart(字串):安全處理查詢句並回傳。
    10. quoteBoolean(布林值):傳回0,1代表布林值。
    11. quoteFloat(浮點數):將浮串數字串化。
    12. escapeSimple(字串):處理其中的單引號加上escape
    13. provides(索引):依索引傳回實體層的特徵(features[索引],索引有limit、new_link、numrows、pconnect、prepare、ssl、transactions)。
    14. setFetchMode(模式,類別):設定查詢結果id的萃取模式,分註標索引模式、字串索引模式、物件模式。
    15. setOption(選項,值):設定 PEAR DB 運行間的選項,可適用多種資料庫。
    16. getOption(選項):取選項值。
    17. prepare(查詢句):處理查詢句中的?&!再傳回。
    18. autoPrepare(表名,欄名陣列,插入或更新,條件):自動產生插入或更新的查詢句。使用buildManipSQL()。
    19. autoExecute(表名,欄名陣列,插入或更新,條件):自動產生插入或更新的查詢句,並執行且傳回結果id。使用autoPrepare()。
    20. buildManipSQL(表名,欄名陣列,插入或更新,條件):自動產生插入或更新的查詢句。
    21. execute(敘述,數據):導入數據並執行executeEmulateQuery()所生的查詢句。傳回:如select執行成功傳回DB_result物件;DB_OK或DB_Error物件。
    22. executeEmulateQuery(敘述,數據):如DBMS不支援時,也能產生查詢句。
    23. executeMultiple(敘述,陣列):多重執行,將陣列中的值一一代入敘述執行,使用相同的敘述handle。成功傳回DB_OK,失敗傳回DB_Error物件。
    24. freePrepared(敘述句所生的資源id,是否一併釋放PHP資源):釋放Prepared所生的資源組合。
    25. modifyQuery(查詢句):預備為不同的DBMS調整查詢句,尚未寫。
    26. modifyLimitQuery(查詢句,起始筆,幾筆):預備加limit子句,尚未寫。
    27. query(查詢句,數據陣列):先prepare()再execute()。
    28. limitQuery(查詢句,起始筆,幾筆,數據陣列):先query(查詢句,數據陣列),再設結果id物件中的limit_from屬性和limit_count屬性。
    29. getOne(查詢句,數據陣列):取回結果id的第一筆第一欄欄值。
    30. getrow(查詢句,數據陣列,結果id萃取模式):取回第一筆。
    31. getCol(查詢句,第幾欄,數據陣列):取回結果id的第幾欄欄值,並做成註標索引陣列。
    32. getAssoc(查詢句,是否強迫化為陣列,數據陣列,結果id萃取模式,是否分群):將查詢結果id化為陣列,首欄之欄值為索引。
    33. getAll(查詢句,數據陣列,結果id萃取模式):取回所有的筆。
    34. autoCommit(開關):未支援。
    35. commit():未支援。
    36. rollback():未支援。
    37. numRows(結果id):未支援。
    38. affectedRows():未支援。
    39. getSequenceName(序列名):將序列名前面換成_,後面加_seq,成為序列表名。
    40. nextId(序列):未支援。
    41. createSequence(序列):未支援。
    42. dropSequence(序列):未支援。
    43. raiseError(錯誤編碼,錯誤模式,錯誤程度或回復方法,使用者除錯資訊,DBMS原生錯誤碼及描述):依編碼傳回錯誤物件。
    44. errorNative():未支援。
    45. errorCode(DBMS送回的錯誤碼):將DBMS送回的錯誤碼,依實體層的errorcode_map陣列轉換成抽象層錯誤碼。因各家DBMS錯誤編碼不盡相同,所以翻譯到抽象層使其一致。
    46. errorMessage(錯誤碼):傳回對應的訊息。
    47. tableInfo(結果id):未支援。
    48. getTables():即getListOf('tables')
    49. getListOf(選項):未支援,取回getSpecialQuery()的列表
    50. getSpecialQuery(選項):未支援。
    51. nextQueryIsManip(真假):強迫設$this->_next_query_manip的真假。
    52. _checkManip(查詢句):_next_query_manip或查詢句有一為資料操作指令,則設$this->_last_query_manip為真,否則為假。
    53. _rtrimArrayValues(陣列):將陣列中所有的字串去尾部空白。
    54. _convertNullArrayValuesToEmpty(陣列):將陣列中所有的null值轉成空字串。
    實體層DB_mysql類別繼承DB_common類別後加以下方法:
    1. DB_mysql():執行DB_common(),實體化物件。
    2. connect(dsn陣列,是否持續連線):連結並登入資料庫。
    3. disconnect():中斷連結。
    4. simpleQuery(查詢句):送出查詢。
    5. nextResult(結果id):尚未完成。本意是要移向下一組結果idid。
    6. fetchInto(結果id,陣列名,結果萃取模式,第幾筆):取某一筆放一維陣列,key改小寫,值去尾端空白,null換成空字串。
    7. freeResult(結果id):釋放結果所佔的記憶體。
    8. numCols(結果id):欄數。
    9. numRows(結果id):筆數。
    10. autoCommit(開或關):開或關交易自動更新模式。
    11. commit():確認更新當前的交易。
    12. rollback():回復當前的交易。
    13. affectedRows():查出並傳回受影響的筆數。
    14. nextId(序列名,無表時是否自動產生):下一個可用的id。
    15. createSequence(序列名):建序列表,只有id一欄,自動加一,加一筆其值0。
    16. dropSequence(序列名):刪除序列表。
    17. _BCsequence(序列表名):序列表留id最大那筆。
    18. quoteIdentifier(字串):將字串內的「`」換成「``」並在字串前後均加「`」。
    19. quote(字串):quoteSmart(字串)並回傳。
    20. escapeSimple(字串):為字串加入跳脫字元並回傳。
    21. modifyQuery(查詢句):在delete查詢句尾加上「where 1=1」以便知道刪了幾筆。
    22. modifyLimitQuery(查詢句,起始筆,筆數):查詢句為資訊操作指令,則只加limit 筆數,否則加limit 起始筆,筆數。
    23. mysqlRaiseError(錯誤碼):依錯誤碼傳回raiseError(錯誤碼,null,null,null,mysql錯誤碼及錯誤描述)物件。
    24. errorNative():傳回最後一次查詢所生的DBMS的錯誤碼。
    25. tableInfo(結果id或表名,有無次序索引):傳回欄數、諸欄五屬性,有無次序索引為4n+0無、4n+1有[order]、4n+2有[ordertable]、4n+3有兩者。
    26. getSpecialQuery(指示):指示為tables傳回SHOW TABLES、為databases傳回SHOW DATABASES、為users傳回SELECT DISTINCT User FROM mysql.user。

    (二)其他

    1. Benchmark/Timer.php:時間計數
    2. PEAR/Info.php:PEAR 設定檔及所安裝的套件訊息,用show()方法看。
    3. HTML_QuickForm:表單

    五、非正常安裝

    (一)租賃主機上安裝

    1. 用phpinfo()查看,沒有任何pear的資訊。如有則可查出pear放在什麼目錄。
    2. 下載所需要的套件包,如基礎包PEAR-1.7.1.tgz和資料庫包DB-1.7.13.tgz
    3. 把套件包解壓縮到本地
    4. 在主機上的虛擬目錄.htdoc或.www之外建立一個include文件夾。然後將剛才解壓出來的檔案上傳到該目錄(如DB包可以只上傳DB.php和DB目錄,PEAR包上傳OS,PEAR,SCRIPT目錄和PEAR.php文件)
    5. 因為無法修改php.ini文件,所以我們在要使用套件的腳本檔加上:
      	  ini_set("include_path",'/var/.../includes/'.PATH_SEPARATOR.ini_get("include_path" ));
      	  require_once "DB.php";

    (二)暴力更新

    當PEAR套件管理程式版本太舊無法更新成功時,可依此法:

    1. 移除舊版:pear uninstall PEAR,因DB套件相依,需一併移除。
    2. 拷貝新版的pearcmd.php,放入/usr/share/pear/之下。
    3. 自製或拷貝新版的shell腳本檔pear,放/usr/bin之下,內容為「exec /usr/bin/php -C -d include_path=/usr/share/pear -d output_buffering=1 /usr/share/pear/pearcmd.php "$@"」
    4. 用pear download PEAR,下載新的套件如PEAR-1.7.1.tgz,再以tar zxvf xxx.tgz解壓縮還原出資料夾,取其中的PEAR.php、System.php、PEAR資料夾、OS資料夾,放在/usr/share/pear之下。
    5. pear install --force PEAR-1.7.1.tgz。
    6. 重新裝回DB套件。