Php教學文件
- 壹、基本說明
- 貳、基本動作
- 參、資料
- 一、資料與算符
- (一)資料型別
- (二)算符
- (三){}的各種用法
-
- 二、常數與變數
- (一)常數
- (二)變數
- 三、字串
- (一)單引號字串
- (二)雙引號字串
- (三)自訂引號(Heredoc)
- (四)字串索引
- (五)字串函式
- (六)正規表示式
- 四、陣列
- 五、類別與物件
- 六、參照
- 肆、控制結構
- 伍、載入程式及定義函數
- 陸、檔案
- 柒、函式
- 捌、設定
- 玖、SAPI
- 拾、PEAR
壹、基本說明
- PHP:
- Personal Home Page Tools。
- 巢狀的縮寫名稱:Hypertext Preprocessor,打開縮寫還是縮寫。
- PHP是一種「伺服器端嵌入式的跨平台描述性語言」
- 在伺服器端執行。伺服器的功能:提供網路服務。
- 嵌入網頁中,在…?>中的部分,執行成HTML語法,丟給瀏覽器端。*.php是指內含php語法的html檔,不是指通篇都是php的檔(也可以通篇是php);注意.php中,非…?>的部分,伺服器端和瀏覽器端看到的是一樣的;…?>的部分,伺服器端和瀏覽器端看到的是不一樣的,前者看到是php語法,後者看到的是輸出的html。perl,c不是嵌入式,ASP、PHP是嵌入式。
- 跨平台。
- 描述性語言,無須先編譯成二進位檔,就能執行。
- 變數分大小寫,保留字不分大小寫。
- 保留字可以做變數名(因前有$),不能做常數名、函式名、類別名,因為之前沒有$和保留字做區隔。
貳、基本動作
- 嵌入Html的方法:
- 短型:<?…?>
- XML型:<?php…?>
- SCRIPT型:<SCRIPT language='php'?>…</SCRIPT>
- ASP型:<%…%>
- 創造一段記憶體空間,在其中操作「資料」。
- 以敘述為基本操作單位,由「資料」「算符」「;」共同構成。
- 「資料」可為常數或變數。資料來自通道、檔案或程式本身。
- 「算符」為對資料的操作。
- 「;」代表執行,用以結束敘述。
- 敘述區塊:在某些條件下才執行的敘述集合,結構為「條件{諸敘述}」。
- 函式既是算符也是敘述區塊。用以將「諸敘述」整合成一個敘述再變成算符寫進「單一敘述」。
- 重要提示:
- 輸出字串:echo "字串";
- 輸出:print_r(陣列或物件);
- 空白空行的作用和HTML一樣。
- 兩個敘述可以寫在同一行:…;…;。
- 註解:
- 多行註解:/*…*/。不可以巢狀。
- 單行註解://或#,註解一直到行末。可以插到敘述分號之後。
- @為錯誤抑制命令,放在敘述頭。
參、資料
一、資料與算符
(一)資料型別
- PHP共有四種純量資料型別:
- 整數(integer)。
- 浮點數(float)。
- 布林(boolean)。
- 字串(string)。
- PHP共有兩種複合資料型別:
- 陣列(array)。
- 物件(object)。
- PHP共有兩種特殊資料型別:
- NULL:只有一值null。
- 資源 (resource):檔案的handle,MySQL請求的結果。
- 變數的資料型別取決於指派給它的值,可以隨時指派新型別的資料,來改變變數的資料型別。
- 轉換型別:$新變數=(新型別)$原變數;。如$a=0;$b=(double)$a:$a是整數0,$b是浮點數0。
- gettype(變數串);取得變數型別:nuknow type,boolean,integer,double,string,array,object,NULL,resource,傳回值是字串。
- settype(變數串,資料型別);設定變數的資料型別。還有:
- intval(變數串):傳回整數。
- floatval(變數串):傳回浮點數,會處理掉變數中的特殊字元及$號。
- doubleval(變數串):傳回倍浮點數,會處理掉變數中的特殊字元及$號。
- strval(變數串):傳回字串。但變數串不能是陣列或物件。
- 測試變數型別,是傳回真,不是傳回偽:
- is_integer()同is_int()同is_long()。
- is_double()同is_float()同is_real()。
- is_string()。
- is_array()。
- is_object()。
- is_null()。
- isset(變數串);變數存在。
- unset(變數串);刪除變數。
- empty(變數串);變數存在且為0或空值。
型別 | 實字 | 資料生成指令 | 帶型別資料 | 指標 | =○ | =&○ |
NULL | null | 無 | 不可使用 | 純量 | 派值 | 不可 |
整數 | 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中的物件) |
「帶型別資料」欄中的值可為實字可為變數;「=○」「=&○」前六列中的○,均代表該型別的實字。
(二)算符
- 指派:=。如$b=6+($a=5);
- 四則:加(+),減(-),乘(*),除(/)。php 的整數四則只支援到 32 bit 的整數,更大的整數會被當作浮點數處理而損失精準度。如要算更大的數就要用BC高精準度函式(BC Math)(Binary Calculator)。
- 餘數(%):A%B,A,B先取整數,再取A除以B的餘數。
- 二元算符:$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;
- 遞增遞減算符:++$x是$x=$x+1;$y=$x++是指定$x的值給$y,再將$x的值加1。
- 參考算符(&):
- $a=5;$b=$a;,當$a=7;時,$b還會維持5。
- $a=5;$b=&$a;,當$a=7;時,$b會同步變成7。$b隨時參考$a的值為其值,$b之值隨$a之值變化而變化。
- 數值比較算符:傳回真(1)、偽(0),有<,>,==(相等),===(全等:值等且型別相同),<=,>=,!=,<>
- 字串連結算符(.):字串一.字串二.字串三…。
- 邏輯算符(可處理數值、字串):AND(&&)、OR(||)、NOT(!)、XOR(任一為真且僅一為真)。非零為真,零為偽。如10||0得出1;10&&0得出0;!10得出0;!0得出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。
- |:位元以OR運算。
- ^:位元以XOR運算。
- ~:位元以NOT運算。
- <<:位元左移。
- >>:位元右移。
如3&7為0011AND0111得出0011,即得3。如7>>1為0111右移一位得出0011,即得3。
- 逗號算符:分隔函數參數與其他表列事項。
- 陣列算符:[]。
- 依條件傳回:
- 三元算符?::條件 ? 為真時 : 為偽時。
- PHP 5.3+:$expr1 ?: $expr2,$expr1 為真,傳回 $expr1,否則傳回 $expr2。
例:expr0 ?: expr1 ?: expr2 ?: expr3…:expr0 不成立就判斷 expr1 ,也不成立就判斷 expr2 ,再不成立就判斷 expr3 …
- 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() 的差異
- 抑制錯誤算符@
- 執行算符`:PHP會執行夾在兩個`之間的作業系統命令,如Linux的`ls`或微軟的`dir c:`
- new:依類別定義製造一個物件。
- ->:取物件的屬性或方法。
- 算符優先順位在p30。
(三){}的各種用法:
- 將多個獨立語句合併為一個複合語句,例如 if … else …中經常如此使用
- 在變數間接引用中進行定界,避免歧義。例如 ${$my_var[8]}與${$my_var}[8]的區分
- 指示字串變數中的單個字元(下標從0開始),例如:「$my_str="1234"; $my_str{1}='5';」現在 $my_str 內容為'1534'
此用法為PHP 5之後的特性,用於消除使用中括號引起的歧義。
- 界定變數的名稱:「$var='sky'; echo "{$var}boy";」
二、常數與變數
- 兩者都是要得到「資料」。
- 常數代表的資料經定義不再改變。常數是全域的。
- 變數可用算符改變內容。變數有範圍(scope)。
(一)常數
- 引用常數時,常數名不加引號,不加$。
- define("常數名",常數值):定義常數。常數一般用大寫字母(不是規定,但易於維護)。常數值只可為整數、字串、浮點數、布林值。
- defined("常數名"):查此常數值是否被定義過。
- PHP系統定義了以下一些常數:
- __DIR__:該 PHP 程式的檔案系統絕對路徑,如 DB.php 的 __DIR__ 是「/volume1/web/et/class/database」。若 DB.php 被 test.php 引用載入(include 或 require),則:
- DB.php 內的 __DIR__ 是指 DB.php 的路徑,而不是 test.php 的路徑。
- DB.php 內的「.」是指 test.php 的路徑,而不是 DB.php 的路徑。
- __FILE__:PHP 程式的檔案系統絕對路徑完整檔名,如 DB.php 的 __FILE__ 是「/volume1/web/et/class/database/DB.php」。若 DB.php 被 test.php 引用載入(include 或 require),則:
- DB.php 內的 __FILE__ 是指 DB.php 的路徑檔名,而不是 test.php 的路徑。
- DB.php 內的「.」是指 test.php 的路徑,而不是 DB.php 的路徑。
- DB.php 內的「$_SERVER["PHP_SELF"]」取得的是 test.php 的 url 適當的代表檔名,以域名代表的目錄為根目錄。
- __LINE__:PHP 程式行數。若引用檔案 (include 或 require)則在引用檔案內的該常數為引用檔案的行,而不是引用它的檔案行。
- __FUNCTION__:預設常數,PHP函式名稱
- __CLASS__:預設常數,PHP類別名稱
- __METHOD__:預設常數,PHP方法名稱
- PHP_VERSION:PHP 程式的版本,如 '3.0.8-dev'。
- PHP_OS:執行 PHP 剖析器的作業系統名稱,如 'Linux'。
- NULL:空值 (null)。
- TRUE:真值 (true)。
- FALSE:偽值 (false)。
-
值 |
常量 |
描述 |
備註 |
1 |
E_ERROR |
最近的錯誤處 |
|
2 |
E_WARNING |
最近的警告處(非致命錯誤) |
|
4 |
E_PARSE |
剖析語法有潛在問題處 |
|
8 |
E_NOTICE |
發生不尋常但不一定是錯誤處。例如存取一個不存在的變數。(比 Warning 的嚴重性更低) |
|
16 |
E_CORE_ERROR |
在 PHP 初始化過程中發生的致命錯誤 |
PHP 4之後 |
32 |
E_CORE_WARNING |
在 PHP 初始化過程中發生的警告(非指明錯誤) |
PHP 4之後 |
64 |
E_COMPILE_ERROR |
編譯時指明錯誤 |
PHP 4之後 |
128 |
E_COMPILE_WARNING |
編譯時警告(非指明錯誤) |
PHP 4之後 |
256 |
E_USER_ERROR |
用戶自定義錯誤資訊 |
PHP 4之後 |
512 |
E_USER_WARNING |
用戶自定義警告資訊 |
PHP 4之後 |
1024 |
E_USER_NOTICE |
用戶自定義提醒資訊 |
PHP 4之後 |
2048 |
E_STRICT |
編碼標準化警告(建議如何修改以向前相容) |
PHP 5之後 |
4096 |
E_RECOVERABLE_ERROR |
接近致命的運行時錯誤,若未被捕獲則視同E_ERROR |
PHP 5.2.0之後 |
8192 |
E_DEPRECATED |
若啟用,會收到警告,指出程式碼中未來的PHP版本將不支援之處 |
PHP 5.3.0之後 |
16384 |
E_USER_DEPRECATED |
類似E_DEPRECATED,但是由 trigger_error() 函式來觸出警告 |
PHP 5.3.0之後 |
30719 |
E_ALL |
所有的錯誤、警告 |
PHP6:32767, PHP5.3.x:30719, PHP5.2.x:6143,之前:2047 |
※錯誤碼是位元掩碼(bitmask),可由數個值來疊加,可以用位元操作來掩去或加上某些位元值。
php.ini只認得~!&|四個位元操作,php3.ini不認得任何位元操作。
錯誤碼的預設可由php.ini的error_reporting選項來設定;或 Apache 配置檔中的 php_error_reporting 來設定;或腳本中的error_reporting()函式來改變。
@前綴會屏蔽該行指令的所有錯誤訊息,但不會屏蔽解析錯誤訊息。如果 track_errors 選項設為開啟,則您還是可以在全域變數 $php_errormsg 中找到錯誤訊息。
(二)變數
- $變數名:大小寫不同$A和$a是兩個不同變數,變數名可以用數字、字母、_,但不能以數字開頭,也不可以含有-、@、!、+等運算元。
- 可以宣告變數,但通常不需要宣告,第一次指派值時,變數會自然產生。
- 指定值給變數:$變數名=數值、字串或另一變數。
- 變數的變數(動態變數):如$a="b";則$$a為$b。$$a以變數$a之值為名。
- 當變數名可能混淆時,用{}括住$及變數名。如$$a[0]="Kitty!"; 用這個語法 PHP 不曉得 $a 和 $a[0] 那一個才是變數,所以算錯;要用${$a}[0]或${$a[0]}來區別兩個含義不同的動態變數。又如{$preparation}d表示$preparation值後緊接著d。
- 函式變數,又稱匿名函式,用create_function()造出來。例:
$list = create_function('$a,$b','return "ln($a) + ln($b) = ".log($a * $b);');
echo $list; // 得 lambda_#,#是整數會跳動
echo $list(2,M_E); // 得 ln(2) + ln(2.718281828459) = 1.6931471805599
echo gettype($list); // 得 string
- phpinfo();會列出之前定義的函數、常數及其他資訊。
- 變數範圍(scope):
- 宣告廣域變數(global),不包括函數內部。
- 函數內部使用的變數,只在函數內部有效。為區域變數,函式執行完變數消滅。
- 函數內宣告成廣域變數的變數指的是參考到同名的廣義變數。
global $變數名;宣告廣域變數。
$GLOBALS["變數名"]:使用廣域變數。$GLOBALS為超級廣域變數,不用宣告即可在函式內使用,其元素為諸廣域變數,以變數名索引變數值。
- 靜態變數:函式內的變數,用「static $變數=初值;」或「static $變數;」宣告,下一次再執行函式時,其值不會消失,會保留上次此函式執行所遺留的值。
但「靜態變數 =& 演算式 ;」將一個參照派給靜態變數時,變數值並不會被記住。
- 傳入變數的通道:一通道走一陣列,每一元素代表一變數,字串索引為變數名,元素值為變數值。不同通道可以有相同之變數名。
- $_GET :走 HTTP GET 通道進來,有長度限制。
- 直接使用:加在url中?之後,變數名與變數值用=相連,變數間用&間開。
- 表單用get方法後送:則將諸表單變數變成url中「?…」取代原有url中的「?…」。
- $_POST :走 HTTP POST 通道進來,無長度限制。
- $_COOKIE :取客戶端之COOKIE變數。
- $_REQUEST:$_GET、$_POST、$_COOKIE三者的綜合,如果變數同名,$_POST中的值會蓋掉$_GET中的值。
巢狀的form,其內層的form全部失效,只有最外層的form有效。form中多確認按鈕(submit),被按下的才後送,沒被按下的不後送。
- $_FILE :上傳檔案。
- $_SESSION:連線會期。
- $_SERVER :由網頁伺服器送來的變數,約28個如:
'PHP_SELF'=>目前執行的檔案名稱,以域名代表的目錄為根目錄,和__FILE__不同。可直接簡稱$PHP_SELF、
'SERVER_NAME'=>伺服器的名稱、
'SERVER_SOFTWARE'=>伺服器使用的軟體、
'DOCUMENT_ROOT'=>文件的根目錄、
'HTTP_USER_AGENT'=>使用者相關資訊、
'REMOTE_ADDR'=>遠端使用者的位址、
'REMOTE_PORT'=>遠端使用者的連線埠、
- $_ENV :由作業系統送來的變數,共6個。
- 終端:TERM,如 xterm ,X Window System上的標準虛擬終端。
- 執行檔預設路徑:PATH,如「/sbin:/usr/sbin:/bin:/usr/bin」。
- 現用工作目錄:PWD,如「/」。
- 語言:LANG,如「C」,代表zh_TW.UTF-8。
- shell的嵌套層次:SHLVL,如「2」。
- 環境:「_」,如「/usr/sbin/httpd」
- 當 register_globals 設為 On 時
- register_globals意為直接註冊為廣域變數,預設為關閉。在 php.ini 中設定。
- 程式執行時會先將 $_GET、 $_POST、 $_COOKIE、 $_SESSION中的元素轉換成以索引為名的變數,如將$_POST['jj']轉變成$jj,而且改動變數值時會同時改動元素值。此時如果變數同名就會導致程式錯誤。
- 這是php最早的變數傳入模式,比諸通道變數還早,但現在這樣的用法已不常見,而且不受推荐。
- cookie:建立客戶端專一性。由伺服器在客戶端建立變數,由伺服器讀取。
- 以函式setcookie('變數名',變數值,存活到何時,有權存取之網址路徑,有權存取之網域,是否保密)存入客戶端,以$_COOKIE通道變數讀取。
- 由於客戶端作業系統不一,瀏覽器種類版本不一,所以建立變數時,所以約定由 HTTP 標頭,由伺服器端向客戶端傳向一個或多個「Set-Cookie: 變數名=變數值;」行。
- 由於因為建立cookie是HTTP 標頭的一部分,所以使用setcookie()函式一定要在伺服器送出HTML顯示資料之前,否則無效。
- 客戶端(瀏覽器)接收到 Set-Cookie 指令時,會將 Cookie 的名稱與值儲存在瀏覽器的 Cookie 存放區,並記錄該 Cookie 隸屬的網域、網址路徑、過期時間、是否為安全連線等資訊。
- 當瀏覽器再次發出 HTTP Request 指令到伺服器時,就會比對目前在瀏覽器內的 Cookie 存放區有沒有「該網域」、「該目錄」、「過期時間尚未過期」且「是否為安全連線」的 Cookie,如果有的話就會包含在 HTTP Request 指令的 "Cookie:" Header 中。
- 使用setcookie()的那一頁,首次建setcookie變數值時,本身那一頁一時還抓不到,要重新整理或用超連結換頁,變數值才能抓到。
- 變數值限用字串,如變數值為空字串,代表取消本cookie變數;有權存取之路徑預設為"/",代表所有檔案皆可存取;有權存取之網域預設空字串,任何網域皆可;是否保密預設0,代表HTTP管道傳送,1代表cookie在SSL環境才能傳送。
- 由於每個客戶每種瀏覽器都有自己的 cookie 存放系統,所以 cookie 具有「客戶專一性」。例如:登錄網頁後,產生cookie,讀後續網頁時檢查有無此cookie,使別人即使知道後續網頁網址也通不過。
- 存活到何時限用整數,以秒為單位,預設0,代表到結束瀏覽器或重開瀏覽器為止,所以具有「會期專一性」。
其餘秒數代表由1970/1/1到有效期的秒數,可利用兩函數:time()傳回1970/1/1到現在的秒數,用time()+幾秒,可設由現在開始幾秒內cookie有效;mktime(時,分,秒,月,日,年)傳回1970/1/1到指定時刻的秒數,可設cookie到那一天有效。
- 預設網址路徑為「/」,代表所有路徑皆可存取,不安全。
- 預設網址為伺服器url之根部,代表該網址可存取,所以具有「伺服器讀取專一性」。
- 由於Cookie盜賊(搜集使用者cookie並發給攻擊者),Cookie投毒(修改cookie,如在購物網站的cookie中改小顧客應付款項,以減少付款),cookie對伺服器和客戶雙方而言皆不安全。但其他替代方案也有類似的問題。
- 浪費頻寬,拖慢顯示:假設瀏覽器在取得一張網頁時如果裡面包含 20 張圖、3 個 CSS、2 個 JavaScript 檔的話,同樣一份 Cookie 就會送出 25 次到伺服器端,如果你 Cookie 的大小有 4K 的話,光是看一張網頁你可能就要從你的電腦發送出 100KB 的頻寬,且可能只有一張網頁用的到這個 Cookie 而已。
- session變數:以sessionId為索引,在伺服器上放置儲存變數的檔案,只要知道 sessionId ,伺服器端的php程式,即可取用session變數。好處是既可得到「客戶專一性」,又不浪費頻寬。
session產生時在伺服器端的session.save_path下造檔,檔名為「sess_唯一的sessionId」,sessionId之值可由系統給,也可由php程式設定,通常由PHP利用uniqid加上md5雜湊產生的字串,會隨時間做不規則變化,長度為26字元。檔內放session變數,以serialize()函式生成,儲存格式如「變數名|變數類別:變數長度或元素:{i:0;s:6:"丁志仁";i:1;s:4:"王大";}」。
跨頁取得正確的 sessionId 可以使用以下四種方法:
第一種,配合 cookie 的使用方式:
- 客戶端只須存一個 cookie 變數,變數名為 PHPSESSID (可依session.name設定而變化),變數值為伺服器上 session 檔的id,預設:存活到連線結束,伺服器之所有網址路徑皆可讀取。
- 建立 cookie 變數 PHPSESSID 必須在所有顯示發出之前,否則建立 cookie 變數會失敗。
- php.ini中 session.auto_start 如設為 1 ,那麼執行 php 程式時先自動產生 sessionId 並於提出請求的客戶端建立 cookie 變數 PHPSESSID ,且存入 sessionId 。後續的 php 程式執行前也皆自動session_start(),參考到這個 sessionId ,讀取之前建立的 session 諸變數。這個方法不管程式怎麼寫,同一次會期的 sessionId 一定會固定下來。
- php.ini中 session.auto_start 如設為關閉,就要很注意php程式撰寫, session_start() 一定要在所有顯示輸出之前執行。如 xoops 是在一開始載入主設定檔時,就執行 session_start() 。
第二種,不用 cookie 的而使用 URL 自動傳送 sessionId :
- 當客戶端把 cookie 功能關閉,跨頁時自動將「PHPSESSID=xxxxxxxxxxxxxxxxxxxxxx」附在 URL 中傳遞,以通知後續的網頁正確的 sessionId 。
- 此時 PHP 的 ini 設定必須打開 session.use_trans_sid (無法用ini_set()設定)、關閉 session.use_only_cookies 、給 url_rewriter.tags 正確的值。
- php 參考 url_rewriter.tagsart 中的設定去增附 URL ,預設包括 a 標籤的 href 屬性、 area 標籤 href 屬性、 frame 標籤的 src 屬性、 input 標籤的 src 屬性、表單的去處等五項。
第三種, cookie 和 session.use_trans_sid 皆關閉時,尚可手動透過的 HTTP POST 和 GET 通道傳送 sessionId :
- 會期中第一次執行 session_start() 時(通常是登入)讓伺服器產生 sessionId ,然後在同一支 php 程式中用 session_id() 函式查出傳回剛剛產生的 sessionId ,再用POST通道或GET通道傳給後續的php程式,而後續的php程式在執行 session_start() 之前先執行 session_id(得到的sessionId) 。
- 在撰寫登出時,要決定這個 sessionId 要不要再透過 POST 通道和 GET 通道傳下去,一中斷就無法查到之前的 session 變數。
- 建議在程式撰寫上要有共用的物件屬性攜帶共用的 URL 段落及共用的表單中隱藏元件。
第四種,將 sessionId 存在檔案中或資料表欄值中,但是要仔細建構會期的專一性,使不同的會期使用不同的 sessionId 。
相關的php.ini設定:(可用ini_get('設定名')查到)除 session.use_trans_sid 須在 php.ini 中才可以修改外,其他可以在程式中用 ini_set('設定項目','值') 加以修改
- session.auto_start:php程式要不要自動執行 session_start(),預設0:關閉。
- session.name:客戶端 cookie 中存 sessionId 的變數名稱,預設為PHPSESSID。
- session.save_path:伺服器存 session 檔的路徑,預設值為 /tmp 。
- session.save_handler:session存取的模式,預設值為 files ,即用檔案存。
- session.serialize_handler:字串化變數的處理模式,有 WDDX 模組或 PHP 內部使用。預設值為 php。
- session.cookie_lifetime:cookie變數的存活期,預設0,到會期結束為止。
- session.cookie_path:預設為「/」,伺服器上任何網址路徑皆可讀取。
- session.cookie_secure:預設空值,不加密。
- session.cookie_domain:預設為空值,客戶端會依伺服器的 URL 根部設定。也可以另行指定。
- session.use_cookies:預設值為1,代表SessionID使用Cookie來傳遞。
- session.use_only_cookies:只使用cookies不使用URL傳 sessionId ,預設值為0,即如果cookie關閉,設法用url傳 sessionId 。
- session.use_trans_sid:如果客戶端cookie不開,將「PHPSESSID=xxxxxxxxxxxxxxxxxxxxxx」附在 URL 中傳遞,以通知後續的網頁正確的 sessionId 。設為0代表禁止這麼做。
- url_rewriter.tags:如果要url傳送 sessionId ,要改寫的標籤有那些。預設為字串「a=href,area=href,frame=src,input=src,form=fakeentry」,將此設為空字串"",則即使想利用 URL 改寫也做不成。
- session.referer_check:按瀏覽器重新整理時檢查session是否還存在。預設空值。
- session.entropy_file:特別設定 session 值的檔案。預設空值。
- session.entropy_length:特別設定 session 值的長度,預設0:關閉。
- session.cache_limiter:使用cache限制器,預設值「nocache」:不用要cache。
- session.cache_expire:cache的存活秒數,預設180。
- session.gc_maxlifetime:Session檔在伺服器端儲存的時間,如果超過這個時間,那麼Session檔就自動刪除。
- session.gc_probability:資源回收筒(garbage collection)的處理機率,預設1。
- session.gc_maxlifetime:回收前的存活秒數,預設1440。
- ini_get()函式查不到使用中的 sessionId ,要由 session_id() 函式才能查到。
相關的的函式:
- bool session_start ( void )
說明:建立一個session,或是經由GET變數或cookie,繼續目前的session id。
- bool session_destroy ( void )
說明:消滅所有session登記過的資料。
- string session_save_path ( [ string path ] )
說明:若未指定path,則傳回目前用來儲存session資料的目錄的路徑;如果有指定path,則改變session資料儲存的路徑。
- bool session_register ( mixed name [ , mixed ... ] )
說明:在目前session中登記一個或多個變數。目前已不再常用,直接在 $_SESSION 中放元素比較快,同時宣布變數名同時派變數值。
- bool session_unregister ( string name )
說明:從目前的session將變數取消登記。可以從 $_SESSION 去掉一個元素。
- string session_id ( [string id])
說明:取得或是設定一個session的session id。PHP判斷session是否打開是用 session_id() 處理,若傳回空字串則 session 未打開。例如:if(!session_id()){session_start();}
- string session_name ( [string name])
說明:取得或是設定客戶端 cookie 中存 sessionId 的變數名稱。
- bool session_is_registered ( string name)
說明:檢查一個變數是否已經儲存在session內。
- void session_set_cookie_params ( int lifetime [, string path [, string domain [, bool secure]]])
說明:設定session cookie的細節。
- bool session_decode(string data)
說明:直接以編碼將變數存入 Session 。成功則傳回 true 。例如「session_decode('jj|s:6:"123456";jj2|i:5;');」等於「$_SESSION['jj']='123456';$_SESSION['jj2']=5;」。
- string session_encode(void)
說明:傳回 Session 中諸變數的編碼,等於直接窺視 session 檔的內容。本函式沒有參數。
SID常數:
- session_start()前為未定義。
- 有 $_COOKIE['PHPSESSID'] 時為空字串。
- 其他時候為 PHPSESSID=xxxxxxxxxxxxxxxxxxxxxxxxxx 。
session 運作流程如下:
SID常數未定義
session_start()
↓SID常數已定義
查session_id()是否派值
├→有→伺服器端讀取對應的session檔案,並對客戶端覆寫cookie變數PHPSESSID,SID為PHPSESSID=xxxx
└→無→查$_COOKIE['PHPSESSID']是否派值
├→有→讀對應的session檔,SID為空字串
└→無→查$_REQUEST['PHPSESSID']是否派值
├→有→讀對應的session檔,SID為PHPSESSID=xxxx
└→無→創一個新的sessionId→造對應的session檔→覆寫cookie變數PHPSESSID,SID為PHPSESSID=xxxx
- 上傳檔案:
- form的屬性一定要設method="post",一定要設enctype="multipart/form-data",encoded type為傳送可分為數個封包/傳送資料當成表單後送資料之一。
- 伺服器端產生四個變數$後送變數名稱放「暫存檔名」,一般都是「php+亂數.tmp」;$後送變數名稱_name放「原檔名」,$後送變數名稱_size放「檔案大小」,$後送變數名稱_type放「MIME類型」。
- 此時只有暫存檔,且暫存檔會在網頁執行完畢後刪除,所以要用copy("暫存檔名","路徑檔名"),真正完成上傳。
三、字串
(一)單引號字串:
- 變數名當成普通字串,不代入變數值。
- \':單引號
(二)雙引號字串:
- 變數名以變數值代入。
- \n:換行
- \r:歸位
- \t:定位字元TAB
- \s:空白
- \':反斜+單引號等雙字元
- \":雙引號
- \\:反斜
- \$:錢號,處理變數時很重要。
- \一到三位數字:以8進位指定字元
- \x一到二位數字:以16進位指定字元
(三)自訂引號(Heredoc):
- 「<<<自訂引號名稱,換行…引號內…換行,自訂引號名稱;」。
$str = <<<EOS
…
EOS;
請注意,自訂引號名稱跟<<<之間沒有空格。
- 自訂引號字元串,須以字母開頭,可用字母、數字、_。
- 變數名以變數值代入。
- \n:換行
- \r:歸位
- \t:定位字元TAB
- \\:反斜
- \$:錢號,處理變數時很重要。
- \一到三位數字:以8進位指定字元
- \x一到二位數字:以16進位指定字元
(四)字串索引
- $字串變數名[整數字]:字串的第幾byte,utf-8算3byte。
- $字串變數名[非整數]:非整數捨去小數變整數,字串的第幾byte,utf-8算3byte。
- $字串變數名[字串]:字串的第幾0byte,utf-8算3byte。
(五)字串函式
- ord(字串):傳回字串首字元的ASCII碼。
- chr(數字):將ASCII碼轉為字元。
- trim():去頭尾空白,換行,含\n和\r。
- ltrim():去頭部空白。
- chop():去尾部空白。
- nl2br():將"\n"換行改成<br>。
- strip_tags(字串,不去除的標籤):除去HTML及PHP標籤。
- parse_url(url字串):依「scheme://user:pass@host:port/path?query#fragment」格式解析url,並傳回陣列,其元素索引為scheme、user、pass、host、port、path、query、fragment。
- parse_str(query字串):將query字串解析成諸變數。如「first=value&second[]=this+works&second[]=another」,傳回$first=value;second[0]="this works";second[1]="another"。
- print():同作用同echo,但print是函式,傳回布林值。
- printf():格式化字串,傳回整數。
- sprintf(規格,字串):格式化字串。
轉換規格%[顯示寬度][-][][.小數位數]型別:有-代表向左靠齊,沒-代表向右。
- %b:將變數解釋為整數,並以二進位顯示。
- %c:將變數解釋為整數,並以字元顯示。
- %d:將變數解釋為整數,並以十進位顯示。
- %f:將變數解釋為浮點數,並以浮點數顯示。
- %o:將變數解釋為整數,並以八進位顯示。
- %s:將變數解釋為字串,並以字串顯示。
- %x:將變數解釋為整數,並以十六進位顯示,用a-f。
- %X:將變數解釋為整數,並以十六進位顯示,用A-F。
- AddSlashes():若有反斜時,加上Slash,讓輸入字串若含特殊字元時,加上逸出字元\,以免存入資料庫時衝碼。Q3上引數為變數時,做完此運算立刻存回此變數,導致變數值改變;較新的版本,引數為變數時,做完此運算不會導致變數值改變。
- StripSlashes():若有反斜時,去掉Slash,使資料庫取出資料還原。Q3上引數為變數時,做完此運算立刻存回此變數,導致變數值改變;較新的版本,引數為變數時,做完此運算不會導致變數值改變。
- strtoupper():轉大寫。uppercase大寫。
- strtolower():轉小寫。lowercase小寫。
- ucfirst():字串首轉大寫。
- ucwords():字串中每個Word的字首轉大寫。
- explode("分隔字元",字串[,最多傳回幾個元素]):將字串以分隔字元拆成一個個元素,變成陣列。分隔字元可以是多byte,如「=>」。
- implode("分隔字元",$陣列):將陣列元素以分隔字元串成字串,又叫join()。分隔字元可以是多byte,如「=>」。
- strtok(字串,"分隔字元"):擷取字串的前面到分隔字元為止,分隔字元可以用中文單字不能用字串,如用英文字串,當成英文字串的首字元。注意 : 只有在第一次呼叫strtok( )時,才使用字串參數,之後的呼叫只要使用分隔字元,它會記錄目前的字串。要切開另一個新的字串時,你只需要再一次呼叫 strtok( )和字串參數即可。你可以在分隔字元參數中放置多樣的分隔字元,當找到任何參數中的字元時,字串將會被切開。如<? $string = "I will be back";$tok=strtok($string," ");while ($tok){echo "Word=$tok<br>";$tok=strtok (" ");} ?>依次傳回I will be back。
- substr(字串,開始字元,長度):擷取子字串,第一字元算0;長度省略則取到字尾。
開始字元為負,為從字串尾倒數,字尾算-1,仍往下取到字尾,不是逆向取字。例如:
- echo substr('abcde',-1);:會輸出 e,因為從字尾開始算,取至字尾。
- echo substr('abcde',-2);:會輸出 de,因為從字尾倒數2開始算,取至字尾。
長度為負則先依開始字元取到字尾,再從其中的字尾開始扣除長度。例如:
- echo substr('abcd',-3,1);:會輸出 b,因為從字尾開始算,先取三個字母為 bcd,接著長度在從 bcd 取 1 位。
- echo substr('abcdef',0,-1);:會輸出 abcde,函式先從零開始取整段字串,長度再由字串尾扣掉一個。
- echo substr('abcdef',2,-1);:會輸出 cde,函式先從第二個字元開始,取得 cdef 這幾個字,再由取得的字串尾扣掉一個。
- echo substr('abcdef',5,-2);:會回傳 false,因為程式一開始先取得 f,然後扣掉兩個字元,就 false 了!
- 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 多字節字的意思
- strcmp(字串一,字串二):比較兩字串,相等為0,正為字串一ASC碼大,負數為字串二ASC碼大。
- strcasecmp(字串一,字串二):同上,但不分大小寫。
- strrev(字串):顛倒字串。
- strlen(字串):字串長度,UTF-8中文字長度算3。mb_strlen(字串,'UTF8'),UTF-8中文字長度算1。中英文混排字串的佔位寬度為(strlen(字串)+mb_strlen(字串,'UTF8'))/2。
- str_pad(字串,位數[,補什麼[,補法]]):補齊位數。補什麼預設值為空白,補法:STR_PAD_RIGHT補右邊(預設)、STR_PAD_LEFT補左邊、STR_PAD_BOTH左右兩邊平均補。
- strstr(字串,子字串)?substr(字串,0,strpos(字串,子字串)):字串:取子字串之前的部分(不含子字串),找不到傳回原字串。
- strstr(字串,子字串):找到傳回子字串「第一次」出現以後之剩餘字串(含子字串),找不到傳回「假」。自PHP 5.3 增加第三參數 strstr(字串,欲找之子字串[,是否傳回欲找字串之前的段落]),「是否傳回欲找字串之前的段落」的預設值為 false ,即傳回子字串「第一次」出現以後之剩餘字串(含子字串);若設為 true 則傳回子字串「第一次」出現以前的段落(不含子字串),兩者合起來恰為原字串。
- strstr(字串,欲找之子字串)?substr(strstr(字串,欲找之子字串),strlen(欲找之子字串)):字串:找到傳回子字串「第一次」出現以後之剩餘字串(不含子字串),找不到傳回原字串。
- strchr(字串,欲找之子字串):同上。
- stristr(字串,欲找之子字串):同上,但不分大小寫。
- strrchr(字串,欲找之子字串):找到傳回子字串「最後一次」出現以後之剩餘字串,找不到傳回「假」。
- strpos(字串,欲找之子字串,指定蒐尋之起始位置):找到傳回子字串「第一次」出現的位置,找不到傳回「假」。字串首位置算0,省略蒐尋起點時,從字串首開始找。但是「假」傳回值是0,字首位置傳回值也是0,會混淆。可以用if(傳回值===false)測,如果成立傳回值代表「假」,如果不成立傳回值代表位置0。
- strrpos(字串,欲找之子字串,指定蒐尋之起始位置):找到傳回「子字串字首字元」「最後一次」出現的位置,找不到傳回「假」。字串首位置算0,省略蒐尋起點時,從字串首開始找。
- str_repeat(字串,重覆次數):重覆字串若干次。
- str_replace(蒐尋字串,代換字串,字串堆):在字串堆中找到「蒐尋字串」並用「代換字串」換掉它們。
- substr_replace(字串堆,代換字串,起點,長度):在字串堆指定的起點及長度,用代換字串換掉它們。起點為0或正,由字串堆頭起算;起點為負,由字串堆尾起算。長度未指定,則換到字串堆尾;長度為0,則插入原字串;長度為正,則取代幾個字串數;長度為負,則自尾端開如取代,停於長度。
- mb_convert_kana(字串,轉換方式):假名轉換。
- iconv("來源編碼","目的編碼",字串):轉碼,編碼代名:big5、utf8。
- chunk_split(字串,切的長度,每段末尾加):切成小段,切的長度預設為76,每段末尾預設加\r\n。
- quoted_printable_decode(qp編碼字串):將 qp 編碼字串轉成 8 位元字串。
- base64_decode(編碼字串):以MIME base64解碼。
- base64_encode(字串):以MIME base64編碼。只包含英文字母大小寫、阿拉伯數字、加號與反斜線,共 64 個基本字符。HTML標籤可以寫成:
<img src='data:image/png;base64,圖的編碼字串' />
- htmlspecialchars(字串[,引號格式[,字元集]]):將字串中&(和)轉成 &、< (小於) 轉成 <、> (大於) 轉成 >,引號:
- 如果轉義,雙引號轉為「"」,單引號轉為「'」。
引號格式 | 雙引號 | 單引號 |
---|
預設 | 轉 | |
---|
ENT_QUOTES | 轉 | 轉 |
---|
ENT_NOQUOTES | | |
---|
- htmlspecialchars_decode(字串[,引號格式]):將字串中 & (和)轉成 &、 < (小於)轉成 < 、 > (大於) 轉成 > ,引號:
- 如果轉義,「"」轉為雙引號,「'」轉為單引號。
引號格式 | 雙引號 | 單引號 |
---|
預設 | 轉 | |
---|
ENT_QUOTES | 轉 | 轉 |
---|
ENT_NOQUOTES | | |
---|
- htmlentities(字串[,引號格式[,字元集]]):將字串中100種ASCII碼轉碼,將轉碼的ASCII如下表
碼 | 換成 | 符 | 碼 | 換成 | 符 | 碼 | 換成 | 符 | 碼 | 換成 | 符 | 碼 | 換成 | 符 | 碼 | 換成 | 符 | 碼 | 換成 | 符 | 碼 | 換成 | 符 | 碼 | 換成 | 符 | 碼 | 換成 | 符 | 碼 | 換成 | 符 | 碼 | 換成 | 符 | 碼 | 換成 | 符 | 碼 | 換成 | 符 | 碼 | 換成 | 符 | 碼 | 換成 | 符
|
A0 | | | A1 | ¡ | ¡ | A2 | ¢ | ¢ | A3 | £ | £ | A4 | ¤ | ¤ | A5 | ¥ | ¥ | A6 | ¦ | ¦ | A7 | § | § | A8 | ¨ | ¨ | A9 | © | © | AA | ª | ª | AB | « | « | AC | ¬ | ¬ | AD | ­ | | AE | ® | ® | AF | ¯ | ¯
|
B0 | ° | ° | B1 | ± | ± | B2 | ² | ² | B3 | ³ | ³ | B4 | ´ | ´ | B5 | µ | µ | B6 | ¶ | ¶ | B7 | · | · | B8 | ¸ | ¸ | B9 | ¹ | ¹ | BA | º | º | BB | » | » | BC | ¼ | ¼ | BD | ½ | ½ | BE | ¾ | ¾ | BF | ¿ | ¿
|
C0 | À | À | C1 | Á | Á | C2 | Â | Â | C3 | Ã | Ã | C4 | Ä | Ä | C5 | Å | Å | C6 | Æ | Æ | C7 | Ç | Ç | C8 | È | È | C9 | É | É | CA | Ê | Ê | CB | Ë | Ë | CC | Ì | Ì | CD | Í | Í | CE | Î | Î | CF | Ï | Ï
|
D0 | Ð | Ð | D1 | Ñ | Ñ | D2 | Ò | Ò | D3 | Ó | Ó | D4 | Ô | Ô | D5 | Õ | Õ | D6 | Ö | Ö | D7 | × | × | D8 | Ø | Ø | D9 | Ù | Ù | DA | Ú | Ú | DB | Û | Û | DC | Ü | Ü | DD | Ý | Ý | DE | Þ | Þ | DF | ß | ß
|
E0 | à | à | E1 | á | á | E2 | â | â | E3 | ã | ã | E4 | ä | ä | E5 | å | å | E6 | æ | æ | E7 | ç | ç | E8 | è | è | E9 | é | é | EA | ê | ê | EB | ë | ë | EC | ì | ì | ED | í | í | EE | î | î | EF | ï | ï
|
F0 | ð | ð | F1 | ñ | ñ | F2 | ò | ò | F3 | ó | ó | F4 | ô | ô | F5 | õ | õ | F6 | ö | ö | F7 | ÷ | ÷ | F8 | ø | ø | F9 | ù | ù | FA | ú | ú | FB | û | û | FC | ü | ü | FD | ý | ý | FE | þ | þ | FF | ÿ | ÿ
|
22 | " | " | 3C | < | < | 3E | > | > | 26 | & | & |
|
- 未下引號格式:雙引號轉為「"」,單引號不轉
- 引號格式為ENT_QUOTES:雙引號轉為「"」,單引號轉為「'」
- 引號格式為ENT_NOQUOTES:單雙引號不轉。
用法如htmlentities($str,ENT_NOQUOTES,'utf-8')。使用本函式常造成中日韓文多字節字產生亂碼。
- get_html_translation_table([表型[,引號格式]]):產生翻譯表陣列,索引為原字元,值為轉換後字元。表型有HTML_ENTITIES, HTML_SPECIALCHARS兩種,前者有100個元素,後者有4個元素。如果省略表型,則為後者。
- strtr(字串,欲翻字串,轉換字串)或strtr(字串,翻譯陣列):將字串翻譯並回傳。翻譯陣列諸元素,索引為原字串,值為轉換後字串。使用陣列時,凡遇到陣列中有的元素就翻譯。
(六)正規表示式(regular expression)
PHP支援兩種正規表示式,POSIX和Perl。POSIX內建,Perl語法須將PCRE(Perl-compatible regular expression)程式庫編譯進來。正規表示式比字串慢,儘量用字串。
括號
- ():括住子表示式,通常為字串或字串選項。
- []:中括號內表示某「字元」或某字元之選項。諸選擇項目中,有任一選項相符,皆算相符。
- {}:括住重覆次數說明。
字元表示(可能在中括號內也可能在中括號外)
- \:跳脫字元。以下是須要加上 \ 表示的特殊字元:
- \\:\。
- \/:/。在preg_match及preg_replace中,即使在中括號內,也一定要用\/來表示字元/,因為此時/還代表樣式開始與樣式結束。
- \|:|。沒反斜則「|」表示多重選擇(讀成OR)
- \$:$。沒反斜則「$」表示匹配結尾位置。
- \^:^。沒反斜則「^」表示匹配開頭位置,或在方括號內使用時表示否定。
- \+:+。沒反斜則「+」表示匹配一個或多個前面的表達式。
- \*:*。沒反斜則「*」表示匹配零個或多個前面的表達式。
- \?:?。沒反斜則「?」表示匹配零個或一個前面的表達式。
- \.:.。沒反斜則「.」表示匹配除了換行符之外的任何單個字符。
- \( 和 \):( 和 )。沒反斜則圓括號 () 表示分組。
- \[ 和 \]:[ 和 ]。沒反斜則方括號 [] 表示指定一個字符集合。
- \{ 和 \}:{ 和 }。沒反斜則花括號 {} 表示指定前面表達式的重複次數範圍。
- \< 和 \>:< 和 >。沒反斜則< 和 >用來夾住「命名捕獲」的名稱。所謂「命名捕獲」請看下面的例子:
$pattern = '/(?<tag>\<\w+\>)/';
$text = "Here is a <firstTag> in the text and another <anotherTag> over here.";
if (preg_match($pattern, $text, $matches)) {
echo "Match found: " . $matches['tag'];
} else {
echo "No match found.";
}
在這個例子中:
「(?<tag>\<\w+\>)」定義了一個「命名捕獲」,名稱為「tag」。
「(?<tag>...)」 是「命名捕獲定義」,捕獲的內容會被命名為 "tag"。
「\<\w+\>」是匹配以 < 開始,接著是一個或多個字母或數字的字符,最後以 > 結尾的模式。
當匹配成功時,你可以通過 $matches['tag'] 來訪問匹配到的第一個 <…> 字串。此例中為 <firstTag> 。
如果你想找出所有的 <…> ,則函式用 preg_match_all 而不是 preg_match ,
而顯示 $matches['tag'] 的函式則須用 print_r() 而不是 echo 。
如果不使用「命名捕獲」,則 $matches[0] 放原句,而 $matches[1], $matches[2], $matches[3]…則依序存放捕獲到的匹配字串。
- 「.」在中括號外表示除\n以外的單一字元。如.at相符於cat,sat,mat;「.」在中括號內表示字元「.」。
- \.在中括號內外皆表示字元「.」。
- \-與-中括號內外皆表示:字元-。但-在中括號內也有區間的含意。
- \\:\。
- \/:/。在preg_match及preg_replace中,即使在中括號內,也一定要用\/來表示字元/,因為此時/還代表樣式開始與樣式結束。
-----反斜字母-----
- \s:代表分隔字元:[\n\t\f\r\v]。
- \S:非分隔字元[^\n\t\f\r\v]。
- \n:換行。
- \r:歸位。
- \f:換頁。
- \t:Tab。
- \v:垂直Tab。
- \c:控制字元。
- \d:代表數字,[0-9]。
- \D:代表非數字,[^0-9]。
- \w:代文字包,含字母、數字、底線。
- \W:代表非文字。
- \u:後面跟的是UTF十六進位編碼。
- [a-z]、[^a-z]:a到z、非a-z。
- [aeiou]:五個母音字中的一個。
- [a-zA-Z]:字母。
- 字元的單字表示法:
- [[:alpha:]]:字母。
- [[:alnum:]]:字母及數字。
- [[:lower:]]:小寫字母。
- [[:upper:]]:大寫字母。
- [[:digit:]]:數字字元。
- [[:xdigit:]]:16進位數字字元。
- [[:punct:]]:標點。
- [[:blank:]]:跳格及空白。
- [[:space:]]:空白。
- [[:cntrl:]]:控制字元。
- [[:print:]]:所有可視字元。
- [[:graph:]]:除空白字元外所有可視字元。
次數
- ?:重複0次或1次,等價於{0,1}。
- *:表示該樣式會出現0或0次以上,等價於{0,}。如(very )*large:相符於large、very large、very very large。
- +:表示該樣式會出現1或1次以上,等價於{1,}。如[[:alpha:]]+表示至少會有一個英文字母。
- {3}:重複三次。
- {2,4}:重複二到四次。
- {2,}:重複兩次以上。
字串首、字串尾
- ^(表示式),表示式須出現在被蒐尋字串首才算相符。如^bob。
- (表示式)$,表示式須出現在被蒐尋字串尾才算相符。如com$。
- ^(表示式)$,首尾所夾必須與表示式相符才算比對成功。如^[a-z]$,字串頭尾之間,出現a-z任一字元就算相符。
多重選擇「|」(讀成OR)
- (選項一)|(選項二)|(選項三):多選一都符合
非補獲比對
補完本段須參考:
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-9]。要看其前後是不是可以構成範圍。
運用
- emEditor 以正規表示式替換,要將「width="...."」雙引號置換成單引號,尋找字串寫成「width="([^"]*)"」非雙引號字元出現0次以上,取代字串寫成「width='$1'」其中,$1 代表第一個捕捉組(即 [^"]* 匹配到的部分)。
函式:
- ereg(正規表示式,被蒐尋字串,陣列名):在被蒐尋字串中找符合於正規表示式的子字串,陣列第0元素放原字串,之後每找到合條件的字串就放進陣列,成為一個元素。傳回真假(1,0)。陣列名可省略,省略陣列名,則只是單純地比對,找到則傳回值為 true。
- eregi(正規表示式,被蒐尋字串,陣列名):同ereg,但不分大小寫。
- ereg_replace(正規表示式,取代字串,被蒐尋字串):在被蒐尋字串中找到表示式,用取代字串換掉。PHP7已用preg_replace取代,比如:
ereg_replace("正規表示式", 取代字串, 被蒐尋字串)
// 修改後應為:
preg_replace("/正規表示式/",取代字串,被蒐尋字串)
「/」代表樣式開始及樣式結束
- eregi_replace(正規表示式,取代字串,被蒐尋字串):同ereg_replace,但不分大小寫。
- split(正規表示式表述之分隔字串,被切割字串,傳回元素上限):用分隔字串,將被切割字串,切成一段段,成為陣列中一個個元素。傳回陣列。
- 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 不分大小寫
- 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
- 在preg_match與preg_replace中,「/」代表樣式開始及樣式結束,「siU」不分大小寫,「\\3」為第三截。
模式修飾符(在patterns結束的斜線之後)
- i (PCRE_CASELESS):不分大小寫
- m (PCRE_MULTILINE):多行。預設為單行。如果目標字串中沒有 "\n" 字元,或者模式中沒有出現 ^ 或 $,設定這個修飾符不產生任何影響。
- s (PCRE_DOTALL):點號元字元匹配所有字元,包含換行符。如果沒有這個修飾符,點號不匹配換行符。一個取反字元類比如 [^a] 總是匹配換行符,而不依賴於這個修飾符的設定。
- x (PCRE_EXTENDED):忽略未經過轉義或不在字元類中的空白數據字元,並且位於一個未轉義的字元類外部的#字元和下一個換行符之間的字元也被忽略。這使被編譯模式中可以包含註釋。注意:這僅用於數據字元。空白字元還是不能在模式的特殊字元序列中出現,比如序列 (?( 引入了一個條件子組(譯註: 這種語法定義的 特殊字元序列中如果出現空白字元會導致編譯錯誤。比如(?(就會導致錯誤)。
- e (PREG_REPLACE_EVAL):已停用。如果設定了這個被棄用的修飾符, preg_replace() 在進行了對替換字串的後向引用替換之後,將替換后的字串作為 php 程式碼評估執行(eval 函式方式),並使用執行結果作為實際參與替換的字串。單引號、雙引號、反斜線(\)和 NULL 字元在後向引用替換時會被用反斜線轉義。
- A (PCRE_ANCHORED):強制為"錨定"模式,也就是說約束匹配使其僅從目標字串的開始位置搜索。
- D (PCRE_DOLLAR_ENDONLY):模式中的元字元美元符號僅僅匹配目標字串的末尾。如果這個修飾符 沒有設定,當字串以一個換行符結尾時, 美元符號還會匹配該換行符(但不會匹配之前的任何換行符)。如果設定了修飾符m,這個修飾符被忽略。
- S:執行額外的分析。當一個模式需要多次使用的時候,爲了得到匹配速度的提升,值得花費一些時間對其進行一些額外的分析。僅僅適用於非錨定模式的匹配(即沒有單獨的固定開始字元)。
- U (PCRE_UNGREEDY):使量詞預設為非貪婪的,通過量詞后緊跟? 的方式可以使其成為貪婪的。同樣可以使用模式內修飾符設定 (?U) 進行設定,或者在量詞后以問號標記其非貪婪(比如.*?)。
- X (PCRE_EXTRA):打開了 PCRE 與 perl 不相容的附件功能。模式中的任意反斜線後就 ingen 一個沒有特殊含義的字元都會導致一個錯誤,以此保留這些字元的向後相容性。預設情況下,在 perl 中,反斜線緊跟一個沒有特殊含義的字元被認為是該字元的原文。
- J (PCRE_INFO_JCHANGED):內部選項設定(?J)修改本地的PCRE_DUPNAMES選項。允許子組重名,(譯註:只能通過內部選項設定,外部的 /J 設定會產生錯誤。)
- u (PCRE_UTF8):模式和目標字串都被認為是 utf-8 的。無效的目標字串會導致 preg_* 函式什麼都匹配不到;無效的模式字串會導致 E_WARNING 級別的錯誤。HP 5.3.4 後,5位元組和6位元組的 UTF-8 字元序列被考慮為無效。以前就被認為是無效的 UTF-8。
常見的正規表示式:
- 日期:
^(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次,中間為數字重複兩次,末段為數字重複兩次。
- 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個以上,含@,@之後被.分成兩段落以上。
- 用戶密碼:
^[a-zA-Z]\w{5,17}$,開頭必須為大小寫字母,跟著5到17位的字母或數字或底線。
^(?=^.{8,}$)((?=.*[A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z]))^.*$,先正向預查長度必須有八碼,再正向預查:是否含數字或字母、是否含小寫字母、是否含大寫字母,其他條件則不太管,只要有一個字元就好。
- 只能輸入漢字:^[\u4e00-\u9fa5]{0,}$,一到龥等20901個漢字。
- 網址:^((http|https|ftp):\/\/)?([\w-]+\.)+[\w-]+(\/[\w-.\/?%&=~+]*)?$,開頭須三協定之一,並且跟://,但協定也可以省略;帶.的字串須一次以上,之後再跟一個字串,最後面加「/路徑」若干次,其中須限網址列許可之諸字元。
- 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]?))*$。
- 電話號碼:^(\d{3,4}-)?\d{7,8}$。適用”XXX-XXXXXXX”、”XXXX-XXXXXXXX”、”XXX-XXXXXXX”、”XXX-XXXXXXXX”、”XXXXXXX”和”XXXXXXXX”。
- 驗證中國身份證號(15 位或 18 位數字):^\d{15}|\d{18}$。
- 信用卡檢查:^(?: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})*$
四、陣列
(一)陣列值
- $陣列名=array(值一,值二,值三…);完全等價於這一種寫法:$陣列名=array(0=>值一,1=>值二,2=>值三…);兩者元素序相同,元素之註標索引也相同。
- $陣列名=array(值一,值二,值三…);不完全等價於另一種寫法:$陣列名=array(1=>值二,0=>值一,2=>值三…);兩者註標索引雖相同,但元素序不同。
$陣列名=array(1=>值二,0=>值一,2=>值三…);的$陣列名[0]還是「值一」,但是已是此陣列的第二個元素,第一個元素已經是「1=>值二」了。
- $陣列名[0]=值一; $陣列名[1]=值二; $陣列名[2]=值三;,
- 將值指給一個原先並不存在的陣列元素,將建立一個新元素。如陣列原有四個元素(標註0-3),你卻使用標註6,則標註4,5的元素值為null,標註6用你指的值,變成七個元素。
- $陣列名=range(1,10);將1到10派給陣列。
- 多維:$陣列名=array(array(…),array(…),…);其元素以$陣列名[i][j]代表,餘類推。
- 多維:$陣列名=array(array(引一=>值一,引二=>值二,引三=>值三…),…);其元素以$陣列名[i][引數]代表,餘類推。
- for($i=0;$i<某數;$i++){while(list($key,$value)=each($陣列名)){echo "|$value";}echo "<br>";},將上項二維陣列逐行印出。
- 陣列間不知如何比大小,所以多元陣列,很難排序,只能用usort()自行定義排序p83。
(二)陣列之索引
- 凡陣列之元素必有索引(key)與值(value)。
- 索引可為註標索引,key為數值,不加引號;索引可為字串索引,key為字串,加引號。
- 標註不等於元素序。
甲、註標索引陣列
- 在指定元素時,同時指定key和value,寫成0=>值一。key可自由指定,但key相同算一個元素,且以後面設定的值為值。註標如果不連續,缺註標處就沒元素,count元素個數時不算,也無法用註標取值。
- 如果給元素時,只給值,沒給key,預設key為註標,PHP系統會自派key給元素,從0開始派,已被其他元素用掉的註標跳過;依元素序派,已有key的元素跳過。如array(1=>200,0=>100,400,3=>300),其中400會被派2為key,而元素序在100之後300之前。
- 按索引找不到元素值時,只送出空值,不會有錯誤或警告訊息,程式也照樣執行。
乙、字串索引陣列(又稱雜湊Hash、組合陣列、關聯式陣列)(
- $雜湊名=array('引一'=>值一,'引二'=>值二,'引三'=>值三…);
- $雜湊名['引一']=值一; $雜湊名['引二']=值二; $雜湊名['引三']=值三;
- 字串索引的元素,用標註是找不出值的。
丙、註標字串混合索引陣列
- key有引號是字串索引,key沒有引號是標註索引。
- 如果給元素時,只給值,沒給key,預設key為註標,PHP系統會自派key給元素,從0開始派,已被其他元素用掉的註標跳過;依元素序派,已有key的元素跳過。如array('aa'=>200,0=>100,400,'3'=>300),其中400會被派1為key,而元素序在100之後300之前。
- each($陣列名)傳回的四個元素就是混合索引,依序為(1=>元素值,'value'=>元素值,0=>元素索引,'key'=>元素索引),為的是讓人又可以用註標取值,又可以用字串索引取值。
- mysql_fetch_array(結果ID)取回2N(N為欄數)個元素的陣列也是混合索引,依序為(註標=>欄值,'欄名'=>欄值,註標=>欄值,'欄名'=>欄值…),為的是讓人又可以用註標取值,又可以用字串索引取值。
(三)陣列函數
- in_array(元素,$陣列名):檢查陣列中是否有此一元素。
- array_search(值, $陣列名,[TRUE]):PHP 4 >= 4.0.5,找陣列中之值,找到傳回其key,找不到4.2.0之前傳回NULL,之後傳回FALSE。第三參數為TRUE時,還要檢查陣列中元素的型別和欲找之值符不符。
- reset($陣列名):將指標移到第一個元素並傳回。
- end($陣列名):將指標移到最後一個元素並傳回。
- next($陣列名):先將指標移到下一個元素,再傳回新的元素。
- prev($陣列名):先將指標移到上一個元素,再傳回新的元素。
- current($陣列名):傳回陣列中目前的元素。
- pos($陣列名):傳回陣列中目前的元素值,就是current()。
- each($陣列名):針對陣列目前的元素,傳回(0=>元素key,1=>元素值,'key'=>元素key,'value'=>元素值)等四個元素構成的陣列;並將指標移到下一個元素。如$A=each($陣列);,則$A[0]和$A['key']為目前元素的key,$A[1]和$A['value']為目前元素的值。
- 如此元素本身為一陣列,其值為'Array',$A[1]和$A['value']傳回'Array'這個字串。
- 如此元素為某「字串索引陣列」的一個元素,$A[0]和$A['key']傳回索引字串,$A[1]和$A['value']傳回元素值。
- 如此元素為某「非字串索引陣列」的一個元素,$A[0]和$A['key']傳回元素key,一般為元素序,$A[1]和$A['value']傳回元素值。
- key($陣列名):傳回目前元素的key。
- list($變數名1,$變數名2…)=$陣列名;將陣列中的各個元素派給一系列的變數。
- list($變數名1,$變數名2)=each($雜湊名);將陣列中目前元素的key和值派給兩個變數。
- while($變數名=each($雜湊名)){echo $變數名["key"];echo "-";echo $變數名["value"];echo "
";}:迴圈中會將雜湊中每一個元素的引數及值都列出來。
- while($變數名=each($雜湊名)){echo $變數名[0];echo "-";echo $變數名[1];echo "
";}:同上。
- while(list($變數名1,$變數名2)=each($雜湊名)) echo "$變數1-$變數2
":同上。
- range(小值,大值):產生連續整數陣列。
sort、rsort、asort、arsort、natsort、natcasesort、ksort、krsort、usort、uasort、uksort均改變原陣列排序,並且不會傳回陣列。所謂改變排序是指影響的是reset、end、next、prev、pos的順序。
- sort($陣列名):洗去索引(不管註標還是字串索引),按各元素值的ASCII值或數字大小升冪排序,重派一套註標索引。
- rsort($陣列名):洗去索引,按各元素的ASCII值或數字大小逆向排序,原陣列改變排序。
- asort($雜湊名):維持索引和元素的對應關係(不管註標還是字串索引),按各元素的「值」排序。
- arsort($雜湊名):維持索引和元素的對應關係,按各元素的「值」逆向排序。
- natsort($陣列名):維持索引,自然排序,會分離出字母中的數字,然後按數字「大小」排,2是排在1之後,不是1、10、11…之後。原陣列改變排序。
- natcasesort($陣列名):自然排序,不分大小寫。原陣列改變排序。
- ksort($雜湊名):按各元素的「引數」排序。
- krsort($雜湊名):按各元素的「引數」逆向排序。
- usort($陣列名,自訂比較函式之函式名):自行定義排序,函式名加引號,洗去原索引。p83。
- uasort($陣列名,自訂比較函式之函式名):自行定義排序,函式名加引號,維持原索引。
- uksort($陣列名,自訂比較函式之函式名):自行定義函式,依索引排序,函式名加引號,維持原索引。
- shuffle($陣列名):隨機排序(洗牌法)。
- array_reverse($陣列名):產生一個新陣列但次序相反。
- array_merge($陣列名,$陣列名,…):合併諸陣列。
- array_push($陣列名,新元素):把新元素加到陣列最後一個元素,元素個數加一。
- array_pop($陣列名):取出並傳回陣列最後一個元素,元素個數少一。
- array_map(函式,陣列1,[,陣列2...]):將陣列1,2的諸元素代入函式,得到一個新陣列。
- array_walk($陣列名,自訂函式,可選用之函式參數):陣列元素之字串處理函式。
- array_keys(陣列):取回陣列所有元素之索引,成為新陣列。新陣列為註標索引(原陣列可能為字串索引)。
- array_values(陣列):取回陣列所有元素之值,成為新陣列。新陣列為註標索引(原陣列可能為字串索引)。
- array_sum(陣列):計算並傳回陣列中所有值的和。
- $陣列名=file("路徑檔名"):將檔內資料一行為一元素存入陣列。
- count($陣列名):計數元素個數。
- sizeof($陣列名):計數元素個數,同上。
- value($陣列名):傳回雜湊,key是陣列中的單一值,value是各單一值在陣列中的出現次數(頻率)。
- extract($雜湊名,可選用的淬取型別,prefix字串):把每一key全部變成變數,變數名是key,變數值是其value。淬取型別:
- EXTR_OVERWRITE:當重覆發生時,覆寫。
- EXTR_SKIP:當重覆發生時,略過。
- EXTR_PREFIX_SAME:當重覆發生時,產生新變數容納新值,變數名為"$prefix字串_重覆之key"。
- EXTR_PREFIX_ALL:全部取新變數容納新值,變數名為"$prefix字串_重覆之key"。
- 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因為沒有任何變數名相符,所以沒作用。
- max(許多數值或陣列):傳回諸數值中或陣列中,數值最大者。如:max(2,3,1,6,7)傳回 7 ;max(array(2, 4, 5))傳回 5 。
- min(許多數值或陣列):傳回諸數值中或陣列中,數值最小者。如:min(2,3,1,6,7)傳回 1 ;min(array(2, 4, 5))傳回 2 。
五、類別與物件
(一)定義類別
class 類別名{ // 定義一個類別(class)
var $屬性1; // 類別內本地變數為屬性
var $屬性2; // 類別內函式為方法
function 類別名(){ // 方法名若為類別名,當產生物件時就先執行此方法
echo "start!!";
}
function 方法2(){
echo $this->屬性1+$this->屬性2; // 類別內稱自身物件為this,取物件之屬性或方法:物件名->
}
}
- class 子類別 extends 父類別 {}:子類別擁有父類別的全部屬性和方法,可以進一步修改原有屬性和方法,也可再增加屬性和方法。
- 類別::方法:不用new物件,直接執行類別中的某方法。
- 物件的屬性不一定要在類別中定義,也可以在物件形成後再用「$物件->屬性=值;」來添加。
- 在類別定義內用this直接引用物件內其他屬性及方法做事,很獨立也很方便。
- $this->xxx為屬性,用動態變數代表函式名時,不能使用 $$this->xxx() 或 ${$this->xxx}(),必須分兩行撰寫:「$temp=$this->xxx;$temp();」。但可以使用 $this->$xxx() 。因為 $this 已是一個須代入物件名稱的變數。
(二)重要提示
- 有一預設的類別StdClass毋須定義,「new StdClass;」等價於「(object)null」。可以不去定義類別先產生空物件後,再用「$物件->屬性=值;」去添加此物件的屬性。
- 使用物件的方法和屬性時,方法名和屬性名可以使用變數以增加彈性,如「$o->$a」、「$o->$b()」。
六、參照
(○)觀念
記憶體上的位置 記憶體上的資料
↓ ↙
變數表:
$b參照$a
- 參照是指「指定位址上的對應資料,包含型別和值」。
- 指標型的資料:變數、物件、函式傳回值,才可以直接使用參照。參照後其資料型別與被參照者的資料型別一樣。
(一)三種可以使用參照的資料
- 參照變數:「$b = & $a;」$b是參照變數,PHP存取參照變數時,會存取記憶體位置上對應的資料。所以當$a變動時,$b也跟著變動;而$b變動時$a也跟著變動。
- 物件:
- PHP4時,一new 類別就產生一個物件,此時用「$bar=new fooclass();」會再拷貝一個物件然後指派給$bar;而「$bar=&new fooclass();」則讓$bar成為參照變數,實際只產生一個物件。這樣能減少記憶體消耗和提高性能。
- PHP5時,只要等號右邊是物件,「=」便代表參照而非拷貝,和「=&」等價。要拷貝須用「= clone 物件」。此意味著,寫程式必須區別物件與非物件資料型態,降低了 PHP 的泛型能力,也造成了語言陷阱(trick)。
- 資源:「$bar=&mysql_query(…);」因為資源型的資料也是靠記憶體指標來存取,所以也可以用參照來節省資源。
※foo、bar、foobar是技術文件中常用的函式、類別或變數名,foo源於中文的「福」。
(二)傳址呼叫(Passing by Reference)函式
- 一般函式的引數不加&,稱為「傳值呼叫」。作法是在函式內拷貝一份變數,函式運算作用在拷貝變數上,不影響原變數。因為有變數的複製所以速度慢。
- 「function foo(&$var){$var++;} $a=5;foo($a);」將使$a的值由5變成6。foo($a)是直接將$a記憶體位址上的變數內容,直接交給函式操作(加1)。因為沒有變數的複製所以速度快。注意在函式呼叫時沒有參照符號,只有函式定義中有。
- 在傳址呼叫函式內部,操做的是位址上面的內容,無法對位址進行存取和操作。
「$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。
- 送給傳址呼叫的引數除了不能是非指標型的6類實字之外,可以是其他指標型資料如變數。如要傳非指標型的實字,可以先將用派值敘述將實字派給變數,再將此變數送給傳址呼叫:(例子中的foo是一個傳址呼叫函式,function foo (&$var){…})
- 送變數:例如foo($a)。
- 送派值式:如foo($a = 5),先把5派給變數$a,再把$a代入函式。
- 送New 語句:例如 foo(new StdClass)。
- 另一函式的傳回值。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());」
以下方式不合法:
(三)函數傳回參照(Returning References)
- PHP4後期,所有函式回傳值均帶有記憶體位址及其內容,均可以用於傳值呼叫與傳址呼叫。所以已經不再需要在定義函式時,在函式名稱前加「&」。
- 早期:定義時如果函式名加了&,則函式傳回的是指定位址及其位址上的內容,即參照。這樣傳回的參照才能用於傳址呼叫,讓傳址呼叫函式直接對位址上的內容進行操作,省去複製變數,提升效能。
(四)取消參照
unset 一個參照變數,只是斷開了變數名和變數內容之間的綁定。這並不意味著變數內容被銷毀了。例如:
「$a=1;$b=&$a;unset ($a);」不會 unset $b,只是 $a。過程如下:
- 變數表中記下變數名a及其位址,並在此位址上放入1。
- 變數表中增加變數名b,其位址抄自a變數的位址。
- 刪去變數表中的a變數。
(五)其他參照
- 宣告一個全域變數「global $var;」等價於「$var =& $GLOBALS["var"];」,這意味著 unset $var 不會 unset 全域變數。
- 在一個物件的方法中,$this 永遠是呼叫它的物件的參照。
肆、控制結構
○、敘述區塊
- 敘述區塊:{}中間放可執行的的敘述。區塊結束處不必加';',但區塊內每個動作末尾均要加';'
- 單行條件:當敘述區塊只有一道敘述時,可省略{}。
一、if
- if(條件一){做一}elseif(條件二){做二}elseif(條件三){做三}…else{做其他}
二、switch
- switch(變數)
{case 值一 : 做一;break;
case 值二 : 做二;break;
case 值三 : 做三;break;…
default :做其他;break;
}
-
三、迴圈while
- while (條件) {合條件時做的事}
- while可以用來設計無窮迴圈,檢查錯誤,或要求直到做對為止。
- do{…}while(條件):先至少做一次,合條件繼續做。
- while (條件) {合條件時做的事}
- while ($xxx=each($陣列)) {每個元素做一輪,用$xxx[0]或$xxx['key']代表每個元素的鍵,用$xxx[1]或$xxx['value']代表每個元素的值;}
四、for
- for(執行敘述;條件;反覆敘述){…}:先做執行敘述,再判斷條件,合條件則做{}中及反覆敘述。
- for (設初值;條件;設下一值) {合條件就做,做到不合條件} 等價於 設初值;while(條件){做;設下一值}
- for($num2=1;$num2<=5;$num2++){echo $num2."<br>";}
五、foreach
- 陣列中每個元素做一輪。
- foreach($陣列 as 變數代表元素的值){使用前面的變數制作敘述;}
- foreach($陣列 as 用變數1代表元素的鍵=>用變數2代表元素的值){使用前面的變數製作敘述;}
- 和while ($xxx=each($陣列)) 比較,foreach可以用一個變數名稱代表元素值,也可用兩個變數名稱代表元素的鍵和值;而while只要用掉一個變數名稱,就能代表元素的鍵和值。特別是只要用一個變數名稱代表元素的鍵時,只能用while。
- 自php 5 起,foreach 還可以遍曆物件內的諸子物件。
- foreach 不支援用「@」來抑制錯誤資訊的能力。
六、控制敘述
- continue;跳過迴圈中以後的部分,跳到迴圈頭再進行條件判斷。
- break;跳出迴圈由迴圈的下一道敘述開始做。
- exit;跳離開PHP行程。
伍、載入程式及定義函數
- include("含程式之檔名"):是include被執行到才會執行載入動作。有傳回值,可以通知其他程式的其他部分,載入是否成功。
載入順位如下:
- 完整的路徑+檔名
- 只有檔名無路徑:找 include_path 指定的目錄
- 只有檔名無路徑:找檔案所在的目錄
- 只有檔名無路徑:找目前工作目錄
都找不到發出一條警告(E_WARNING)。
- require("含程式之檔名"):是母程式被解析是就會執行載入動作。
- include_once("含程式之檔名")、require_once("含程式之檔名"):只載入一次。
require | include |
母程式被解析是就會執行載入動作 | 被執行到才會執行載入動作 |
出錯時產生 E_COMPILE_ERROR 級別的錯誤 | 有傳回值,可以通知其他程式的其他部分,載入是否成功 |
引入檔有錯,會顯示錯誤,立刻終止程式,不再往下執行 | 引入檔有錯,會顯示警告,不會立刻停止 |
陸、檔案
- 檔案代碼=fopen("檔名","w"):開檔,並傳回檔案代碼。指定用途r為讀,w為重寫,a為接著寫,r+,w+,a+為可讀寫,b指定為二進位檔,這是當作業系統的文字及二進位檔不同時採用,unix不需要。
- 檔案代碼=popen("檔名","w"):單向開檔,並傳回檔案代碼。只能用於讀或寫,指定用途r為讀,w為重寫。
- fread(檔案代碼,讀取位元組數):讀回指定長度的位元組或到檔尾 EOF(省略長度時)。
- 檔案如果未鎖定,即使某甲開檔了,持續寫入中,某乙都可以再對同一檔案進行寫入,使檔案變成兩個人寫入的交雜(像麻花一樣)。即使他們之間相互破壞也可以,要管必須由寫程式的人構思去管。這個特性使多行程共用日誌檔成為可能。
例如:某甲啟動「$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。
- fgets(檔案代碼,讀取位元組數):從檔案指標所指的行,並從該行傳回指定長度;未指定長度時傳回字串長度為行的長度減一,不含換行。
如檔案代碼指向 php://stdin 在命令列模式下會等待使用者輸入;但在瀏覽器下不會等待輸入。
- fwrite(檔案代碼,字串[,長度指標]):寫入字串。
- fputs(檔案代碼,字串[,長度指標]):將字串寫到檔案指標處。
- fclose(檔案代碼):關檔,把檔案代碼還給系統。
- pclose(檔案代碼):關檔,把檔案代碼還給系統。配合popen()使用。
- filesize(檔名):傳回檔案位元組數。傳回值放在快取,非常省資源。
- readfile(檔名):傳回檔案位元組數,並將檔案內容送至標準輸出裝置,若有錯誤傳回 false。檔名可用http://、ftp://
- file(檔名):傳回陣列,每元素為檔中一行。檔名可用http://、ftp://。
- 檔案指標函數: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指令清單的扼要解說與範例。
- 函式是整合諸敘述的算符。
- 定義函式:function 函式名 ($引數[=初值],&$引數){含$引數之諸敘述}。函式名不可用數字開頭,函式名不可以用保留字如「list」,函式名可以使用中文,可以使用變數。函式名之前可以加&,使傳回值為參照供另一個傳址呼叫函式之用。但PHP4後期已經改為所有函式的傳回值均為指標型資料(帶記憶體位址),所以在函式名之前加&已無必要。
引數前不加&為傳值呼叫,在函式內複製一個變數,函式對此變數進行操作,函式結束收回變數空間。引數前加&,為傳址呼叫,不必在函式內複製一個變數,而是讓函式直接操作位址上的內容。所以引用函式時傳入的資料須是指標型的資料。如果要傳入實字(非指標)要先轉化成變數(指標),如foo($a=5)。
傳址呼叫會改變傳入變數的值,要確定對該變數進行操作時才應使用。
引數為物件或陣列時,傳址呼叫能有較大的好處;引數為變數但非物件或陣列時,好處較小;引數為實字時,傳址呼叫沒有好處。
傳值函式 | 定義時引數前不加& | 不影響輸入值 | 慢 | 函式內只能操作複製的輸入值變數,不能操作輸入值的內容或指標 |
傳址函式 | 定義時引數前加& | 直接改變輸入值內容 | 快 | 函式內只能操作輸入值的內容,不能操作輸入值的指標 |
- 引用函式時,函式名可用變數$xxx()、$this->$xxx(),函式引數中的預設值不可用函式,可用變數。
- 遞迴函式:function 函式名 {… 函式名()…},時一定要設定停止點,不然會陷入無窮迴圈。
- 連結MySQL
- mysql_pconnect("機器", "使用者", "通行碼"):連上MySQL。連成,傳回連結ID,失敗傳回false。傳回的是一個「持續連結」,不會在程式結束或mysql_close()時結束。下次再用pconnect,會先去看有沒有已開啟的持續連結可用,如有就用,不會再去開新的持續連結。
- mysql_connect("機器", "使用者", "通行碼"):連上MySQL。連成,傳回連結ID,失敗傳回false。傳回的是「非持續連結」,連結在程式結束或mysql_close()時結束。misqli為mysqli_connect("機器", "使用者", "通行碼","資料庫名");
- mysql_close(連結ID):關閉一個「非持續連結」。沒啥用,持續連結不能關,非持續連結到程式結束時會自動關閉。mysqli為mysqli_close(連結ID)。
- mysql_select_db("資料庫名",[連結ID]):使用資料庫,可指定資料庫連結,如果沒指定,會使用最後一個被開啟的連結。如果沒指定連結,也沒有已開啟的連結,會去叫mysql_connect()來開啟連結。
- $result = mysql_query(命令字串,[連結ID]):下命令給MySQL,並將結果傳回給指定變數。可指定資料庫連結,如果沒指定,會使用最後一個被開啟的連結。如果沒指定連結,也沒有已開啟的連結,會去叫mysql_connect()來開啟連結。傳回結果ID,失敗時傳回false。mysqli為mysqli_query(連結ID,命令字串)
- $result = mysql_db_query(資料庫名,命令字串,[連結ID]):mysql_select_db()和mysql_query()的組合。
- mysql_insert_id([連結ID]):傳回AUTO_INCREMENTED欄位最所產生的id,如果省略連結ID則假定是最後所開啟的連結。如果AUTO_INCREMENTED的欄位是bigint(64bit)會因為傳回的位數太大而出錯,php的整數只到32bit,此時就要用MySQL自己的函數 LAST_INSERT_ID([expr]) 來取值。
- mysql_num_rows(結果ID):查傳回的筆數。
- mysql_data_seek(結果ID,跳過筆數):將筆指針下移幾筆,之後用mysql_fetch_array,取出的是下移後的首筆。如果結果中本沒就沒筆,會傳回false。
- $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()。
- $row = mysql_fetch_assoc(結果ID):結果集合若有n欄,取出結果集合中的一筆資料,丟進一個陣列,此陣列有n個元素,('欄名'=>欄值,'欄名'=>欄值,'欄名'=>欄值…)。用$row['欄名']…來取各欄之值。
- $row = mysql_fetch_row(結果ID):結果集合若有n欄,取出結果集合中的一筆資料,丟進一個陣列,此陣列有n個元素,(0=>欄值,1=>欄值,2=>欄值…)。用$row[0],$row[1]…來取各欄之值。
- $row = mysql_fetch_object(結果ID):取出結果集合中的一筆資料,丟進一個物件,每一欄是一性質。用$row->欄名,來取各欄之值。
- $row = mysql_result(結果ID,筆次,'欄名'):取出結果集合中的某欄、某筆資料。筆次是結果集合中的筆次,不是資料表中的筆次。
- mysql_affected_rows():最後一次查詢,MySQL受影響的筆數。
- mysql_num_fields (結果ID):共幾欄。
- mysql_field_table(結果ID,第幾欄):查該欄所屬的資料表,如果該表有代稱,傳回的是代稱。
- mysql_field_name (結果ID,第幾欄):查欄名。
- mysql_field_type (結果ID,第幾欄):查欄型。
- mysql_field_len (結果ID,第幾欄):查欄長。
- 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
|
timestamp | timestamp(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查得到。
- mysqli連結沒有 mysqli_field_name 等函式,是用 mysqli_fetch_field_direct(結果ID,第幾欄) 得回物件,此物件的 name 屬性為欄名、 table 屬性為表名,詳述如下:
- name - 欄名
- orgname - 原始的欄名(如果指定了別名)
- table - 表名
- orgtable - 原始的表名(如果指定了別名)
- def - 該欄的預設值
- max_length - 欄的最大寬度
- length - 在表定義中規定的欄寬度
- charsetnr - 欄的字符集號
- flags - 欄的位標誌
- type - 用於欄的數據類型
- decimals - 整數欄,小數點後的位數
- mysql_free_result(結果ID):放掉儲存這個結果的記憶體。mysqli為mysqli_free_result(結果ID)。
- mysql_create_db("資料庫名",[連結ID]):建立資料庫,可指定資料庫連結,如果沒指定,會使用最後一個被開啟的連結。成功傳回true,失敗傳回false。
- mysql_drop_db("資料庫名",[連結ID]):刪除資料庫,可指定資料庫連結,如果沒指定,會使用最後一個被開啟的連結。成功傳回true,失敗傳回false。
- mysql_error():傳回與 MySQL 互動最近的錯誤訊息。
- 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 版本過舊,不具此功能。
- mysqli_connect_errno(連結ID):mysqli 連結的錯誤代碼。省略連結ID則指最近一次連結。沒錯傳回 0 。
- mysqli_connect_error(連結ID):mysqli 連結的錯誤訊息。
- 連結DBASE
- 編輯資料表最佳方式,還是以Excel編dbf檔,可以靈活搬移筆。
- 在windows下:
- 找到php\extensions下,確實有php_dbase.dll。
- 在windows下找到php.ini。
- 改extension_dir = ./ =>extension_dir = c:\php\extensions
- 改;extension=php_dbase.dll,將行首分號去掉,改抑制為啟動。
- 重新啟動apache。
- 連結Socket
- 要--enable-sockets,才有諸socket常數及函式可用,此點可在phpinfo()中Configure Command欄查出來。如美國的GoDaddy.com租賃網站就不能用,而戰國策可用。
- $socket=socket_create(AF_INET, SOCK_STREAM, SOL_TCP);:建立一個插頭。
- socket_connect($socket,'ip',port):該插頭對伺服器建立一個連線。
- $command="GET /程式?變數 HTTP/1.0\nhost:伺服器\n\n";:造一個 HTTP 請求,第一行交代通道、目的程式、HTTP版本,三者用空白間隔開;然後換行交代伺服器(無http://);然後換行兩次,表示請結束。
- socket_write($socket,$command,strlen($command)):經通道送一個命令給伺服器。
- socket傳回值時,通常一次只能讀2k,所以要用迴圈讀取。如:while($response=socket_read(socket連線代碼,1024)){$temp.=$response;}
- socket_close($socket):關閉連線
- socket_bind($socket,'ip',port):和socket_connect功能類似,但卻是用來配合socket_listen()。
- socket_listen($socket[,佇列數]):可以開始聽取客戶端請求,不一定會接受(可能請求太多,無法每個都接受)
- socket_accept($socket):接受客戶端連線進來,並分配一個代表客戶端的代碼。如果沒有客戶端要連進來,就等到有,或出現錯誤為止。
- 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) 。
- 用 socket 編寫一個簡單的HTTP Server,請參考:https://codertw.com/程式語言/110155/
- 檔案格式轉譯函式,如:JSON,CSV
- json_decode(json字串[,傳回陣列,解析的遞迴深度(預設512層),位掩碼]):對 JSON 格式的字符串進行解碼。
json字串,代入實字時,最外層必須以單引號(')包絡區隔,內部使用雙引號區分字串;不能以雙引號(")包絡區隔,內部使用單引號(')區分字串。代入變數則內部須使用雙引號區分字串。
傳回陣列若true,傳回陣列,若false傳回物件,預設為假(false)。
位掩碼(bitmask),預設0即:將大整數轉換為浮點數。目前的選用值只有 JSON_BIGINT_AS_STRING ,若選用,大整數視為字串,不視為浮點數。
- 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
- 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
- fgetcsv(檔案代碼[,行的最大長度,分界符,環繞符]):從檔案指針處中讀入一行並解析 CSV 字串傳回陣列;出錯或碰到文件結束時傳回FALSE。
行的最大長度必須大於 CVS 文件內最長的一行,預設為0,即長度沒有限制,但會影響執行效率。
分界符(只允許一個字符)預設為逗號「,」。
環繞符只允許一個字符)預設為雙引號「"」。
常用的讀取手法「while(!feof(檔案代碼)){$陣列[]=fgetcsv(檔案代碼);}」
- 時間
- time():1970年到當下的秒數再減時區秒數。
- mktime(時,分,秒,月,日,年):1970年至此時的秒數再減時區秒數。
- 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"
|
---|
| %% | 一個文字「%」
|
---|
- 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())可求出目前的系統時間。
- int checkdate(int月,int日,int年):檢查日期是否有效,true有效,false無效。可查閏年。
- 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'
- sleep(秒數):等待幾秒。javasript無類似的函式,要使用者自己寫:
function sleep(numberMillis){
var now=new Date();
var exitTime=now.getTime()+numberMillis;
while(true){now=new Date();if(now.getTime()>exitTime) return;}
}
- time_nanosleep(秒數,納秒數):等待幾秒加幾納秒。1納秒為十億分之一秒。兩參數均須為整數。本函數未在 Windows 平台下實現。
- 寄信
- mail(給誰,主旨,內容,額外標頭):傳回布林值,寄mail。前提是必須使用一個不用驗證即可寄信的 SMTP 。
- 加附檔,先將附檔讀入變數 $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";
- 收信(IMAP,已打開的某個IMAP流,在本段中簡稱為$imap)
- imap_8bit(字串) - 將8位元字串轉換為帶引號的可打印字串
- imap_alerts - 返回發生的所有IMAP警告郵件
- imap_append - 將字串附加到指定的郵箱
- imap_base64(字串) - 解碼BASE64編碼的文本
- imap_binary(字串) - 將8位元字串轉換為base64字串
- imap_body - 閱讀郵件正文
- imap_bodystruct - 讀取特定郵件的指定正文部分的結構
- imap_check - 檢查當前郵箱
- imap_clearflag_full - 清除郵件標誌
- imap_close($imap,[常數CL_EXPUNGE]) - 關閉IMAP流。如給出常數CL_EXPUNGE,則在關閉連結前先清理電子信件信箱。
- imap_create - imap_createmailbox的別名
- imap_createmailbox - 創建一個新郵箱
- imap_delete($imap,幾封信) - 將郵件標記為從當前郵箱中刪除
- imap_deletemailbox - 刪除郵箱
- imap_errors - 返回發生的所有IMAP錯誤
- imap_expunge - 刪除標記為刪除的所有郵件
- imap_fetch_overview - 閱讀給定郵件標題中郵件的概述
- imap_fetchbody($imap,區段序,區段數目) - 獲取郵件正文內的指定區段
- imap_fetchheader - 返回郵件的標題
- imap_fetchmime - 為郵件的特定部分獲取MIME標頭
- imap_fetchstructure($imap,資訊數) - 讀取特定郵件的結構
- imap_fetchtext - imap_body的別名
- imap_gc - 清除IMAP緩存
- imap_get_quota - 檢索每個郵箱的配額級別設置和使用率統計郵件
- imap_get_quotaroot - 檢索每個用戶的配額設置
- imap_getacl - 獲取給定郵箱的ACL(存取權控制清單)
- imap_getmailboxes - 閱讀郵箱列表,返回每個郵箱的詳細郵件
- imap_getsubscribed - 列出所有訂閱的郵箱
- imap_header($imap,郵件數) - 讀取郵件的標題,省略郵件數,代表全部
- imap_headerinfo - imap_header的別名
- imap_headers - 返回郵箱中所有郵件的標題
- imap_last_error - 獲取此頁面請求期間發生的最後一次IMAP錯誤
- imap_list - 閱讀郵箱列表
- imap_listmailbox - imap_list別名
- imap_listscan - 返回與給定文本相匹配的郵箱列表
- imap_listsubscribed - imap_lsub的別名
- imap_lsub - 列出所有訂閱的郵箱
- imap_mail_compose - 根據給定的信封和正文部分創建MIME郵件
- imap_mail_copy - 將指定的郵件複製到郵箱
- imap_mail_move - 將指定的郵件移動到郵箱
- imap_mail - 發送電子郵件
- imap_mailboxmsginfo - 獲取有關當前郵箱的郵件
- imap_mime_header_decode - 解碼MIME標題元素
- imap_msgno - 獲取給定UID的郵件序列號
- imap_num_msg - 獲取當前郵箱中的郵件數量
- imap_num_recent - 獲取當前郵箱中最近郵件的數量
- imap_open(server,username,password) - 打開一個IMAP流(本段中簡稱$imap)到郵箱
- imap_ping - 檢查IMAP流是否仍處於活動狀態
- imap_qprint(字串) - 將帶引號的可打印字串轉換為8位元字串
- imap_rename - imap_renamemailbox的別名
- imap_renamemailbox - 將舊郵箱重命名為新郵箱
- imap_reopen - 重新打開IMAP流到新郵箱
- imap_rfc822_parse_adrlist - 分析地址字串
- imap_rfc822_parse_headers - 從字串解析郵件標題
- imap_rfc822_write_address - 根據郵箱、主機和個人郵件,返回格式正確的電子郵件地址
- imap_savebody - 將特定的正文部分保存到文件中
- imap_scan - imap_listscan的別名
- imap_scanmailbox - imap_listscan的別名
- imap_search - 此函數返回與給定搜索條件匹配的郵件陣列
- imap_set_quota - 為給定郵箱設置配額
- imap_setacl - 設置給定郵箱的ACL(存取權控制清單)
- imap_setflag_full - 設置郵件標誌
- imap_sort - 獲取和排序郵件
- imap_status - 返回郵箱的狀態郵件
- imap_subscribe - 訂閱郵箱
- imap_thread - 返迴線程郵件樹
- imap_timeout - 設置或獲取imap超時
- imap_uid - 此函數返回給定郵件序列號的UID
- imap_undelete - 取消標記為已刪除的郵件
- imap_unsubscribe - 取消訂閱郵箱
- imap_utf7_decode - 解碼已修改的UTF-7編碼字串
- imap_utf7_encode - 將ISO-8859-1字串轉換為修改後的UTF-7文本
- imap_utf8 - 將MIME編碼的文本轉換為UTF-8
- 數學
- bindec(二進位字串):二進位轉十進位。如:bindec('00110')。
- bin2hex(ASCII字串):二進位轉十六進位。如:bin2hex('chengdu')。
- octdec(八進位字串):八進位轉十進位。如:boctdec('010')。
- decbin(整數):十進位轉二進位。如:decbin(50)。
- decoct(整數):十進位轉八進位。如:decoct(50)。
- dechex(整數):十進位轉十六進位。如:dechex(50)。只能處理無符號整數,負整數會以無符號來處理。
- hex2bin(十六進位字串):十六進位轉二進位。如:hex2bin('6368656e67206475')。
- hexdec(十六進位字串):十六進位轉十進位。如:hexdec('that')會忽略t,h,傳回整數10。
- base_convert(數值字串,2~36間的整數(輸入值進位制),2~36間的整數(傳回值進位制)):任意進位制轉換,傳回字串。
- deg2rad(數):角度轉徑度。
- sin(徑度):正弦。
- abs(數):取絕對值。
- ceil(數):進位。
- floor(數):捨去小數。
- round(數,小數位數):四捨五入。
- pi():圓周率。
- sqrt(數):開平方。
- pow(底,次方):求次方值,底,次方可為非整數。如果次方是分數,即涉及開方,則底必須為非負數,如-1開三方即不允許,會回應NAN(並非一個數值)。此非為數學上的定義,同樣的情形Excel就許可運算。但負數開偶次,會得出i,PHP和Excel皆不允許。
- exp(數):取自然對數為底的次方值。
- log(數,底):對數,如省略底即為自然對數。
- log10(數):以10為底的對數。
- mt_rand(最小整數值,最大整數值):傳回介於兩值間的一個整數亂數,不指定範圍,則從0到常數RAND_MAX間找一亂數。使用馬其賽特旋轉 (Mersenne Twister) 演算法,比 libc 計算速度至少快四倍。實測值和 rand() 函式速度差不多。
- mt_srand(整數種子):設定亂數種子seed。無傳回值。
- rand(最小整數值,最大整數值):傳回介於兩值間的一個整數亂數,不指定範圍,則從0到常數RAND_MAX間找一亂數。
- srand(整數種子):設定亂數種子seed。無傳回值。
- 變數
- empty(變數們):傳回(01)變數是否為空值。
- gettype(變數們):傳回(字串)變數型態。
- get_defined_vars():傳回(陣列)所有變數。
- intval(變數們[, int base]):傳回整數值。
- is_array(變數們):判斷是否為陣列。
- is_bool(變數們):判斷是否為布林值。
- is_double(變數們):判斷是否為倍浮點數。
- is_float(變數們):判斷是否為浮點數。
- is_int(變數們):判斷是否為整數。
- is_integer(變數們):判斷是否為整數。
- is_long(變數們):判斷是否為整數。
- is_null(變數們):判斷是否為空值。
- is_numeric(變數們):判斷是否為數字或數字的字串。
- is_object(變數們):判斷是否為物件。
- is_real(變數們):判斷是否為實數。
- is_resource(變數們):判斷是否為資源。
- is_string(變數們):判斷是否為字串。
- isset(變數們):測試是否為存在。
- print_r(函式們):列出敘述句之資訊。
- unset(變數們[, mixed var [, ...]]):刪除變數。
- 函數處理
- function_exists(string function_name):檢查函數是否已經定義過。
- get_defined_functions():傳回所有已定義過函數。
- 類別和物件
- call_user_method_array(方法,物件[, array paramarr]):以陣列參數呼叫指定的方法。
- call_user_method(方法,物件[, mixed paramarr [, mixed ...]]):在一個指定的物件上呼叫指定的方法。
- class_exists(類別);檢查類別是否已經定義。
- get_class(物件):傳回物件中的類別名稱。
- get_class_methods(類別):傳回類別中方法的名稱。
- get_class_vars(類別):傳回類別預設的屬性。
- get_declared_classes():傳回聲明的類別的名稱。
- get_object_vars(物件):傳回物件的屬性。
- get_parent_class(物件):傳回物件的父類別名稱。
- is_subclass_of(物件,子類別):判斷物件是否屬於類別的子類別,如果物件 obj是屬於 superclass的子類別時,此函式會傳回 true,否則傳回 false。
- method_exists(物件,方法):檢查類別的方法是否存在。
- URL
- base64_decode(編碼字串):以MIME base64解碼。見字串函式。
- base64_encode(字串):以MIME base64編碼。見字串函式。
- parse_url(url字串):見字串函式。
- urldecode(字串):傳回解碼後的url字串。
- urlencode(字串):傳回url編碼字串。
- 檔案系統(待充實)
- dirname(路徑檔名):傳回完整的目錄名稱。如dirname(__FILE__)。
- basename(路徑檔名):傳回路徑檔名最後一個「/」之後的名字。如basename(dirname(__FILE__))。
- pathinfo(路徑檔名,常數):依四種不同常數傳回不同字串,可用常數如下:
- PATHINFO_DIRNAME:取得資料夾路徑
- PATHINFO_BASENAME:取得整個檔名(主+副)
- PATHINFO_FILENAME :取得主檔名
- PATHINFO_EXTENSION:取得副檔名
此函式遇多數的中文檔名、路徑名都沒問題,但對少數中文檔名、路徑名抓不到,如「菊」。所以還有以下幾種抓副檔名的方法,依執行速度排列如下:
- substr(strrchr($filename,'.'),1)
- substr($filename,strrpos($filename,'.')+1)
- preg_replace('/^.*\.([^.]+)$/D','$1',$filename)
- end(explode('.',$filename))
- $exts=split("[/\\.]",$filename);
$n=count($exts)-1;
$ext=$exts[$n];
- copy(來源檔名,目的檔名):複製檔案。copy完原檔案還是會在。
- chmod(檔名,權限):複製檔案。權限參數由 4 個數字組成:
- 第一個數字永遠是 0
- 第二個數字規定所有者的權限
- 第三個數字規定所有者所屬群組成員的權限
- 第四個數字規定其他所有人的權限
可能的值(如需設置多個權限,請對下面的數字進行總計):1(執行權限)、2(寫權限)、4(讀權限)。
- is_uploaded_file(暫存檔名):檢查檔案是不是由 HTTP POST 上傳的暫存檔。
- 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() 來處理上傳檔。
- unlink(檔名[,context]):刪除檔案。context引數是PHP 5.0.0 添加的,相關說明請參考 CXLI. Stream Functions 。delete(檔名)為無用的函式,不能做事。
- rmdir(目錄名):刪除目錄。欲刪除的路徑必須是空的目錄,且權限必須要合乎要求。發生錯誤則傳回 0。
- file_exists(檔名):檔案是否存在。
- is_dir(路徑):路徑是否存在,該路徑存在且為一個目錄,返回 true ,否則返回 false 。
- is_file(檔名):辨別檔名是否為正規的檔案。
- is_link(檔名):辨別檔名是否為連結。
- fileatime(檔名):檔案最後存取的時間戳記。
- filemtime(檔名):檔案最後寫入異動的時間戳記。
- filectime(檔名):檔案最後權限異動的時間戳記。
- filegroup(檔名):檔案所屬群組的id。
- fileowner(檔名):檔案所有者的id。
- fileinode(檔名):檔案實際存放的節點位址。
- fileperms(檔名):檔案的權限。
- filesize(檔名):檔案的大小(bytes數)。
- filetype(檔名):傳回file、dir、link、block、char、fifo、unknown等7種可能的值。
- 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」
- scandir(路徑):傳回路徑下的諸檔名組成之陣列,含「.」「..」。
- mkdir(路徑及目錄名,mode值,是否遞迴):建立目錄。mode預設值為0777。
- chdir(路徑及目錄名):變更PHP現在目錄到指定目錄。無法變更目錄時則傳回false,否則則傳回ture。
- dir(路徑及目錄名):製造一個物件,兩屬性,三方法。path屬性放輸入的路徑檔名,handle屬性放傳回的資源代碼。read()方法自資源代碼中取出一個檔案條目,close()方法繳還資源代碼,rewind()將指標調回目錄開始處。
例如「$d=dir(".");while($entry=$d->read()){echo $entry."\n";}$d->close();」
- opendir(路徑及目錄名):開啟一個目錄處理流程,取回資源代碼。如不能打開目錄傳回 FALSE 並產生一個 PHP 錯誤訊息。可以在 opendir() 前面加上「@」符號來抑制錯誤訊息的輸出。
- readdir(資源代碼):從目錄傳回下一個檔案條目的檔案名稱,傳回時不依照任何特殊順序。
例如 「$handle=opendir('.');while($file=readdir($handle)){echo $file."
\n";}closedir($handle);」
- closedir(資源代碼):繳還資源代碼。
- rewinddir(資源代碼):重設資源代碼指示的目錄流到目錄的開始處。
- $陣列名=file("路徑檔名"):將檔內資料一行為一元素存入陣列。
- 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');
- file_put_contents(路徑檔名,data,mode,context):逐byte將內容送入檔案
- 路徑檔名,必需。規定要寫入數據的檔案。如果檔案不存在,則創建一個新檔案。
- data,可選。規定要寫入檔案的數據。可以是字符串、陣列或數據流。
- mode,可選。可選。規定如何打開/寫入文件。可能的值:
- FILE_USE_INCLUDE_PATH
- FILE_APPEND
- LOCK_EX
- context,可選。是一套可以修改「資料流」行為的選項。若使用 null,則忽略。
- PHP選項與資訊
- 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 | 顯示全部資料,預設值 |
- 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:資料壓縮函式庫的相關設定。
- ini_get('設定項目'):傳回各設定項目之值。
- 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:')可以擴充預設載入路徑。
- ini_restore('設定項目'):回復預設值。
- 雜項
- constant(常數名稱):傳回常數值。
- define(常數名稱,值[, int case_insensitive]):定義常數名稱。
- defined(常數名稱):檢查常數是否存在。
- $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
- sha1(字串):傳回sha1雜湊值,用於線上金流。
- die(訊息字串):輸出訊息並終止程式。
- exit(訊息字串):輸出訊息後終止目前程式。同die。
- 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.這個 杯子 中裝有 咖啡.」
- get_browser([string user_agent]):識別使用者瀏覽器。
- uniqid(前置字元):依據當時的毫秒以及指定的前置字串產生一個獨一無二的字串。參數 prefix 為前置的字串,最多可達 114 字元。
- 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()並執行。
錯誤處理及記錄
- 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 中。
- error_reporting(int [錯誤碼]):指定PHP程式只需要回報的錯誤等級其他的一律忽略。參看常數一節,各種錯誤碼的含意。PHP4中預設值為E_ALL & ~E_NOTICE,即除注意以外的一切訊息均顯示,PHP3不支持位元操作,錯誤碼預設值為7。
- restore_error_handler():恢復先前的錯誤處理函數。
- set_error_handler(錯誤處理函式的函式名稱):指定使用者自定錯誤處理函數。此函式很重要,因為預設的錯誤處理函式會洩露出錯腳本的路徑、行數和原因。對駭客來說,路徑可是非常重要資訊。將PHP配置檔中的display_errors設置為Off是一種解決之道,自定錯誤處理函式,將原始的錯誤訊息過濾或重導向是另一種解決之道。
- trigger_error(錯誤訊息[, int error_type]):產生使用者自訂的錯誤、警告、注意訊息。可以與內建的錯誤處理器一同使用,也可以與由 set_error_handler() 函數創建的使用者自定義函數使用。
- user_error(錯誤訊息[, int error_type]):產生使用者等級的錯誤、警告、注意訊息。
繪圖
- header('Content-type:image/png或jpeg或gif'); 送出http header,通知以下輸出的圖。
- imagecreate(寬點數,高點數):開圖,傳回圖代碼。左上為原點。
- imagepng(圖代碼[,檔名]):送出png圖到瀏覽器或是檔案。
- imagegif(圖代碼[,檔名]):送出gif圖到瀏覽器或是檔案。
- imagejpeg(圖代碼[,檔名]):送出jpg圖到瀏覽器或是檔案。
- imagedestroy(圖代碼):還回 ImageCreate() 所產生圖代碼,省略也可不會怎麼樣。
- imagecolorallocate(圖代碼,紅值,綠值,藍值):配一色,傳回色代碼。
- imagecolortransparent(圖代碼,色代碼):將顏色轉為透明背景色,並傳回新的色代碼。
- imagestring(圖代碼,字型代碼,x座標,y座標,字串,色代碼):畫一水平字串。
- imagestringup(圖代碼,字型代碼,x座標,y座標,字串,色代碼):畫一垂直字串。
- imagettftext(圖代碼,字大小之像素值,從水平算起逆時鐘整數角度採360度制,起點x,起點y,色代碼,字型檔,輸出字串):用ttf輸出字串到圖中,常用於中文。
對red hat的linux,楷書在/usr/share/fonts/zh_TW/TrueType/bkai00mp.ttf,細明體在/usr/share/fonts/zh_TW/TrueType/bsmi00lp.ttf。
- imagesetpixel(圖代碼,x座標,y座標,色代碼):畫點。
- imageline(圖代碼,起點x,起點y,終點x,終點y,色代碼):畫直線。
- imagedashedline(圖代碼,起點x,起點y,終點x,終點y,色代碼):畫虛線。
- imageellipse(圖代碼,圓心x,圓心y,水平軸長,垂直軸長,色代碼):畫橢圓。
- imagearc(圖代碼,圓心x,圓心y,水平軸長,垂直軸長,起始角度,結束角度,色代碼):畫橢圓弧,角度是360度制,以右方水平為0度,順時鐘計算角度。
- 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」畫出餅狀圖輪廓。
- imagerectangle(圖代碼,角x,角y,對角x,對角y,色代碼):畫矩形。
- imagefilledrectangle(圖代碼,角x,角y,對角x,對角y,色代碼):矩形內部著色。
- imagepolygon(圖代碼,頂角座標陣列,頂角數,色代碼):畫多邊形,可能開口,可能封閉,封閉時首尾頂角座標相同。
- imagefilledpolygon(圖代碼,頂角座標陣列,頂角數,色代碼):多邊形著色。
- imagefill(圖代碼,x座標,y座標,色代碼):將該點區域著色。
- imagefilltoborder(圖代碼,x座標,y座標,邊界色代碼,著色代碼):在x,y座標點周圍,在邊界色的包圍範圍內,著上指定色。
- imageloadfont(字型檔名):載入使用者自訂的字型檔,其0-3bytes為檔案中字元的數目;4-7bytes為字型的啟始 ASCII 字元,例如從 ASCII 32 的空白開始;8-11bytes為字元的寬度,12-15bytes為字元的高度;16byte以後為各字元的位元值,也就是點陣的內容。
- imagepsloadfont(PS字型檔名):載入PS字型檔,傳回字型碼。
- imagepsfreefont(字型碼):還回字型碼及記憶空間。
- imagepstext(圖代碼,字串,字型代碼,字大小之像素值,前景色碼,背景色碼,左下角x,左下角y,文字間隔,單字間的緊密度,浮點數之角度,邊緣鋸齒狀修正等級範圍為4至16):畫PS字到圖中,傳回一維陣列四值,左下角座標及右上角座標。
- 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
- 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,目的圖路徑);
HTTP
- header(字串):送出http header。
- headers_sent():判斷標頭是否已送出。
- setcookie('變數名',變數值,存活到何時,有權存取之路徑,有權存取之網域,是否保密):由HTTP存在客戶端的變數,經由標頭傳送,在建立cookie還抓不到要換頁才抓得到。
FTP
- FTP上傳期間,如果是覆寫遠端的舊檔,上傳前會先刪掉遠端的舊檔,傳送完成或傳送中斷,遠端的檔案才會產生。所以上傳期間,遠端的目的檔案是不能讀寫的,因為不存在。很簡單的檔案讀寫鎖定機制。
- ftp_connect(string host [, int port]):開啟FTP連結。
- ftp_login(int ftp_stream, string username, string password):登入FTP連結。
- ftp_pwd(int ftp_stream):傳回目前的目錄名稱。
- ftp_cdup(int ftp_stream):回到父目錄。
- ftp_chdir(int ftp_stream,目錄):切換到指定的目錄。
- ftp_mkdir(int ftp_stream,目錄):建立新目錄。
- ftp_rmdir(int ftp_stream,目錄):移除目錄。
- ftp_nlist(int ftp_stream,目錄):傳回給予的目錄中檔案的列表。
- ftp_rawlist(int ftp_stream,目錄):傳回給予的目錄中檔案的詳細列表。
- ftp_systype(int ftp_stream):傳回遠端FTP伺服器的系統型態identifier
- ftp_pasv(int ftp_stream, int pasv):開啟或關閉被動模式。
- ftp_get(int ftp_stream, string local_file, string remote_file, int mode):從FTP伺服器下載檔案。mode,0是文字檔,1是二元檔。
- ftp_fget(int ftp_stream, int fp, string remote_file, int mode):從FTP伺服器下載檔案並且儲存到開啟的檔案。
- ftp_put(int ftp_stream, string remote_file, string local_file, int mode):上傳檔案到FTP伺服器。
- ftp_fput(int ftp_stream, string remote_file, int fp, int mode):從開啟的檔案上傳到FTP伺服器。
- ftp_size(int ftp_stream, string remote_file):傳回檔案的大小。
- ftp_mdtm(int ftp_stream, string remote_file):傳回檔案的最後修改時間。
- ftp_rename(int ftp_stream, string from, string to):將FTP伺服器上的檔案重新命名。
- ftp_delete(int ftp_stream, string path):刪除FTP伺服器上的檔案。
- ftp_site(int ftp_stream, string cmd):送出site命令給伺服器。
- ftp_quit(int ftp_stream):結束FTP連結。
安全執行外部命令
- EscaPeShellCmd(命令字串):將命令字串中可能騙過Shell而去執行另外一個命令的字元的「轉義」,如分號;,重定向>和從文件讀入<。
- EscaPeShellArg(命令參數):給定的字串兩邊加上單引號,並把字串中的單引號轉義,這樣這個字串就可以安全地作為命令的參數。
- `外部命令`:代表命令執行的結果。如:「echo "<Pre>";echo `ls -l`;echo "</Pre>";」。
- system(外部命令[,放回傳狀態碼的變數名]):執行外部命令並輸出返回結果。system()等函數要等命令的輸出結果後才返回,這肯定會引起PHP腳本的超時。解決的辦法是把命令的輸出用「>」重定向到另外一個檔或流中。
- exec(外部命令[,傳回結果陣列[,狀態碼的變數名]]):執行外部命令不輸出返回結果,而將返回結果的最後一行放進結果陣列的最後一個元素。回傳陣列可能放前個執行命令的回傳結果。
- Passthru(外部命令[,狀態碼的變數名]):執行外部命令不返回結果,而把結果原樣地直接輸出到標準輸出設備上。適合處理圖片流。如:
header("Content-tyPe: image/gif");
Passthru(".PPmtogif hunte.PPm");
- pOpen(外部命令,'w'或'r')。上面的方法只能簡單地執行外部命令,卻不能與外部命令互動。pOpen則打開一個管道來執行給定的外部命令,返回一個檔案控制碼,後續就可以持續對檔案控制碼讀和寫了,其操作宛如對待檔案。
與外部命令持續互動的例子:
$fP=@pOpen(外部命令,'w');
@fPuts($fP,用字串回應外部程式);
@Pclose($fP);
- 安全模式下,只有在特定目錄中的外部程式才可以被執行,對其他程式的調用將被拒絕。這個目錄可以在PhP.ini 檔中用safe_mode_exec_dir指定。
捌、設定
一、php.ini中的重要項目
(一)與檔案上傳相關(以群暉DS218+為例)
- 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');」。
- file_uploads = 1,即On
- upload_max_filesize = 32M ,上傳檔案的最大大小。
- max_file_uploads = 60 ,最多一次上傳檔案個數。
- max_execution_time = 240 ,每個腳本最長執行時間,單位秒。
- max_input_time =60 ,每個腳本花在解析請求數據上的最長時間,單位秒。
- post_max_size = 32M ,POST數據所允許的最大大小。要上傳大檔案,該值必須大於 upload_max_filesize。
其他輔助設定:
- 系統常數:PHP_VERSION
- my.ini:max_allowed_packet = xxM ,BLOB進行二進制檔案儲存的上限。
- .htaccess 或 httpd.conf:LimitRequestBody ,限制使用者送出的 HTTP 請求內容
(二)其他設定
- magic_quotes_gpc = Off
- default_socket_timeout = 60
- mysql.connect_timeout = 60
- error_reporting = E_ALL
- display_errors = On
- log_errors = On
- log_errors_max_len = 1024
二、httpd.conf中的相關項目
- Timeout 120
- AddDefaultCharset UTF-8
- ErrorLog logs/error_log
- Alias /error/ "/var/www/error/"
三、PHP 5.3 以上的設定改變
(一)移除 magic_quotes_gpc
- get_magic_quotes_gpc() 函式隨之停用
- 但可以在 php.ini 中設定 filter.default = magic_quotes 取代 magic_quotes_gpc=on ,對所有站台都生效。
- 如果是有的站台需要,有的站台不需要,可以在該站台的 apache <VirtualHost> 設定內,加上「php_value filter.default magic_quotes」設定值,就會只作用在這個站台而已。
- 也可以在 apache 的 <Directory> 或 <Files> 來包住「php_value filter.default magic_quotes」,只讓特定目錄裡的 php 或特定 php 程式會有 magic_quotes 的效果。
- 也可以在該目錄的 .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的方法:
- 命令列php -v
- 命令列模式查常數PHP_SAPI得CLI或CGI,透過瀏覽器查得「apache2handler」。
- 命令列模式由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 設置選項:
- html_errors:無意義的 HTML 標記符會使得出錯資訊很凌亂,所以在shell下閱讀報錯資訊是十分困難的。因此將該選項的預設值改為 FALSE。
- implicit_flush:在命令行模式下,所有來自 print() 和 echo() 的輸出將被立即寫到輸出端,而不作任何地緩衝操作。如果您希望延緩或控制標準輸出,您仍然可以使用 output buffering 設置項。
- max_execution_time:鑒於在shell環境下使用 PHP 的無窮的可能性,最大運行時間被設置為了無限長。為 WEB 開發的應用程式可能只需運行幾秒鐘時間,而shell應用程式的運行時間可能會長的多。
- 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的輸入/輸出流:
- php://stdin
- php://stdout
- php://stderr,預設送入標準輸出。
- php://output
- php://input
- php://filter (PHP 5.0.0以後可用)
- php://memory (PHP 5.1.0以後可用)
- 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:
- 當shell用「php 腳本檔」執行時,PHP自動定義三常數STDIN、STDOUT、STDERR,代表標準輸入、標準輸出、標準錯誤裝置的handle。以下範例會和使用者互動:
<?php
fwrite(STDOUT, "Enter your name: ");
$name = trim(fgets(STDIN));
fwrite(STDOUT, "Hello, $name!");
?>
- 當shell用「php -r PHP程式碼」時,PHP程式碼中STDIN、STDOUT、STDERR當成已定義的常數。
- 當用瀏覽器透過網頁伺服器請求腳本檔時,PHP則將STDIN、STDOUT、STDERR當成未定義的常數。
- 其實STDIN就是fopen 'php://stdin'所得的handle,STDOUT就是fopen 'php://stdout'所得的handle,STDERR就是fopen 'php://stderr'所得的handle。
(三)$argv、$argc:
- $argv變數,它將命令行中傳遞給PHP腳本的參數保存為單獨的陣列。如果是腳本檔,註標0的元素放腳本檔的檔名。
- $argc變數,放上述陣列的元素個數。
三、選項及參數
(一)CGI程式在命令列模式執行
- 用法php [-q] [-h] [-s] [-v] [-i] [-f <腳本檔>]
php <腳本檔> [-- 腳本檔參數]
- 諸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 則僅試圖加載相對於當前目錄的擴展庫。
- 設定腳本檔參數:
# 以下命令將不會運行 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程式在命令列模式執行
- 最好跳到php根目錄去執行.\CLI\php這樣各項函式庫、套件才能順利找到。
- 用法php [諸選項] [-f <腳本檔>] [腳本檔參數]
php [諸選項] -r "php程式碼" [腳本參數]:注意php程式碼在windows中必須用"包起來,不能用'包起來。在Linux中用"和'包程式碼都可以,但如用"其中的$變數會以變數值代入,所以要用\$;
php [諸選項] [-- 腳本檔參數]
- 選項大多數和CGI一樣
但是沒有 -C 和 -q多了
-r :直接執行php命令不需要腳本檔標籤「」
-- 諸腳本參數:參數送到腳本檔。當第一次參數開始或是指令來自標準輸入(stdin)
四、和Linux的shell結合
檔案與資料夾處理權限:
- PHP的執行權限是由HTTP daemon(通常是Apache)來決定的,所以多半只有Apache執行者的權限。權限不夠就無法上傳檔案或是利用mkdir()建目錄。
- SELinux會因為安全性的設定,而禁止httpd來控制檔案或目錄。所以,不管你PHP怎麼調整,目錄權限怎麼設定,通通都不會有作用的。只有「Disable Selinux protection for httpd daemon」才能解決問題。
- shell腳本:第一行以 #!/usr/bin/php 開頭,在其後加上以 PHP 開始和結尾標記符包含的正常的 PHP 代碼,然後為該腳本檔設置正確的運行屬性。
#!/usr/bin/php
<?php
var_dump($argv);
?>
- 用shell指令「exec /usr/bin/php -C -d include_path=/usr/share/pear -d output_buffering=1 腳本檔 "$@"」來執行,執行完控制權交回shell。
- 腳本檔中可以用php語法再執行shell指令。
五、以WinBinder寫桌面程式
- 只支援windows不能支援Linux。
- 只做到2006.1.19的0.46.0版。
- 正式版只支援到PHP5.1,PHP5.2要下載新的php_winbinder.dll,並且取消winbinder.php中的版本檢查。
- 要在ext中加php_winbinder.dll、freeimage.dll,另外四個php_pdo.dll、php_mysql.dll、php_pdo_sqlite.dll、php_sqlite.dll用PHP5原來的即可。
- 要用調過的php.ini(待研究),其中含
「extension_dir = "./ext/"
extension=php_winbinder.dll」
- 要改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\""
- phpw檔和includ資料夾相對位置要對。
- 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();
- 可以用php.exe、php-cgi.exe、php-win.exe執行,用php.exe、php-cgi.exe會開cmd視窗,php-cgi.exe還會在視窗中送出http head,用php-win.exe不開cmd視窗。
- 手冊在 英文 http://winbinder.org/manual/index.html
- 也可以下載安裝檔,直接裝。其中server要選NCHC(Taiwan)
- 參考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寫桌面程式
- 參考http://blog.roodo.com/rocksaying/archives/3400303.html、http://bbs.phpres.com/thread-6299-1-1.html、
- 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寫桌面程式
- 參考http://blog.roodo.com/rocksaying/archives/3400303.html、http://bbs.phpres.com/thread-6299-1-1.html、
- 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為例。
一、諸程式庫:
- 在/usr/share/pear之下,通常一套件為一支php或一個資料夾。
- 如能改 php.ini 可將 pear 的絕對路徑加到 php.ini 設定檔中「include_path = ".:/usr/share/pear:"」。諸路徑在UNIX中用:間開,在windows用;間開。
- 如不能改 php.ini ,直接在php程式中加「ini_set('include_path',ini_get('include_path').'/var/www/vhosts/某DN/httpdocs/PEAR:');」指向上傳的PEAR資料夾。
- chown -Rf 擁有者:群組 /usr/share/pear # 將 pear 資料夾及其子資料夾(-R)的擁有者及群組改成適應Apache讀寫的情形。
- 在PHP腳本檔中直接載入即可,如「require_once "DB.php";」
二、套件管理程式
- 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
- 較新版的/usr/bin/pear將路徑改為變數,先自環境變數中查找,是很好的範例。
三、套件管理指令:
- pear list:查看 pear 已安裝的套件版本。
- pear remote-list:目前pear網站上所有可取得pear程式庫列表
- pear list-upgrades:列出可以升級的套件
- pear install 套件名:從網路下載套件並安裝。
- pear download 套件名、pear download-all:下載套件但不安裝。
- pear install filename.tgz:安裝已下載的套件。
- pear upgrade 套件名、pear upgrade filename.tgz、pear upgrade-all:更新套件。
- pear uninstall 套件名:移除套件。
- pear help:查看 pear 指令
四、套件說明
(一)DB.php
在DB.php中放入口靜態的公用方法,在DB/common.php放抽象層,在DB/mysql.php中放實體層
名詞「資料來源名稱」(Database Source Name):資料庫種類://帳號:密碼@機器/選用資料庫。例如:mysql://john:pass@localhost/my_db。
DB類別諸方法
- factory(型):建DB物件指令資料庫類別,但不連上資料庫。
- connect(DSN):建DB物件並連上資料庫。
- apiVersion():傳回版本。
- isError(傳回值):檢查是否有錯。
- isConnection(傳回值):檢查是已連上資料庫。
- isManip(查詢句):檢查查詢句是否為資料操作指令(如INSERT,UPDATE,DELETE…)或資料定義指令(CREATE,DROP,ALTER,GRANT…),傳回真假。
- errorMessage(傳回值):由錯誤碼傳回錯誤訊息。
- parsedsn(DSN):解析DSN並傳回陣列。
- getdsnstring(DSN,是否隱藏密碼):將DSN陣列或字串,轉換成DSN字串,並依指示處理密碼段。
DB_result類別諸方法
- db_result(DB物件,結果id,結果選項):實體化。不回傳。
- setOption(鍵,值):設定結果選項limit_from或limit_count之值。不回傳。
- fetchRow(模式,筆數):以物件或陣列傳回結果數據。
- fetchInto(陣列,模式,筆數):將若干筆數據放進指定陣列。
- numCols():傳回欄數。
- numRows():傳回筆數。
- nextresult():傳回下一個結果。當批次執行多個查詢句時。
- free():釋放結果資源。
- tableInfo(模式):
- getQuery():傳回查詢句。
- getRowCounter():傳回現在正在處理那一筆。
DB_row類別只有一方法:DB_row(陣列):參考代表一筆數據的陣列生成一物件並回傳,諸欄名轉為屬性名。
DB_Error類別繼承PEAR類別後加一方法:DB_Error(錯誤碼,模式,程度,除錯訊息):不回傳。
抽象層DB_common類別繼承PEAR類別後加以下方法:
- db_common():叫「$this->PEAR('DB_Error');」,不回傳。
- __sleep():當serialize()時,傳回一組該字符串化的屬性。
- __wakeup():unserialize()時,重新連線。
- __toString():PHP5時自動轉換,傳回PEAR DB的描述。
- toString():傳回__toString()的傳回結果id。
- quoteString(字串):安全處理查詢句中的單引號並回傳。使用quote()。
- quote(字串):安全處理null及單引號並回傳。
- quoteIdentifier(字串):將字串內的「"」換成「""」並在字串前後均加「"」。
- quoteSmart(字串):安全處理查詢句並回傳。
- quoteBoolean(布林值):傳回0,1代表布林值。
- quoteFloat(浮點數):將浮串數字串化。
- escapeSimple(字串):處理其中的單引號加上escape
- provides(索引):依索引傳回實體層的特徵(features[索引],索引有limit、new_link、numrows、pconnect、prepare、ssl、transactions)。
- setFetchMode(模式,類別):設定查詢結果id的萃取模式,分註標索引模式、字串索引模式、物件模式。
- setOption(選項,值):設定 PEAR DB 運行間的選項,可適用多種資料庫。
- getOption(選項):取選項值。
- prepare(查詢句):處理查詢句中的?&!再傳回。
- autoPrepare(表名,欄名陣列,插入或更新,條件):自動產生插入或更新的查詢句。使用buildManipSQL()。
- autoExecute(表名,欄名陣列,插入或更新,條件):自動產生插入或更新的查詢句,並執行且傳回結果id。使用autoPrepare()。
- buildManipSQL(表名,欄名陣列,插入或更新,條件):自動產生插入或更新的查詢句。
- execute(敘述,數據):導入數據並執行executeEmulateQuery()所生的查詢句。傳回:如select執行成功傳回DB_result物件;DB_OK或DB_Error物件。
- executeEmulateQuery(敘述,數據):如DBMS不支援時,也能產生查詢句。
- executeMultiple(敘述,陣列):多重執行,將陣列中的值一一代入敘述執行,使用相同的敘述handle。成功傳回DB_OK,失敗傳回DB_Error物件。
- freePrepared(敘述句所生的資源id,是否一併釋放PHP資源):釋放Prepared所生的資源組合。
- modifyQuery(查詢句):預備為不同的DBMS調整查詢句,尚未寫。
- modifyLimitQuery(查詢句,起始筆,幾筆):預備加limit子句,尚未寫。
- query(查詢句,數據陣列):先prepare()再execute()。
- limitQuery(查詢句,起始筆,幾筆,數據陣列):先query(查詢句,數據陣列),再設結果id物件中的limit_from屬性和limit_count屬性。
- getOne(查詢句,數據陣列):取回結果id的第一筆第一欄欄值。
- getrow(查詢句,數據陣列,結果id萃取模式):取回第一筆。
- getCol(查詢句,第幾欄,數據陣列):取回結果id的第幾欄欄值,並做成註標索引陣列。
- getAssoc(查詢句,是否強迫化為陣列,數據陣列,結果id萃取模式,是否分群):將查詢結果id化為陣列,首欄之欄值為索引。
- getAll(查詢句,數據陣列,結果id萃取模式):取回所有的筆。
- autoCommit(開關):未支援。
- commit():未支援。
- rollback():未支援。
- numRows(結果id):未支援。
- affectedRows():未支援。
- getSequenceName(序列名):將序列名前面換成_,後面加_seq,成為序列表名。
- nextId(序列):未支援。
- createSequence(序列):未支援。
- dropSequence(序列):未支援。
- raiseError(錯誤編碼,錯誤模式,錯誤程度或回復方法,使用者除錯資訊,DBMS原生錯誤碼及描述):依編碼傳回錯誤物件。
- errorNative():未支援。
- errorCode(DBMS送回的錯誤碼):將DBMS送回的錯誤碼,依實體層的errorcode_map陣列轉換成抽象層錯誤碼。因各家DBMS錯誤編碼不盡相同,所以翻譯到抽象層使其一致。
- errorMessage(錯誤碼):傳回對應的訊息。
- tableInfo(結果id):未支援。
- getTables():即getListOf('tables')
- getListOf(選項):未支援,取回getSpecialQuery()的列表
- getSpecialQuery(選項):未支援。
- nextQueryIsManip(真假):強迫設$this->_next_query_manip的真假。
- _checkManip(查詢句):_next_query_manip或查詢句有一為資料操作指令,則設$this->_last_query_manip為真,否則為假。
- _rtrimArrayValues(陣列):將陣列中所有的字串去尾部空白。
- _convertNullArrayValuesToEmpty(陣列):將陣列中所有的null值轉成空字串。
實體層DB_mysql類別繼承DB_common類別後加以下方法:
- DB_mysql():執行DB_common(),實體化物件。
- connect(dsn陣列,是否持續連線):連結並登入資料庫。
- disconnect():中斷連結。
- simpleQuery(查詢句):送出查詢。
- nextResult(結果id):尚未完成。本意是要移向下一組結果idid。
- fetchInto(結果id,陣列名,結果萃取模式,第幾筆):取某一筆放一維陣列,key改小寫,值去尾端空白,null換成空字串。
- freeResult(結果id):釋放結果所佔的記憶體。
- numCols(結果id):欄數。
- numRows(結果id):筆數。
- autoCommit(開或關):開或關交易自動更新模式。
- commit():確認更新當前的交易。
- rollback():回復當前的交易。
- affectedRows():查出並傳回受影響的筆數。
- nextId(序列名,無表時是否自動產生):下一個可用的id。
- createSequence(序列名):建序列表,只有id一欄,自動加一,加一筆其值0。
- dropSequence(序列名):刪除序列表。
- _BCsequence(序列表名):序列表留id最大那筆。
- quoteIdentifier(字串):將字串內的「`」換成「``」並在字串前後均加「`」。
- quote(字串):quoteSmart(字串)並回傳。
- escapeSimple(字串):為字串加入跳脫字元並回傳。
- modifyQuery(查詢句):在delete查詢句尾加上「where 1=1」以便知道刪了幾筆。
- modifyLimitQuery(查詢句,起始筆,筆數):查詢句為資訊操作指令,則只加limit 筆數,否則加limit 起始筆,筆數。
- mysqlRaiseError(錯誤碼):依錯誤碼傳回raiseError(錯誤碼,null,null,null,mysql錯誤碼及錯誤描述)物件。
- errorNative():傳回最後一次查詢所生的DBMS的錯誤碼。
- tableInfo(結果id或表名,有無次序索引):傳回欄數、諸欄五屬性,有無次序索引為4n+0無、4n+1有[order]、4n+2有[ordertable]、4n+3有兩者。
- getSpecialQuery(指示):指示為tables傳回SHOW TABLES、為databases傳回SHOW DATABASES、為users傳回SELECT DISTINCT User FROM mysql.user。
(二)其他
- Benchmark/Timer.php:時間計數
- PEAR/Info.php:PEAR 設定檔及所安裝的套件訊息,用show()方法看。
- HTML_QuickForm:表單
五、非正常安裝
(一)租賃主機上安裝
- 用phpinfo()查看,沒有任何pear的資訊。如有則可查出pear放在什麼目錄。
- 下載所需要的套件包,如基礎包PEAR-1.7.1.tgz和資料庫包DB-1.7.13.tgz
- 把套件包解壓縮到本地
- 在主機上的虛擬目錄.htdoc或.www之外建立一個include文件夾。然後將剛才解壓出來的檔案上傳到該目錄(如DB包可以只上傳DB.php和DB目錄,PEAR包上傳OS,PEAR,SCRIPT目錄和PEAR.php文件)
- 因為無法修改php.ini文件,所以我們在要使用套件的腳本檔加上:
ini_set("include_path",'/var/.../includes/'.PATH_SEPARATOR.ini_get("include_path" ));
require_once "DB.php";
(二)暴力更新
當PEAR套件管理程式版本太舊無法更新成功時,可依此法:
- 移除舊版:pear uninstall PEAR,因DB套件相依,需一併移除。
- 拷貝新版的pearcmd.php,放入/usr/share/pear/之下。
- 自製或拷貝新版的shell腳本檔pear,放/usr/bin之下,內容為「exec /usr/bin/php -C -d include_path=/usr/share/pear -d output_buffering=1 /usr/share/pear/pearcmd.php "$@"」
- 用pear download PEAR,下載新的套件如PEAR-1.7.1.tgz,再以tar zxvf xxx.tgz解壓縮還原出資料夾,取其中的PEAR.php、System.php、PEAR資料夾、OS資料夾,放在/usr/share/pear之下。
- pear install --force PEAR-1.7.1.tgz。
- 重新裝回DB套件。