PHP的全名為 “PHP: Hypertext Preprocessor”,意思為 “超文件前置處理器”,是一種用來產生 HTML網頁原始檔的中介程式及語言。PHP是一種伺服端內嵌式HTML的應用程式(server-side embedded HTML scripting language),類似IIS的ASP。PHP的語法,基本上是混合了C/C++、Java、Perl和自創部份語法。PHP不像用C或Perl寫成的CGI程式,不是用來一大堆指令來輸出HTML程式,而是直接可以在PHP和HTML間切換。如以下是一個簡單的PHP程式:
其執行時的結果如下畫面所示:
PHP程式看起來和用於client端的JavaScript很相似,只不過,它是用於server端,我們可以利用它來連接資料庫及其他網路資源。當然,PHP可以產生含JavaScript的HTML網頁。PHP和web server及client端瀏覽器(browser)的關係如下:
PHP是於主機端(Server端; 服務端)執行的Script程式,如:ASP也是一種Server端執行的Script程式。而JavaScript或VBScript 則是本地端或客戶端(Client)執行的程式。例如:我們下達 http://www.im.chu.edu.tw/~dtchang/index.php, 若 index.php 這支PHP程式內含有 JavaScript 程式,則 index.php 會先於 www.im.chu.edu.tw 這部機器上執行,而且這部機器上必需安裝一套WEB Server(網站伺服器,如:Apache)和可以分析和執行PHP的程式或套件。WEB Server會把index.php傳給PHP的解析和執行器執行,把index.php執行的結果以網頁的方式回傳給瀏覽器,而回傳的網頁中可能含有JavaScript程式,此時若有需要,則會透過瀏覽器於本地端(瀏覽器所在的這一部機器)上執行。因此,WEB-Based 的資訊系統開發者必需了解的程式和工具相當的多,還好,一般而言都不會太複雜。
PHP的語法採用自由格式(free format),其程式常以和?>括起來,或者是以和?>括來,若經設定也可以用<%和%>括起來。其寫法有如下數種方式:
¨ 程式碼 ?>
例:
此種寫法最為常見。而echo(“Hello world!”); 可以寫成 echo “Hello world!”; 看起來較像是指令。echo()的功能為show出一段訊息。
¨ 程式碼 ?>
例: echo(“Hello world!”); ?>
這種寫法是上一種寫法的簡寫方式,一般而言,是需要做config設定。
¨
例::
這種寫法很像寫JavaScript,但很少見。
¨ <% 程式碼 %>
例: <% echo “Hello world”; %>
註:當asp標籤(asp tags)有設定時才可以支持ASP-style的寫法。
這些不同的寫法執行時都會顯示一行 Hello world,參考如下畫面:
我們可使用require()或include()來把一個檔案的內容引入目前的檔案中(或執行位置),以下是require()和include()的使用說明:
¨ require( “檔名” );
檔名所指的程式在網頁程式執行前,即載入成為網頁程式的一部份;通常放於程式的開頭處,應用於程式一定要引入某一個檔的時候,換言之,require的檔名是不可以用字串變數來臨時決定要載入那個檔案。require()有點像C語言的#include,不管require()會不會被執行到它都會被載入。假如我們想要的是有條件的引用檔案,則應使用include()。關於include()部份說明於下一段文字。require()不是函數,因此不會有所謂的傳回值,也只會被載入一次。
例: require( “config.inc.php” );
¨ include( “檔名” );
檔名所指的程式在讀到include這行指令時才會載入;通常用在程式的流程當中,尤其是選擇性的引用時,換言之,include的檔名可以用字串變數來臨時決定要載入那個檔案。
例: include( “config.inc.php” );
但是要特別注意到使用條件是引入時include()一定要用括號{}括起來,否則會產生錯誤!如下是會產生錯的:
if($condition) include($file_A);
else include($file_B);
以下才是正確的:
if($condition) {include($file_A);}
else {include($file_B);}
使用include()時,引入檔案中可以有return值。如test.php3和main.php3位於同一個目錄,test.php3內容為:
echo "Before the return \n";
if (1)
{
return 27;
}
echo "After the return \n";
?>
而main.php3的內容為:
echo "Before in main.php3 \n";
$retval = include ('test.php3');
echo "File returned: '$retval' \n";
echo "Back in main.php3 \n";
?>
則於PHP4中執行的結果為:
Before in main.php3
Before the return
File returned: '27'
Back in main.php3
【注意】:執行到return處為止。然而在PHP3中這是不合法的,PHP3中include()是不能傳回數值的。假如把main.php3改成:
echo "Before in main.php3 \n";
include ('test.php3');
echo "Back in main.php3 \n";
?>
則PHP3會產生parse error(剖析錯誤,由語法或打字錯誤所產生):
Before in main.php3
Before the return
27Back in main.php3
Parse error: parse error in .....
這是因為return指令並不是位於函數的括號中,而是位於非函數的括號中,只要把return移到括號之外即可。【注意】:當PHP執行require()和include()時會由PHP模式轉為HTML模式,檔案引入完成時,再轉回PHP模式。因此,若require()或include()的檔案中有使用PHP語法,則需使用合法的PHP開始和結束的標記(TAG)。假如main.php3改成:
echo "Before in main.php3 \n";
require ('test.php3');
echo "Back in main.php3 \n";
?>
其結果為:
Before in main.php3
Before the return
After the return
Back in main.php3
【注意】:和用include()的結果不同!
¨ 可以使用標準C語言多行的註解
/* 註解文字 */
¨ 也可以使用標準C++語言單行的註解
// 註解文字
PHP的系統常數和內容,如下表所示:
系統常數名稱 |
內容的定義 |
__FILE__ |
目前被解析的PHP程式的檔名,若目前被解析的程式是include()或require()中的程式則改為本子程式的檔名,而不是父程式的檔名 |
__LINE__ |
本__LINE__出現處位於PHP程式的行號,即本行為第幾行。若目前被解析的程式是include()或require()中的程式則改為本子程式的行號 |
PHP_VERSION |
PHP的版本代號,如: “3.0.8-dev” |
PHP_OS |
執行PHP程式的OS別,如: “WIN32”, “Linux” |
TRUE |
true真值 |
FALSE |
false假值 |
E_ERROR |
mask值為1,發生錯誤時,用來設定error_reporting()的層級。通常ERROR發生時,程式會中斷並產生錯誤的訊息報告 |
E_WARNING |
mask值為2,同上,用於WARNING警告發生時。程式不會中斷,可幫助debug(除錯) |
E_PARSE |
mask值為4,同上,用於分析語法錯誤發生時 |
E_NOTICE |
mask值為8,同上,不尋常的訊息發生時,如: 存取未定義的變數、檔案,大都用於除錯,此時任何可能的錯誤皆會報告 |
E_CORE_ERROR |
mask值為16,同上,PHP核心程式產生錯誤時 |
E_CORE_WARNING |
mask值為32,同上,PHP核心程式產生警告時 |
E_ALL |
所有可能的錯誤1+2+4+8+16+32 |
系統一般預設的錯誤層次為 E_ALL & ~E_NOTICE,即顯示所有的錯誤,但不會出現如變數未定義這一種錯誤訊息,必竟那可能是正常的,因為PHP允許變數事先不存在。這項設定設定於 php.ini 這個檔案中。 如下所示:
error_report = E_ALL & ~E_NOTICE
這一行就是錯誤的層次設定。
例子:(php.ini 中的error_report = E_ALL )
// 這是php系統常數的應用例子.
echo ("Hello world! \n");
echo ("本PHP版本為".PHP_VERSION."執行於".PHP_OS."作業系統. \n");
echo "本PHP檔名為".__FILE__." \n";
// 註: 文字字串可用 "." 這個符號串接
echo "現在所在的行號為:".__LINE__." \n";
if(error_reporting( E_ERROR|E_WARNING|E_PARSE|E_NOTICE))
echo ("設定成功! \n");
echo "下一行會產生 E_NOTICE 的錯誤. \n";
stat( "hello.php3" );
echo "Continue... \n";
?>
執行後的 HTML 原始碼為:
Content-Type: text/html
X-Powered-By: PHP/4.0b4pl1
Content-Type: text/html
Hello world!
本PHP版本為4.0b4pl1執行於WIN32作業系統.
本PHP檔名為C:\WINDOWS\TEMP\tmpF3B1.TMP
現在所在的行號為:7
設定成功!
下一行會產生 E_NOTICE 的錯誤.
Warning: stat failed for hello.php3 (errno=2 - No such file or directory) in C:\WINDOWS\TEMP\tmpF3B1.TMP on line 11
Continue...
透過 Navigator 觀看的結果為:
Content-Type: text/html X-Powered-By: PHP/4.0b4pl1 Content-Type:
text/html Hello world!
本PHP版本為4.0b4pl1執行於WIN32作業系統.
本PHP檔名為C:\php\PHPEd\NONAME1.php3
現在所在的行號為:7
設定成功!
下一行會產生 E_NOTICE 的錯誤.
Warning: stat failed for hello.php3 (errno=2 - No such file or directory) in
C:\php\PHPEd\NONAME1.php3 on line 11
Continue...
假如 error_report = E_ALL & ~E_NOTICE 則不會出現 Warning。
當程式設計寫作時,若覺得內定系統常數不夠用,此時,我們可用define()來自行定義程式所需的常數。其應用和定義的方式如下:
define( “常數名稱”, “常數值”);
例:
// 這是php 自定常數的用法例子
define( "MY_VER", "xwin 3.1.2");
echo "MY_VER=".MY_VER." \n";
// 移去下一行的註解符號後會產生 "parse error"
// 常數值是無法改變的.
// MY_VER = "xwin 3.2.2";
// 下一行將不會產生錯誤,也不會重新定義常數之值
define( "MY_VER", "new value");
echo "MY_VER=".MY_VER." \n";
?>
執行畫面如下:
PHP的資料型態與變數
PHP支援的資料型態不多,有:string(字串),integer(整數),double(雙浮點數),array(陣列)和object(物件)等等。變數事先不需要宣告,可以直接使用,變數的名稱前面要加上$以作為識別,變數的名稱有大小寫之分(註:PHP的變數用$符號開頭,是不是很棒?很多人最喜歡的東西不就是這個?)。若被引用的變數事先沒資料,則設為null值(我們可以用empty()或isset()來檢驗它)。而資料的型態,基本上,並不是由程式設計師所決定的,而是於執行時期由PHP依照該變數的內容(context)來決定的。假如我們想要強迫某變數為某特定的資料型態,則可以用settype()或cast來改變。如下例:
$a = 10; // integer
$b = (double) $a; // force $b to double
可以用的cast有(int)、(integer)、(real)、(double)、(float)、(string)、(array)和(object)。而利用settype()函數則是另一種方式。settype()函數的雛型為:
int settype(string var, string type);
其中var為變數的名稱,而type型態可為: “integer”、 “string”、 “double”、 “array” 和 “object”。若轉換成功則傳回true,失敗則傳回false。我們可用gettype()來取得變數的資料型態。以下是轉換的例子:
$a= 10;
$b=(double)$a;
$c=(string)$a;
$d=(array)$a;
$e=(object) $a;
echo "a=".$a.",type a is ".gettype($a)." \n";
echo "b=".$b.",type b is ".gettype($b)." \n";
echo "c=".$c.",type c is ".gettype($c)." \n";
echo "d=".$d[0].",type d is ".gettype($d)." \n";
echo "e=".$e->scalar.",type e is ".gettype($e)." \n";
?>
注意: “.” 為串接字串文字的運算子符號。其執行結果如下:
a=10,type a is integer
b=10,type b is double
c=10,type c is string
d=10,type d is array
e=10,type e is object
【注意】:數值或字串轉換成array時,自動設索引值為0之元素,而數值或字串轉換成object時則變數值自動變成object的屬性值(attribute),而且以scalar為屬性名(attribute name)。
在PHP3.x版中只支援數值設定(assign by value),換言之,當我們把變數設定為某式子的結果時,表示式最終的結果值會被複製到該變數。因此如下的式子:
$a=$b; // 將 $a 之值設為 $b 之值
$b++; // 將 $b 增加 1
當$b改變時並不會影響到$a。在PHP4.x版則新增參考設定(assign by reference)的語法。換言之,使用參考設定時,新的變數會參考舊變數,也就是說新變數是舊變數的別名(alias)或指向(point to)該變數。此時,改變新變數的值也會異動舊變數的值,反之亦然。要使用參考設定則加&(ampersand)這個符號於被參考的變數之前即可,這個用法和C++ 的參考(reference)是一樣的。如:
$name = 'Bob'; // Assign the value 'Bob' to $name (assign value)
$bar = &$name; // Reference $name as $bar.(assign reference)
$bar = "My name is $bar"; // Alter $bar...
echo $name; // $name is altered too.
echo $bar;
?>
其執行的結果畫面為:
注意:文字字串在 PHP 中可用單引號或雙引號括起來,但其效果是不一樣的,如:
$name = “blob”;
$a = “$name”;
$b = ‘$name’;
結果 $a 的內容為 “blob” 這個文字,而 $b 的內容則為 “$name” 這個文字。換言之,用單引號括起來的字串中的任何文字皆不會被改變,但用雙引號括起來的文字中若含變數名稱,則會以變數之值取代之。
integer(整數)和C/C++ 一樣有多種表示法,以0開頭者表示為八進位,而0x或0X則表示為十六進位。而integer的有效範圍在32位元的作業系統中為正負21億左右( -2,147,483,648 ~ +2,147,483,647)。double(浮點數)則是含有小數點的數值,可用科學表示法表示,如: 12.34, -1.23, 2.34+E30, -1.23e-20,有效範圍為 1.7E-308 ~ 1.7E+308。設定數值的例子如下:
$a = 1234; # 正數(十進位)
$a = -123; # 負數(十進位)
$a = 0123; # 八進位(十進位值為83)
$a = 0x12; # 十六進位(十進位值為18)
$d = 1.23; # 浮點數
$d = -1.24E+20; #浮點數
?>
註: PHP 允許用 # 做為註解文字的開頭。
string(字串)可以為單一字元或多字元的字串。脫離碼(Escape sequence)的用法和C/C++一樣,如:\”, \\, \n, \r, \t … 等等。字串與變數間可用 “.” 串接。字串的標示方法有兩種:(一)用雙引號括起來、(二)用單引號括起來。用雙引號括起來的字串中若含有變數名,則該變數會被展開(expand),而用單引號括起來者則否。用雙引號括起來的字串可以使用脫離碼(Escape sequence),其規則和C/C++及perl一樣。脫離碼如下:
脫離碼 |
意義 |
\n |
new line(新行) |
\r |
carriage return(歸位) |
\t |
horizontal tab(水平定位點) |
\\ |
blackslash(反斜線) |
\$ |
dollar sign(錢號) |
\” |
double-quote(雙引號) |
\[0-7]{1,3} |
octal notation(最多三位的八進位),如:\077 |
\x[0-9A-Fa-f]{1,2} |
hexadecimal notation(最多二位的十六住位數),如:\x8F |
但若用單引號則只認得 ‘\\’(反斜線)及 ‘\’’(單引號)兩種特殊的脫離碼,其他的一律不做修改。另外,PHP(PHP 4.0以上)也提供了一種類似shell的字串輸入寫法 doc syntax(<<<),使用doc syntax必須宣告分隔識別字(delimit),而且必須緊跟在後,結束時必須是該行的最前頭。如以下用EOD作為分隔識別字:
$str = <<<EOD
Example of string
spanning multiple lines
using heredoc syntax.
EOD;
echo $str;
?>
換言之,EOD ... EOD 之間的文字是一串輸入之文字,其執行的結果畫面如下:
在PHP中字串可以用點(dot ‘.’)串接字串或變數,但不可以用 ‘+’ 號。字串中的字元可以用陣列索引的方式運作(如C/C++),如:
$str= “Hello”;
則 $str[0] 為第一個字元 H。注意:PHP沒有字元(char)這種型態,只有字串(string)這種型態。所以
$c = ‘x’;
是把 $c設為一個字串,其值只含單一個字元,這和C/C++是不一樣的。以下是一個示範的程式:
/* 設定字串 */
$str = "This is a string";
/* 串接字串 */
$str = $str . " with some more text";
/* 串接字串,含newline */
$str .= " and a newline at the end.\n";
/* str 結果(展開)為 '
Number: 9 ' */
$num = 9;
$str = "
Number: $num ";
/* str 結果(不會展開)為 '
Number: $num ' */
$num = 9;
$str = '
Number: $num ';
$str = 'This is a test.';
$first = $str[0]; /* 取得第一個字元(索引值為0) */
$str = 'This is still a test.';
$last = $str[strlen($str)-1]; /* 取得最後一個字元 */
/* 把第五個字元設成 'p' */
$str = 'This is still a test.';
$str[5] = "p";
?>
當字串要轉成數值時,PHP依照下列的規則轉換:
n 若字串中包含有: ‘.’、 ‘e’ 或 ‘E’,則轉成double。否則,則轉成整數(integer)。
n 若字串中含有非數值表示法的資料,則取最前頭的數值字串轉換之。若開頭處即為數值性文字則轉為0。
n 若字串無法正常的轉換發生時,此時,最終的資料型態由其他的運算式決定。
例:
$var = 1 + "10.5"; // $var is double (11.5)
$var = 1 + "-1.3e3"; // $var is double (-1299)
$var = 1 + "bob-1.3e3"; // $var is integer (1)
$var = 1 + "bob3"; // $var is integer (1)
$var = 1 + "10 Small Pigs"; // $var is integer (11)
$var = 1 + "10 Little Piggies"; // $var is integer (11)
$var = "10.0 pigs " + 1; // $var is integer (11)
$var = "10.0 pigs " + 1.0; // $var is double (11)
?>
以下是一個混合應用的雜例:
echo "a=".$a." \n";
if( empty($a) )
{
echo "a=null \n";
}
if( !isset($a) ) echo “a=undefined \n”;
$a="hello";
echo "(1)a=".$a." length=".strlen($a)." \n";
$a[2]=”p”;
echo "(2)a=".$a." length=".strlen($a)." \n";
$a=”\\”;
echo "(3)a=".$a." \n";
echo "(4)a=".$a." length=".strlen($a)." \n";
$a=2000;
// 以下會show出 (5)a=2010 length=4
echo "(5)a=".($a+10)." length=".strlen($a)." \n";
?>
執行結果為如下:
在PHP中array(陣列)則較為特殊,array可以是多維陣列,陣列的設定變化較多和自由,陣列的索引不限定只可以用整數,也可以用字串來標示。假如沒有標明陣列的索引值,如:a[],則會引用上一個整數之索引值往下遞增,如先前使用到a[5],則下一個a[]相當於a[6]。給定陣列初值時用array關鍵字來標明。基本上,PHP的array很像雜湊表和索引陣列的綜和體(hash table and indexed array),我們可以用數值的索引方式(index值從0開始),也可以用字串做為鍵值(key)的雜湊表。而array的key值和資料值則用 => 做關連。以下是一個簡例:
$a[0] = "abc"; #數值索引 0
$a[1] = "def"; #數值索引 1
$b["apple"] = 13; #鍵值 “apple”
$b[“orange”] = “水果”; #鍵值(key) “orange” 對應到值(value) “水果”
$c[] = 10; # $c[0]=10;
$c[] = 20; # $c[1]=20;
基本上,當我們沒標明索引值或鍵值時(index or key),PHP會自動由index=0開始設定陣列的值,假如先前有用index的方式設定過陣列的元素,則自動延伸其index值為下一個可用的index值(該值不一定為index+1,因為它可能已經存在了)。如:
$a[2]=10;
$a[]=12;
print_r($a);
$b[]=100;
$b[]=200;
echo " \n";
print_r($b);
?>
其結果為
Array
(
[2] => 10
[3] => 12
)
Array
(
[0] => 100
[1] => 200
)
【注意】:$a[2]和$a[“2”]是同一個元素,但和$a[“2a”]則不會一樣。換言之,數值索引會被轉成文字鍵值。因此,$a[0]和$a[00]和$a[“0”]相同,但不同於$a[“00”]。上例中用到 print_r() 這個函數,它可以將任何資料以人們可閱讀的方式顯示出來,是一個相當好用的函數。
Arrays可以用array這個關鍵字和 => 這個設定子一次設定多個元素,其效果和逐一分開是一樣的。如:
$a=array(10,20);
print_r($a);
echo " ";
$b=array(1=>20,0=>10);
print_r($b);
echo " ";
$c=array(12=>10, "11"=>20, 30, 40);
print_r($c);
?>
其結果為:
其設定的方式是由左至右依序設定。當然,數值索引和文字鍵值是可以混合使用。要注意的是如下:
$b=array(11=>20,"11"=>10);
print_r($b);
?>
其結果為
Array ( [11] => 10 )
只有一個元素$b[“11”](或者說$b[11]),且其值為10。換言之,$b[11]被設成20,接著,$b[“11”]被設成10,而$b[11]和$b[“11”]是同一個元素,因為整數11轉成字串時是 “11” !
Arrays可以用 asort(), arsort(), ksort(), rsort(), sort(), uasort(), usort() 和 uksort() 等函數來做各式各樣的排序。除此之外,array也可以用next(), prev(), current(), each(), end() 以及 reset() 等來移動目前array指標的位置。然而,array中的元素值有可能為0或 “” 或null等狀況會造成next()及current()產生false,此時可能會造成沒有把整個array走完(walk through)。因此若需要走完array中所有的元最好用each()。其中,reset()為array指標移到最前頭,而end()為移到最後,prev()為取得前一個元素之value,current()為取得目前的元素之value,而each()為傳回目前的元素之key和value對並移動指標到下一個位置,each()的傳回值是array,包括0,1,key,value,其中[0]和[“key”]為key值(鍵值),而[1]和[“value”]為data value(資料值)。【注意】:prev()、current()和next()只傳回data value(資料值)!以下是array運作的相關的一些函數列表:
函數名稱 |
功能 |
雛型 |
asort() |
由小到大排列array,索引值或key值不變 |
void asort(array array); |
arsort() |
由大到小排列array,索引值或key值不變 |
void arsort(array array); |
ksort() |
依key值由小到大排列array |
void ksort(array array); |
krsort() |
依key值由大到小排列array |
void krsort(array array); |
rsort() |
由大到小排列array,索引值改變(用數值) |
void rsort(array array); |
sort() |
由小到大排列array,索引值改變(用數值) |
void sort(array array); |
uasort() |
依使用者定義的比較函數,由小到大排列array,索引值不變 |
void uasort(array array, function cmp_function); |
uksort() |
依使用者定義的比較函數,依key值排列array |
void uksort(array array, function cmp_function); |
usort() |
依使用者定義的比較函數,由小到大排列array,索引值改變 |
void usort(array array, function cmp_function); |
count() |
計算陣列的元素個數,若為一般變數則傳回1,若該變數未定義則傳回0 |
int count(mixed var); |
例:
$fruits = array ("d"=>"lemon", "a"=>"orange", "b"=>"banana", "c"=>"apple");
// 結果: fruits[c] = apple, fruits[b] = banana, fruits[d] = lemon, fruits[a] = orange
asort ($fruits);
$fruits = array ("d"=>"lemon", "a"=>"orange", "b"=>"banana", "c"=>"apple");
// 結果: fruits[a] = orange, fruits[d] = lemon, fruits[b] = banana, fruits[c] = apple
arsort($fruits);
$fruits = array ("d"=>"lemon", "a"=>"orange", "b"=>"banana", "c"=>"apple");
// 結果: fruits[a] = orange, fruits[b] = banana, fruits[c] = apple, fruits[d] = lemon
ksort ($fruits);
$fruits = array ("lemon", "orange", "banana", "apple");
// 結果: fruits[0]= "orange", fruits[1]= "lemon", fruits[2]= "banana", fruits[3]= "apple"
rsort ($fruits);
$fruits = array ("lemon", "orange", "banana", "apple");
// 結果: fruits[0] = apple, fruits[1] = banana, fruits[2] = lemon, fruits[3] = orange
sort ($fruits);
// 以下的程式碼可以列出array的內容
for (reset ($fruits); list ($key, $value) = each ($fruits); )
{
echo "fruits[$key] = ", $value, "\n";
}
// 以下的程式碼為列出 each() 的內容
echo " ";
for( reset($fruits); $a = each($fruits); )
{
print_r($a);
echo " ";
}
?>
以下是執行的結果(注意:我們用 echo() 和 print_r() 的部份才有列出來!):
從圖上的後面數行,我們發現 each() 傳回的值是一個 array,索引值 0($a[0]) 和 “key”($a[“key”]) 是指到該元素的陣列索引,而索引 1($a[1]) 和 “value”($a[“value”]) 則指到該元素的資料值。
以下則是用使用者自定的比較函數之排序程式範例:(比較函數和C/C++ 的規則一樣,$a==$b時傳回0,$a>$b時傳回正數,$a<$b時傳回負數)
function cmp ($a, $b) // 使用者自定的函數
{
if ($a == $b) return 0;
return ($a > $b) ? -1 : 1; // 若 $a>$b 則傳回 –1,否則傳回 1
}
$a = array (3, 2, 5, 6, 1);
usort ($a, cmp); // 呼叫 usort() 指定排序的函數名稱為 cmp,即 cmp()
while (list ($key, $value) = each ($a))
{
echo "a[$key]: $value\n";
}
?>
註:list()可以一次設定多個變數值,list()不是函數而是PHP的語法。
執行的結果為:
a[0]: 6 a[1]: 5 a[2]: 3 a[3]: 2 a[4]: 1
以下是array移動及讀取的相關函數列表:
函數名 |
功用 |
雛型 |
reset() |
重置array並傳回first element之值 |
mixed reset(array array); |
end() |
移到array最後一個元素 |
end(array array); |
prev() |
移到前一個元素並傳回該element之值 |
mixed prev(array array); |
current() |
讀取目前所在元素之值(不做移動) |
mixed current(array array); |
next() |
移到下一個元素並傳回該element之值 |
mixed next(array array); |
each() |
用array的方式傳回目前element資料,並移到下一個位置 |
array each(array array); |
key() |
目前所在元素之鍵值(未移動前為第0個元素所在) |
mixed key(array array) |
array_walk() |
以使用者定義的函數將陣列走過(walk)一次 |
int array_walk(array arr, string func, mixed userdata); |
【注意】:prev/current/current傳回值為0、 “”、null 皆會產生false,移動失敗也會產生false。
以下是一個示範例子:(注意:sort()把key值改變成數值)
$fruits = array ("a"=>"lemon", "b"=>"orange", "c"=>"banana", "d"=>"apple");
// 結果: fruits[0] = apple, fruits[1] = banana, fruits[2] = lemon, fruits[3] = orange
sort ($fruits);
print_r($fruits);
echo " ";
// 以下的程式碼可以列出array的內容
$i=0; # 預防打字錯誤造成無限迴圈用, 可以去除
echo "
";
for (reset ($fruits); current($fruits) ; next($fruits))
{
echo '
current='.current($fruits)." | ";
$var = each($fruits);
echo '
$var[0]='.$var[0]." | ";
echo '
$var[1]='.$var[1]." | ";
echo '
$var["key"]='.$var["key"]." | ";
echo '
$var["value"]='.$var["value"]." | ";
echo '
prev='.prev($fruits)." | ";
$i++; # 預防打字錯誤造成無限迴圈用, 可以去除
if( $i >= 8) { echo "error"; break; } # 預防打字錯誤造成無限迴圈用, 可以去除
}
echo " ";
?>
其執行結果如下:
注意:執行 each() 時,會自動地移動位置到下一個元素的位置。
又如:(注意key()值的變化)
$a=array(10,20,30);
echo key($a)."=".current($a)." \n";
next($a);
$a[]=40; // 新增一個元素!
echo key($a)."=".current($a)." \n";
reset($a);
echo key($a)."=".current($a)." \n";
print_r($a);
?>
執行的結果為:
0=10
1=20
0=10
Array ( [0] => 10 [1] => 20 [2] => 30 [3] => 40 )
至於array_walk()可用來把陣列的元素以使用者定義的函數處理過一遍,把所有的元素皆走過一次。其用法為指定要處理的陣列名稱為第一個參數,要使用的函數為第二個參數。array_walk()函數會把元素的數值(value)當做第一個參數傳給使用者函數,把元素的鍵值(key),當做第二個參數傳給使用者函數。假如array_walk()有使用第三個參數,則第三個參數會成為使用者函數的第三個參數。如:
function show($e)
{
echo "value=$e \n";
}
function show2($v, $k)
{
echo "key=$k, value=$v \n";
}
function show3($v, $k, $extra)
{
echo "key=$k, value=$v($extra) \n";
}
$arr=array("ca","us","tw","cn","uk");
array_walk($arr,show);
reset($arr);
array_walk($arr,show2);
reset($arr);
array_walk($arr,show3,"para3");
?>
其結果為:
value=ca
value=us
value=tw
value=cn
value=uk
key=0, value=ca
key=1, value=us
key=2, value=tw
key=3, value=cn
key=4, value=uk
key=0, value=ca(para3)
key=1, value=us(para3)
key=2, value=tw(para3)
key=3, value=cn(para3)
key=4, value=uk(para3)
PHP使用多維陣列相當的簡單,只要加上另一個key值索引即可。注意:留意一下二維時的語法及 => 的用法: $key=>$value;
例:
$a=array("甲","乙","丙", 40);
// 以下會show出: Array=甲乙丙40
echo $a."=".$a[0].$a[1].$a[2].$a[3]." \n";
$a["A"]="甲";
$a[]="三";
echo "a=".$a["A"].$a[4]." \n";
echo '$a::';
print_r($a);
$b[]=10;
$b[]=21;
echo '$b::';
print_r($b);
echo "b[0]=".$b[0].";b[1]=".$b[1];
//以下為 二維陣列
$c = array(
0 =>array("甲", "乙", "丙"),
"1" =>array(1.3,2.4,3.6),
"C3" =>array(1.2E+2,null, 3.4E-5)
);
echo "array c[0]=".$c[0][0].$c[0][1].$c[0][2]." \n";
echo "array c[\"1\"]=".$c["1"][0].$c["1"]["1"].$c["1"][2]." \n";
echo "array c[\"C3\"]=".$c["C3"][0].$c["C3"][1].$c["C3"][2]." \n";
// 以下會 show 出: The same!
if( $c[0][1]==$c["0"]["1"] ) echo("The same! \n");
if( 1 == "1" ) echo("yes, the same. \n");
echo '$c::';
print_r($c);
echo " ";
// 以下為多維陣列
$f = 10;
$a[1] = $f; # one dimensional
$a["foo"] = $f;
$d[1][0] = $f; # two dimensional
$e["foo"][2] = $f; # 混合型keys
$g[3]["bar"] = $f; # 混合型keys
$h["foo"][4]["bar"][0] = $f; # four dimensional!
echo '$h::';
print_r($h);
// 以下示範數值和文字key值並用的array
$a=array("a"=>100, 2=>200, "c"=>300); // 重新定義 $a 為一維array
for(reset($a); list($key, $value)=each($a); )
{
echo "a[$key]=$value; \n";
}
?>
以下是執行後觀看瀏覽器的原始碼(不是瀏覽器顯示的HTML結果,而是HTML的原始碼)之結果:
Array=甲乙丙40
a=甲三
$a::Array
(
[0] => 甲
[1] => 乙
[2] => 丙
[3] => 40
[A] => 甲
[4] => 三
)
$b::Array
(
[0] => 10
[1] => 21
)
b[0]=10;b[1]=21array c[0]=甲乙丙
array c["1"]=1.32.43.6
array c["C3"]=1203.4E-005
The same!
yes, the same.
$c::Array
(
[0] => Array
(
[0] => 甲
[1] => 乙
[2] => 丙
)
[1] => Array
(
[0] => 1.3
[1] => 2.4
[2] => 3.6
)
[C3] => Array
(
[0] => 120
[1] =>
[2] => 3.4E-005
)
)
$h::Array
(
[foo] => Array
(
[4] => Array
(
[bar] => Array
(
[0] => 10
)
)
)
)
a[a]=100;
a[2]=200;
a[c]=300;
注意:在PHP4中Array的維數不能不同維度混合,這可能和PHP3不一樣。而當我們用echo把array放在引號裡頭時,在PHP會產生問題。如:
$a[3]['bar'] = 'Bob';
echo "This won't work: $a[3][bar]";
?>
這時候會產生出
This won't work: Array[bar]
我們可以用字串串接的方式解決,如:
$a[3]['bar'] = 'Bob';
echo "This will work: " . $a[3][bar];
?>
若是PHP 4.x以上的版本,則可用大括號把它括起來就可以:
$a[3]['bar'] = 'Bob';
echo "This will work: {$a[3][bar]}";
?>
此時執行的結果為預期的:
This will work: Bob
【注意】:由於PHP的發展速度很快,所以不同版本之間的行為可能不同,有可能是錯誤的修正,也可能是功能的修正,因此,發生因版本改變時造成預期外的結果是可能的。
在PHP中並沒有支援或需要明顯的變數資料型態宣告,這一點和C/C++語言是大不相同的。PHP中變數的型態是依其內容來作決定的。假如我們設定字串資料給變數$var,則$var變成字串(string)。假如設定整數資料給變數$var,則$var變成整數(integer)。當我們對運算元做運算時(如 + ),若運算元其中有一個是double,則所有的運算元皆轉成double,其運算結果也為double。若否,則依整數的方式運算,最後的結果為整數。
$foo = "0"; // $foo 為 string (ASCII 48)
$foo++; // $foo 為 string "1" (ASCII 49)
$foo += 1; // $foo 變成為 integer (2)
$foo = $foo + 1.3; // $foo變成為double (3.3)
$foo = 5 + "10 Little Piggies"; // $foo變成為integer (15)
$foo = 5 + "10.5 meter"; // $foo變成為integer (15)
$foo = 5.0 + "10.5 meter"; // $foo變成為double (15)
$foo = 5.1 + "10.5 meter"; // $foo變成為 double (15.6)
【注意】:當數值和字串做運算時,表示式的結果是依數值資料之型態而定。我們可用gettype()函數來取得某資料或變數之資料型態。
在PHP中所有出現在函數之內的變數均為區域變數(local variable),其有效視野(scope)限於函數之內。而出現於函數之外的變數為全域變數(或稱整體變數; global variable),各個地方皆可使用,唯函數之內是不可以直接使用,必需透過GLOBAL $變數名稱;或者global $變數名稱;的方式將需要的變數取出,而後才可使用。這和C/C++有著極大的不同。假如我們想保存區域變數,希望它不會因離開函數而消失,則可以用state $變數名稱的方式來達到這個效果,如:static $c;,這和C/C++是一致的。
例:
$c="Hello";
function concate1($a)
{
GLOBAL $c;
return $c." ".$a;
}
function concate2($a)
{
return $c." ".$a;
}
function concat3($a)
{
$b = $b.$c." ".$a;
return $b;
}
function concat4($a)
{
static $b;
$b = $b.$c." ".$a;
return $b;
}
$x = "world";
$d = concate1($x);
// 以下show 出: d=Hello world
echo "d(1)=".$d." \n";
$d = concate2($x);
// 以下show 出: d= world
echo "d(2)=".$d." \n";
$d = concat3($x);
$d = concat3($x);
echo "d(3)=$d ";
$d = concat4($x);
$d = concat4($x);
echo "d(4)=$d ";
?>
執行的結果如下:
d(1)=Hello world
d(2)= world
d(3)= world
d(4)= world world
注意:使用 concat3() 和 concat4() 的結果明顯不一樣。
以下是一些和變數相關的函數列表:
資料判斷函數 |
功能 |
is_int(mixed var) |
變數是否為整數,傳回true/false |
is_integer(mixed var) |
變數是否為整數,傳回true/false |
is_long(mixed var) |
變數是否為長整數,傳回true/false |
is_double(mixed var) |
變數是否為浮點數,傳回true/false |
is_float(mixed var) |
變數是否為浮點數,傳回true/false |
is_real(mixed var) |
變數是否為實數(浮點數),傳回true/false |
is_string(mixed var) |
變數是否為字串,傳回true/false |
is_array(mixed var) |
變數是否為串列,傳回true/false |
is_object(mixed var) |
變數是否為物件,傳回true/false |
issset(mixed var) |
變數是否存在(exist),傳回true/false |
empty(mixed var) |
變數是否為空的,即為NULL,空字串或0。傳回true/false |
unset(mixed var) |
取消/消滅某變數,使該變數消失,此後isset()檢定會false |
gettype(mixed var) |
傳回變數的型態,可能的值為 “integer”, “double”, “string”, “array”, “object”及“unknown type” |
settype(mixed var, string type) |
將變設成type指定的型態,type可為 “integer”, “double”, “string”, “array”, “object”,成功傳回true,否則false |
doubleval(mixed var) |
傳回數值型態的變數之浮點值 |
intval(mixed var, int [base]) |
傳回數值型態的變數以base為底的整數值,如intval(‘FF’,16)為255。預設以10為底 |
strval(mixed var) |
傳回數值型態的變數之字串結果 |
print_r(mixed expr) |
以人類可讀的方式顯示expr的結果 |
PHP的運算符號及表示式(expression)大致上和C/C++是一樣的,只有一些比較特殊的除外,這些運算符號如:
符號 |
意義 |
$ |
變數,如: $c。而$$c則是以$c的內容取變數(間接變數),即以$c的內容當做變數的名稱,如: $c= “abc”,則$$c相當於 $abc |
=> |
設定陣列的元素 |
. |
字串串接 |
.= |
字串串接的簡寫,如:$a=$a+$b; 可以簡化為 $a .= $b; |
and |
邏輯的AND,同意於 && |
or |
邏輯的OR,同意於 || |
xor |
邏輯的XOR |
@ |
加在函數名稱之前,disable該函數會產生之警告訊息 |
以下是符號列表:
符號 |
意義 |
符號 |
意義 |
符號 |
意義 |
+ |
加 |
- |
減 |
* |
乘 |
/ |
除 |
% |
取餘數 |
++ |
增加(+1) |
-- |
減少(-1) |
= |
設定 |
|
|
< |
小於 |
<= |
小於等於 |
> |
大於 |
>= |
大於等於 |
== |
等於 |
!= |
不等於 |
&& |
邏輯AND |
|| |
邏輯OR |
! |
邏輯NOT |
and |
邏輯AND |
or |
邏輯OR |
xor |
邏輯XOR |
& |
逐位AND |
| |
逐位OR |
~ |
逐位NOT |
^ |
逐位XOR |
<< |
左移 |
>> |
右移 |
, |
逗點運算子 |
?: |
問號運算子 |
$ |
變數 |
=> |
陣列元素值 |
-> |
物件的方法 |
-> |
物件的屬性 |
. |
字串串接 |
& |
參考(reference) |
[] |
取陣列元素 |
【註】:未定義的變數於邏輯測試時相當於false。可用{}括起一個元素以做明顯的區隔,可用於字串之內。
由於PHP的大部份語法承襲了C/C++的語法,大都是和 C/C++ 一樣,也有和C/C++一樣的流程控制,但由於其Web server script特性以及結構化的組成,在PHP中不能使用goto以外,,其他的流程控制和C/C++是一樣的。主要的流程控制有:if…else、while、do…while、switch…case和for loop。此外,也可以用break和continue來改變流程。
if …else 控制流程和C/C++一樣有三種構造:
1. 只有簡單的if判斷,語意為: “如果…則….”。語法為:
if( expression )
{
statements;
}
例:
$c=10;
// 單一行時可以省去{}
if( $c >= 10 )
echo "變數c >= 10. \n";
if( $c >= 10 )
{
echo "變數c >= 10. \n";
}
?>
執行的結果為:
變數c >= 10.
變數c >= 10.
2. 除了if之外還else,語意為: “如果…則…否則…”。其語法為:
if( expression )
{
statements;
}
else
{
statements;
}
例:
$c=15;
if( $c >= 10 ) echo "變數c >= 10. \n";
else echo "變數c < 10. \n";
if( $c >= 20 )
{
echo "變數c >= 20. \n";
}
else
{
echo "變數c < 20. \n";
}
?>
其執行的結果為:
變數c >= 10.
變數c < 20.
3. 巢狀的一系列if..else流程,,主要用於多層分岐判斷,其語意為: “如果…則…否則如果…則…(多次重複)”。其語法為:
if( expression )
{
statements;
}
else if(expression)
{
statements;
}
else if(expression)
….
else
{
statements;
}
例:
$c=10;
if( $c >= 20 ) echo "變數c 大於 20. \n";
else if( $c >= 15) echo "變數c 介於15和20之間. \n";
else if( $c >= 10 ) echo "變數c 介於10和15之間. \n";
else echo "變數c 小於10. \n";
?>
其執行的結果為:
變數c 介於10和15之間.
又除了以上的寫法,,PHP也提供了另一種比較像script的寫法,如:
if( expression) :
statements;
else:
statements;
endif;
例:
$c=10;
if( $c >= 20 ):
echo "變數c 大於 20. \n";
else:
echo "變數c 小於 20. \n";
endif;
?>
while迴圈主要是用來指定滿足條件內的不斷的重複執行指定動作,除非條件不滿足。語意為: “當…時,做…”。其語法為:
while( expression )
{
statements;
}
或類似script的語法:
while( expression ):
statements;
endwhile;
例:
$c=10;
while( $c > 0 )
{
echo "現在 c = ".$c." \n";
$c--;
}
?>
其執行的結果為:
現在 c = 10
現在 c = 9
現在 c = 8
現在 c = 7
現在 c = 6
現在 c = 5
現在 c = 4
現在 c = 3
現在 c = 2
現在 c = 1
假如把 $c=10; 改成 $c=0; 則不會執行 while 迴圈,因此不會有任何輸出。
do while迴圈主要用來重複執行特定的動作一直到滿足的條件失敗為止。語意為: “做…當…”。do while迴圈的特點為 “至少執行一次”,為執行後檢查。而while迴圈的特點則可能一次也不執行,為檢查後執行。其語法為:
do
{
statements;
} while( expression );
例:
$c=10;
do
{
echo "現在 c = ".$c." \n";
$c--;
} while( $c > 0);
// 註:把 $c=10; 改成 $c=0; 時會發現和while之不同處
?>
其執行的結果為:
現在 c = 10
現在 c = 9
現在 c = 8
現在 c = 7
現在 c = 6
現在 c = 5
現在 c = 4
現在 c = 3
現在 c = 2
現在 c = 1
假如把 $c=10; 改成 $c=0; 則執行結果為:
現在 c = 0
for迴圈是含有初值設定、條件判斷和計數功能的迴圈,但每一個部份不一定都需要有式子。我們可以想像一下如何精確的跑完20圈,首先將計數計歸零(初值設定),看一下是否要跑?跑了20圈沒有?(條件判斷),若需要跑則執行跑步的動作。每跑完一圈按一下計數器(增量設定、計數功能)。for迴圈的語法如下:
for( initial expr1; condition expr2; counter expr3)
{
statements;
}
其中,initial expr1 為初值設定(嚴格來說是要執行迴圈前的工作設定),而condition expr2 則是判斷迴圈要不要執行的依據,最後的 counter expr3 則是每一次迴圈結束時要做的事情。
例:
for($i=0; $i<10; $i++)
{
echo "現在執行第 ".$i." 圈慢跑. \n";
}
echo "總共跑了 ".$i." 圈. \n";
// for loop 變型 I
$i=0;
for( ; $i<10; $i++)
{
echo "現在執行第 ".$i." 圈慢跑. \n";
}
echo "總共跑了 ".$i." 圈. \n";
// for loop 變型 II
$i=0;
for( ; $i<10; )
{
echo "現在執行第 ".$i." 圈慢跑. \n";
$i++;
}
echo "總共跑了 ".$i." 圈. \n";
// for loop 變型 III
$i=0;
for( ; ; )
{
if( !($i<10) ) break; // 假如 i < 10 不成立則中斷之
echo "現在執行第 ".$i." 圈慢跑. \n";
$i++;
}
echo "總共跑了 ".$i." 圈. \n";
$i=0;
for($i=0;$i<10;$i++)
{
if( $i %2 ) continue; // 本行相當於 if( ($%2) != 0 ) continue;
echo "現在執行第 ".$i." 圈(偶數)慢跑. \n";
}
?>
執行的結果如下:
現在執行第 0 圈慢跑.
現在執行第 1 圈慢跑.
現在執行第 2 圈慢跑.
現在執行第 3 圈慢跑.
現在執行第 4 圈慢跑.
現在執行第 5 圈慢跑.
現在執行第 6 圈慢跑.
現在執行第 7 圈慢跑.
現在執行第 8 圈慢跑.
現在執行第 9 圈慢跑.
總共跑了 10 圈.
現在執行第 0 圈慢跑.
現在執行第 1 圈慢跑.
現在執行第 2 圈慢跑.
現在執行第 3 圈慢跑.
現在執行第 4 圈慢跑.
現在執行第 5 圈慢跑.
現在執行第 6 圈慢跑.
現在執行第 7 圈慢跑.
現在執行第 8 圈慢跑.
現在執行第 9 圈慢跑.
總共跑了 10 圈.
現在執行第 0 圈慢跑.
現在執行第 1 圈慢跑.
現在執行第 2 圈慢跑.
現在執行第 3 圈慢跑.
現在執行第 4 圈慢跑.
現在執行第 5 圈慢跑.
現在執行第 6 圈慢跑.
現在執行第 7 圈慢跑.
現在執行第 8 圈慢跑.
現在執行第 9 圈慢跑.
總共跑了 10 圈.
現在執行第 0 圈慢跑.
現在執行第 1 圈慢跑.
現在執行第 2 圈慢跑.
現在執行第 3 圈慢跑.
現在執行第 4 圈慢跑.
現在執行第 5 圈慢跑.
現在執行第 6 圈慢跑.
現在執行第 7 圈慢跑.
現在執行第 8 圈慢跑.
現在執行第 9 圈慢跑.
總共跑了 10 圈.
現在執行第 0 圈(偶數)慢跑.
現在執行第 2 圈(偶數)慢跑.
現在執行第 4 圈(偶數)慢跑.
現在執行第 6 圈(偶數)慢跑.
現在執行第 8 圈(偶數)慢跑.
註:我們可以像C/C++一樣用break中斷迴圈及continue提早本次迴圈的完成而進入下一個迴圈。
在PHP中也可以使用switch case做複合式或分類式的狀況判斷,每個子狀況或分類都有一個單一的case窗口及相關指令區段,各個指令區段由進入點開始,一直到遇到break指令或整個switch case的結束符號 “}” 為止,這點和C/C++一樣。其語法為:
switch( tested expr0 )
{
case expr1:
[statements;]
[break;]
case expr2:
[statements;]
[break;]
…
case exprN:
[statements;]
[break;]
default:
[statements;]
[break;]
}
或者類似script的語法:
switch (tested expr0 ):
case expr1:
[statements;]
[break;]
case expr2:
[statements;]
[break;]
…
case exprN:
[statements;]
[break;]
default:
[statements;]
[break;]
endswitch;
例:
$d = date("D"); // 取得系統日期的資料
switch( $d )
{
case "Mon":
echo "今天星期一,猴子穿新衣. \n";
break; // case “Mon” 結束
case "Tue":
echo "今天星期二,猴子肚子餓. \n";
break; // case “Tue” 結束
case "Wed":
echo "今天星期三,猴子去爬山. \n";
break;
case "Thu":
echo "今天星期四,猴子看電視. \n";
break;
case "Fri":
echo "今天星期五,猴子去跳舞. \n";
break;
case "Sat": // case “Sat” 會往下執行到 Case “Sun” 的程式碼
case "Sun":
echo "今天放假天. \n";
break; // Case “Sun” 結束
default: // 其他 case
echo "錯誤發生!!. \n";
break; // case default 結束
}
?>
除了相關的流程控制語句之外,我們可以用break以及continue來改變程式中迴圈的流程。break(中斷)的主要用意為跳出目前的迴圈(離開迴圈),最主要是用於while loop和for loop中。而continue(繼續)的主要用意為使迴圈提早進入下一圈(相當於goto到迴圈尾巴)。break和continue的例子,請參考前面for loop的例子。
在PHP中,如C/C++語言,允許程式設計者將常用的程式碼及變數等元件,組成一個獨立的函數(function)或物件(object),以利程式的設計和開發及利用。
PHP的函數和C/C++語言一樣,包含有傳回值及無傳回值兩種,然而,不同的是宣告的方式及使用傳回值的方式不同,而且函數的名稱上是不分大小寫的,這一點和C/C++是不一樣的。另外,函數出現的位置沒有限定。【注意】:變數名稱是大小寫不同的!因此,設計函數的名稱時要特別的注意到這個特性。以下是函數宣告的語法:
function function_name($arg1, $arg2, …, $argN)
{
statements;
}
其中合法的function_name和C/C++一樣,名稱可用底線 “_” 或英文字母及數字組成,但第一個字不可以是數字。參數間用逗點隔開。當想要傳回結果時,要用return來傳回其值。語法為:
return $變數名稱; 或 return($變數名稱);
若沒有資料要傳回則使用語法為:
return; 或 return(null);
函數的參數可以事先定義內定值或預設值(default value),唯有預設值的參數一定要放在所有沒有預設值參數之右,否則無法正常的運作。
例:
function myfunc($a, $b, $c=100) // 參數 $c 預設值為 100
{
return $a+$b+$c;
}
$d = myfunc(10, 20, 30);
echo $d." \n";
$d = myfunc(10, 30);
echo $d." \n";
echo myfunc("100", "20", "30")." \n";
?>
執行的結果為:
60
140
150
而參數的傳遞方式有傳值方式(call by value;最常見;不會影響到原變數)及參考方式(call by reference;有點像C語言的傳址,但事實上是像C++的參考方式)兩種方式。我們可以使用參考的方式來改變原呼叫變數的內容。要使用參考的方式時,只要在想參考的參數前加上&(參考運算子)即可。如例:
function myfunc($a, &$b) // 參考 $b, 相對的變數可以被更改
{
$b++;
return $a+$b;
}
$a=100;
$b=200;
$c=myfunc($a, $b);
echo "a=".$a." \n"; // a=100
echo "b=".$b." \n"; // b=201
echo "c=".$c." \n"; // c=301
?>
其執行的結果為:
a=100
b=201
c=301
關於函數定義的位置,在PHP 3.x中需要事先定義才可,但PHP 4.x則無此限制。在PHP 3.x中不支援未定參數個數的函數(variable-length argument list);雖然可以設定預設值。而於PHP 4.x中則可以使用。與未定參數個數的函數運作相關的函數有:func_num_args(), func_get_arg()和func_get_args()。
函數 |
函數雛型 |
意義 |
func_num_args() |
int func_num_args(void ); |
取得參數個數 |
func_get_arg() |
int func_get_arg(int arg_num); |
取得index為arg_num之參數值 |
func_get_args() |
int func_get_args(void ); |
取得由參數組成之array |
以下是應用例子:
function foo()
{
$numargs = func_num_args();
echo "Number of arguments: $numargs \n";
$arg_list = func_get_args();
for ($i = 0; $i < $numargs; $i++)
{
echo "Argument $i is: " . $arg_list[$i] . " \n";
echo "Argument $i is: " . func_get_arg($i)." \n";
}
}
foo (1, 2, 3);
foo(12, 15);
?>
其執行的結果為:
Number of arguments: 3
Argument 0 is: 1
Argument 0 is: 1
Argument 1 is: 2
Argument 1 is: 2
Argument 2 is: 3
Argument 2 is: 3
Number of arguments: 2
Argument 0 is: 12
Argument 0 is: 12
Argument 1 is: 15
Argument 1 is: 15
在PHP中,使用者可以定義及使用物件。唯PHP的物件比較單純,目前只有類別(class)、方法(method)、屬性(attribute)及單一繼承(extension)等,比起一般的物件導向的語言算是很單純的。基本上,所謂物件就是把資料及操作的方法包裝起來,而開放一些方法(method, function)給物件使用者使用,利用這些開放的方法來運作物件。如以下是一個購物手推車的簡單例子,這個程式定義了一個名為CART的物件,這個物件只有三個變數items(array型態;各物品數量)、names(array型態;各物品數名稱)及cnt(整數;物品類別數)用來儲存採購的資料。另外,開放了三個函數(方法):add_item、remove_item及lookup。add_item是用來增加採購的量,remove_item則用來減少採購的量(退回),而lookup則用來查詢。而NAMED_CART則延伸由CART,其中增加了推車使用者名稱。注請意其中$this(物件本身)的用法。整個例子如下:
class CART
{
var $items;
var $names;
var $cnt=0;
function add_item($goods, $num)
{
if( ! isset($this->items[$goods]) )
{
$this->names[] = $goods;
$this->cnt++;
}
$this->items[$goods] += $num;
}
function lookup($goods)
{
for($i=0; $i < $this->cnt; $i++)
if( $this->names[$i] == $goods)
return $this->items[$goods];
return false;
}
function remove_item($goods, $num)
{
if( $this->items[$goods] >= $num)
{
$this->items[$goods] -= $num;
return true;
}
else return false;
}
}
class NAMED_CART extends CART
{
var $name;
function set_name( $iname )
{
$this->name = $iname;
}
}
$cart = new NAMED_CART;
$cart->set_name( "John" );
$cart->add_item( "Apple", 10);
$cart->add_item( "Orange", 12);
echo "Apple=".$cart->items["Apple"]." \n";
$cart->remove_item( "Apple", 5);
echo "Apple=".$cart->items["Apple"]." \n";
if( $cart->remove_item("Apple", 5) )
echo "移除成功! \n";
else echo "移除失敗! \n";
if( $cart->remove_item("Lemon", 10) )
echo "移除成功! \n";
else echo "移除失敗! \n";
echo "查詢結果 Apple 有 ".$cart->lookup("Orange")."個 \n";
for($i=0; $i < $cart->cnt; $i++)
echo "購入 ".$cart->names[$i]."數量".
$cart->items[$cart->names[$i]]." \n";
?>
其執行的結果為:
Apple=10
Apple=5
移除成功!
移除失敗!
查詢結果 Apple 有 12個
購入 Apple數量0
購入 Orange數量12
【注意】:對於衍生類別(derived class)而言,當衍生類別的構建子(constructor)被呼叫時,父類別(parent class)的構建子並不會被自動的呼叫。
在PHP中我們可以設定某一個變數的值為null或NULL,代表它的值為null。另一種狀況則是使用未出現過的變數,稱為undefined variable。當們在應用這兩種特殊的變數值時會引發出一些意料外的結果,換言之,我們可能會把它的行為猜錯。另外,我們可用isset()和empty()來做一些測試,isset()是用來測該變數是否有值、有被設定過,而empty()則是用來測試這個變數是否存在。以下是它們可能的行為:
變數設定 |
empty() |
isset() |
echo (++$var); |
備註 |
$var=0; |
true |
true |
1 |
|
$var=null; |
true |
false |
1 |
|
$var= “”; |
true |
true |
“” |
|
(不存在) |
true |
false |
1 |
|
$var= “0”; |
true |
true |
1 |
|
$var= ‘0’; |
true |
true |
1 |
|
$var= ‘\0’; |
false |
true |
\1 |
|
$var= ‘\x0’ |
false |
true |
\x1 |
|
$var= “\0”; |
false |
true |
|
脫離碼 |
$var= “\x0”; |
false |
true |
|
脫離碼 |
【注意】:注意‘\x0’(不會展開) 和 “\x0”(脫離碼) 的異同。isset()除了該變數未定義或該變數為null之外皆為 true。
empty()測試,當變數有設定且其值不為0、 ‘0’、 “0”或null時為假(false),否則為真,換言之,0、 ‘0’、 “0”、null及未定義皆為empty。而isset()測試,則用來測試某變數是否存在(有定義且非null;defined and not null),若存在則為真,否則為假。我們可用unset()來取消(刪除)某一個變數。
在程式設計中最常處理的資料是文字,一如C/C++語言一樣,PHP也提供了為數不少的字串處理函數。基本上,我們可以把字串函數分成:分析、轉換、搜尋和處理等幾種類型。在PHP中除提供了一些基本的字串函數外,PHP也提供了強大的常規表示式處理函數(regular expression)。以下是函數列表和其用途:
函數 |
用途 |
addcslashes |
以C語言的方式於指定的字元之前加入 \ (blackslash)符號 |
addslashes |
於特定的字元之前加入 \ |
bin2hex |
將二進位字串轉成十六進位字串 |
chop |
移除字串尾之空白字元(whitespace)(空白, \n, \t等等) |
chr |
傳回指定ASCII CODE之相對字元 |
chunk_split |
將字串分成數小段(用於BASE64_ENCODE MIME編碼) |
convert_cyr_string |
轉換Cyrillic字集到其他的字集 |
count_chars |
統計字串中各字元出現的頻率或相關資訊 |
crypt |
將字串用標準的UNIX DES加密 |
echo |
輸出字串 |
explode |
拆開字串 |
flush |
清除輸出緩衝區 |
get_html_translation_table |
取得HTML字元轉換表 |
get_meta_tags |
取得檔案中所有META標記資料 |
htmlentities |
轉換HTML所有特殊字元 |
htmlspecialchars |
轉換HTML特殊字元(如:< >) |
implode |
縫接字串, explode的反向動作 |
join |
同implode |
ltrim |
去掉字串中導前的空白字元(whitespace) |
md5 |
計算字串之RSA MD5雜湊編碼 |
metaphone |
計算字串之metaphone鍵值,類似soundex() |
nl2br |
於換行字元前插入
|
ord |
傳回字元之ASCII CODE值,chr()的反向動作 |
parse_str |
剖析URL之query字串成相對應的變數和變數值 |
print |
輸出字串 |
printf |
輸出格式化字串 |
quoted_printable_decode |
轉換quoted_printable字串為8 bits 字串 |
QuoteMeta |
於meta字元 .\+*?[^]($) 之前加入 \ |
rawurldecode |
將URL編碼字串還原 |
rawurlencode |
將字串作URL編碼 |
setlocale |
設定地域化資訊 |
similar_text |
計算兩個字串的相似度 |
soundex |
計算字串的發音值 |
sprintf |
格式化輸出資料到字串中 |
strcasecmp |
比較字串大小(不分大小寫) |
strchr |
尋找字串中第一次出現指定字元(也可以是字串),傳回其後的所有字串 |
strcmp |
比較字串大小(分大小寫) |
strcspn |
尋找非遮罩字元之長度(字數) |
strip_tags |
去掉HTML和PHP標記 |
stripCslashes |
去掉反斜線 \ (保留C語言的脫離碼) |
stripslashes |
去掉反斜線 \ (不保留C語言的脫離碼) |
stristr |
不分大小寫版的strstr |
strlen |
取得字串長度 |
strpos |
尋找字串中第一次出現指定字元(字串)的位置 |
strrchr |
尋找字串中最後一次出現指定字元(也可以是字串),傳回其後的所有字串 |
str_repeat |
重複字串n次 |
strrev |
反轉字串 |
strrpos |
尋找字串中最後一次出現指定字元(字串)的位置 |
strspn |
尋找遮罩字元之長度(字數) |
strstr |
尋找字串中第一次出現指定字串,傳回其後的所有字串 |
strtok |
剖析字串,同C語言的strtok |
strtolower |
傳回小寫之字串 |
strtoupper |
傳回大寫之字串 |
str_replace |
取代字串 |
strtr |
轉換字串(可多個)或逐一字元轉換 |
substr |
取得部份字串 |
substr_replace |
取代部份字串 |
trim |
去掉字串頭尾之空白字元 |
ucfirst |
字串第一個字轉成大寫 |
ucwords |
每個字(word)的第一個字元皆轉成大寫 |
我們可以從以上的列表,大略的知道PHP提供了那些字串處理函數。基本上,字串函數可分:轉換、比較和搜尋這幾種類型。以下針對較常用的函數及其原型做探討:
substr()
string substr(string source, int start, int [length] );
substr()可以從來源字串source中的第start(從0算起)個字起抽出length個字元,其中,若省略length,則取至字尾為止。若start為負數(start<0),則由字尾倒數。如:
範例 |
結果 |
$a = substr(“hello world”, 5, 5); |
$a = “lo wo”; |
$a = substr(“hello world”, 5); |
$a = “lo world”; |
$a = substr(“hello world”, -3); |
$a = “rld”; |
strstr()
string strstr(string haystack, string needle);
strchr()
string strchr(string haystack, string needle);
strrstr()
string strrchr(string haystack, string needle);
stristr()
string stristr(string haystack, string needle);
strpos()
int strpos(string haystack, string needle, int [offset] );
strrpos()
int strrpos(string haystack, char needle);
strstr()和strchr()具有同樣的功能,strstr()是strchr()的別名。其作用為從haystack字串(乾草堆)中尋找出needle字串(針)第一次出現的位置,將其及其隨後的字串抽出,若找不到則傳回false。而strrchr()則是由字尾倒過來尋找,至於stristr()則做不分大小寫之尋找。假如,我們只想找出needle出現於haystack的位置,則使用strpos()和strrpos()。如:
範例 |
結果 |
$a = strstr( ‘guest@hinet.net’, ‘@’ ); |
$a = “@hinet.net”; |
$a = strchr( ‘www.im.chu.edu.tw’, ‘.’); |
$a = “.im.chu.edu.tw”; |
$email = 'sterling@designmultimedia.com';
$domain = strstr ($email, '@'); |
$domain = '@designmultimedia.com' |
$a = strrchr( ‘www.im.chu.edu.tw’, ‘.’); |
$a = ‘.tw’; |
$a = strpos("www.im.chu.edu.tw", "im");
print_r($a); |
4 |
$a = strrpos("mate.im.chu.edu.tw", "m");
print_r($a); |
6 |
【註】:其結果和PHP的manual的說明結果有所出入。也許是否因版本而有所不同?又如果我們想要由字尾做不分大小寫的尋找,可用strrchr(strtolower(haystack), strtolower(needle)); 的方式來做到。
addcslashes()
string addcslashes(string str, string charlist);
addslashes()
string addslashes(string str);
stripcslashes()
string stripcslashes(string str);
stripslashes()
string stripslashes(string str);
addcslashes()和addslashes()用來對特定的字元之前加上 \ (slash)這個特殊符號,常用於SQL指令。而stripcslashes()和stripslashes()則用來拿掉由addcslashes()和addslashes()加入之多餘的 \ (slash)。而其中有標明c者,可使用C 語言的慣例,如:’\n’和 ’\t’,而ASCII碼低於32或高於126的字元可用八進位表示法表示。addslashes()則會於單引號、雙引號、\ (slash)及零碼之前加入必要的 \ (slash)。如:
範例 |
結果 |
$a = addcslashes( “abc\tdef\n”, ‘\t’ );
print_r($a).” ”; |
abc def\n
|
$a = addslashes( “abc\tdef\n”);
print_r($a).” ”; |
abc def
|
$a = addcslashes( “abc\tdef\n”, ‘\t\n’ );
print_r($a).” ”; |
abc\tdef\n
|
$a = "abc\tdef\n";
$b = addcslashes ($a, "\0..\37!@\177..\377");
print_r($b); |
abc\tdef\n
|
$a = "abc\'def\'\"ijk\\\\MMM";
$b = addslashes($a);
print_r($b); |
abc\\\'def\\\'\"ijk\\\\MMM |
$a= "abc\'def\'\"ijk\\\\MMM";
echo stripslashes($a); |
abc'def'"ijk\MMM |
$b = "abc\'def\'\"ijk\\\\MMM";
echo stripcslashes($b); |
abc\'def\'"ijk\MMM |
【註】:stripslashes()會把兩個 \ 拿掉一個。
echo()
echo(string arg1, string [argn]... );
print()
print(string arg);
printf()
int printf(string format, mixed [args]... );
print_r()
void print_r(mix expression);
sprint()
string sprintf(string format, mixed [args]... );
echo()可用來輸出多個參數之資料,而print()則僅能輸出一個參數之資料,它們並不是函數,而是語法。而print_r()則是一個較特別的函數,可用人類可閱讀的方式來顯示資料,用於顯示array時特別的好用。至於printf()和sprintf()則是用來做格式化輸出,其用法和C語言中的printf()及sprintf()是運作的方式是差不多的。sprintf()會把資料args以format指示的格式輸出到傳回值字串中,我們可用變數來接收它。而printf()則直接輸到輸出設備去,相當於直接輸出到瀏覽器中,而sprint()則不會。格式format字串和C語言的格式碼類似,其包含:導前添充指示(padding specifier flag)、對齊指示(alignment)、最小寬度(minimum width)、精確度(precision)和資料類別(type)。格式碼可表示如下:
%[F][A][W][.P]Type
其詳細說明如下:
Flag |
值 |
意義 |
F |
預設 |
補滿導前空白 |
|
0 |
以0補滿原導前空白,用於數字/數值 |
|
‘Char |
| |