Hi-Fi優質I.T網:技術文章...
您尚未登入...
帳號:
密碼:

忘記密碼 
 
  訂閱電子報

取消   訂閱
 
2005/11/6-11:3:33
 PHP 語法│作者:│分數:0

 


 

PHP程式設計

PHP簡介

 

PHP的全名為 “PHP: Hypertext Preprocessor”,意思為超文件前置處理器,是一種用來產生 HTML網頁原始檔的中介程式及語言。PHP是一種伺服端內嵌式HTML的應用程式(server-side embedded HTML scripting language),類似IISASPPHP的語法,基本上是混合了C/C++JavaPerl和自創部份語法。PHP不像用CPerl寫成的CGI程式,不是用來一大堆指令來輸出HTML程式,而是直接可以在PHPHTML間切換。如以下是一個簡單的PHP程式:

 

 

其執行時的結果如下畫面所示:

 

 

PHP程式看起來和用於client端的JavaScript很相似,只不過,它是用於server端,我們可以利用它來連接資料庫及其他網路資源。當然,PHP可以產生含JavaScriptHTML網頁。PHPweb serverclient端瀏覽器(browser)的關係如下:

 

 

        PHP是於主機端(Server; 服務端)執行的Script程式,如:ASP也是一種Server端執行的Script程式。而JavaScriptVBScript 則是本地端或客戶端(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 嵌入語法

 

PHP的語法採用自由格式(free format),其程式常以?>括起來,或者是以?>括來,若經設定也可以用<%%>括起來。其寫法有如下數種方式:

 

¨             程式碼    ?>

例:

此種寫法最為常見。而echo(“Hello world!”); 可以寫成 echo “Hello world!”; 看起來較像是指令。echo()的功能為show出一段訊息。

 

¨                程式碼    ?>

例:

這種寫法是上一種寫法的簡寫方式,一般而言,是需要做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.php3main.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中這是不合法的,PHP3include()是不能傳回數值的。假如把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系統常數

 

        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” 這個文字。換言之,用單引號括起來的字串中的任何文字皆不會被改變,但用雙引號括起來的文字中若含變數名稱,則會以變數之值取代之。

 

integerdouble

 

        integer(整數)和C/C++ 一樣有多種表示法,以0開頭者表示為八進位,而0x0X則表示為十六進位。而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

 

        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

 

但若用單引號則只認得 ‘\\’(反斜線) ‘\’’(單引號)兩種特殊的脫離碼,其他的一律不做修改。另外,PHPPHP 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";

 ?>

 

string轉換

 

        當字串要轉成數值時,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";

?>

 

執行結果為如下:

 

 

array

 

        PHParray(陣列)則較為特殊,array可以是多維陣列,陣列的設定變化較多和自由,陣列的索引不限定只可以用整數,也可以用字串來標示。假如沒有標明陣列的索引值,如:a[],則會引用上一個整數之索引值往下遞增,如先前使用到a[5],則下一個a[]相當於a[6]。給定陣列初值時用array關鍵字來標明。基本上,PHParray很像雜湊表和索引陣列的綜和體(hash table and indexed array),我們可以用數值的索引方式(index值從0開始),也可以用字串做為鍵值(key)的雜湊表。而arraykey值和資料值則用 => 做關連。以下是一個簡例:

 

$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()為取得前一個元素之valuecurrent()為取得目前的元素之value,而each()為傳回目前的元素之keyvalue對並移動指標到下一個位置,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 '

";

$var = each($fruits);

echo '

";

echo '

";

echo '

";

echo '

";

echo '

";

$i++;    # 預防打字錯誤造成無限迴圈用, 可以去除

if( $i >= 8) { echo "error"; break;  }     # 預防打字錯誤造成無限迴圈用, 可以去除

}

echo "

current='.current($fruits)." $var[0]='.$var[0]." $var[1]='.$var[1]." $var["key"]='.$var["key"]." $var["value"]='.$var["value"]." prev='.prev($fruits)."
";

?>

 

其執行結果如下:

 

注意:執行 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)

 

多維array

 

        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;

 

注意:在PHP4Array的維數不能不同維度混合,這可能和PHP3不一樣。而當我們用echoarray放在引號裡頭時,在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…elsewhiledo…whileswitch…casefor loop。此外,也可以用breakcontinue來改變流程。

 

if…else控制流程

 

        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 介於1520之間.
\n";

     else if( $c >= 10 ) echo "變數c 介於1015之間.
\n";

          else echo "變數c 小於10.
\n";

 

?>

 

其執行的結果為:

 

變數c 介於1015之間.

 

又除了以上的寫法,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迴圈主要是用來指定滿足條件內的不斷的重複執行指定動作,除非條件不滿足。語意為:時,做…”。其語法為:

 

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迴圈主要用來重複執行特定的動作一直到滿足的條件失敗為止。語意為:…”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迴圈

 

        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提早本次迴圈的完成而進入下一個迴圈。

 

switch   case流程

 

        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 結束

 }

?>

 

中斷語句—breakcontinue

 

        除了相關的流程控制語句之外,我們可以用break以及continue來改變程式中迴圈的流程。break(中斷)的主要用意為跳出目前的迴圈(離開迴圈),最主要是用於while loopfor loop中。而continue(繼續)的主要用意為使迴圈提早進入下一圈(相當於goto到迴圈尾巴)breakcontinue的例子,請參考前面for loop的例子。

 

函數與物件

 

PHP中,如C/C++語言,允許程式設計者將常用的程式碼及變數等元件,組成一個獨立的函數(function)或物件(object),以利程式的設計和開發及利用。

 

函數

 

        PHP的函數和C/C++語言一樣,包含有傳回值及無傳回值兩種,然而,不同的是宣告的方式及使用傳回值的方式不同,而且函數的名稱上是不分大小寫的,這一點和C/C++是不一樣的。另外,函數出現的位置沒有限定。【注意】:變數名稱是大小寫不同的!因此,設計函數的名稱時要特別的注意到這個特性。以下是函數宣告的語法:

 

function function_name($arg1, $arg2, …, $argN)

{

        statements;

}

 

其中合法的function_nameC/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);

取得indexarg_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型態;各物品數量)namesarray型態;各物品數名稱)及cnt(整數;物品類別數)用來儲存採購的資料。另外,開放了三個函數(方法):add_itemremove_itemlookupadd_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)的構建子並不會被自動的呼叫。

 

NULL值或未定義值

 

        PHP中我們可以設定某一個變數的值為nullNULL,代表它的值為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()測試,當變數有設定且其值不為00’0”null時為假(false),否則為真,換言之,00’0”null及未定義皆為empty。而isset()測試,則用來測試某變數是否存在(有定義且非nulldefined 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

剖析URLquery字串成相對應的變數和變數值

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

去掉HTMLPHP標記

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

【註】:其結果和PHPmanual的說明結果有所出入。也許是否因版本而有所不同?又如果我們想要由字尾做不分大小寫的尋找,可用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()會把資料argsformat指示的格式輸出到傳回值字串中,我們可用變數來接收它。而printf()則直接輸到輸出設備去,相當於直接輸出到瀏覽器中,而sprint()則不會。格式format字串和C語言的格式碼類似,其包含:導前添充指示(padding specifier flag)、對齊指示(alignment)、最小寬度(minimum width)、精確度(precision)和資料類別(type)。格式碼可表示如下:

 

%[F][A][W][.P]Type

 

其詳細說明如下:

 

Flag

意義

F

預設

補滿導前空白

 

0

0補滿原導前空白,用於數字/數值

 

Char