官术网_书友最值得收藏!

第4章 PHP的語言結構

學習目標|Objective


任何一種語言都有程序結構,常見的有順序結構、分支結構和循環結構。在學習程序結構前,讀者還需要對函數的知識進行學習。本章主要介紹PHP語言中函數和語言結構的使用方法和技巧。

內容導航|Navigation


  • 熟悉函數的使用方法
  • 熟悉流程控制的概述
  • 掌握條件控制結構
  • 掌握循環控制結構
  • 掌握條件分支結構的綜合應用
  • 掌握循環控制結構的綜合應用

4.1 內置函數

函數的英文為function,function是功能的意思。顧名思義,使用函數就是要在編程過程中實現一定的功能,即通過代碼塊來實現一定的功能。比如通過一定的功能記錄下酒店客人的個人信息,每到他生日的時候自動給他發送祝賀email,并且這個發信“功能”可以重用,可更改為在某個客戶的結婚紀念日時給他發送祝福email。所以函數就是實現一定功能的一段特定的代碼。

PHP提供了大量的內置函數,方便程序員直接使用,常見的內置函數包括數學函數、字符串函數、時間和日期函數等。

下面以調用數學函數rand()為例進行講解。

【例4.1】(實例文件:源文件\ch04\4.1.php)

本程序運行結果如圖4-1所示。

圖4-1 程序運行結果

4.2 自定義函數

其實,更多的情況下,程序員需要的是自定義函數。

4.2.1 自定義和調用函數

自定義函數的語法結構如下:

其中,name_of_function是函數名,param1、param2是參數,statement是函數的具體內容。

下面以自定義和調用函數為例進行講解。本實例主要實現酒店歡迎信息。

【例4.2】(實例文件:源文件\ch04\4.2.php)

本程序運行結果如圖4-2所示。

圖4-2 程序運行結果

值得一提的是,此函數的返回值是通過值返回的。也就是說return語句返回值時,創建了一個值的副本,并把它返回給使用此函數的命令或函數,在這里是echo命令。

4.2.2 向函數傳遞參數值

由于函數是一段封閉的程序,因此很多時候程序員都需要向函數內傳遞一些數據來進行操作。

下面以計算酒店房間住宿費總價為例進行講解。

【例4.3】(實例文件:源文件\ch04\4.3.php)

運行結果如圖4-2所示。

圖4-3 程序運行結果

【案例分析】

(1)以這種方式傳遞參數值的方法就是向函數傳遞參數值。

(2)其中function totalneedtopay($days,$roomprice){}定義了函數和參數。

(3)無論是通過變量$rentdays和$roomprice向函數內傳遞參數值,還是像totalneedtopay (5,198)這樣直接傳遞參數值都是一樣的。

4.2.3 向函數傳遞參數引用

向函數傳遞參數引用其實就是向函數傳遞變量引用。參數引用一定是變量引用,靜態數值是沒有引用一說的。由于在變量引用中已經知道,變量引用其實就是對變量名的使用,是對特定的變量位置的使用。

下面仍然以計算酒店服務費總價為例進行講解。

【例4.4】(實例文件:源文件\ch04\4.4.php)

運行結果如圖4-4所示。

圖4-4 程序運行結果

【案例分析】

(1)以這種方式傳遞參數值的方法就是向函數傳遞參數引用。使用“&”符號表示參數引用。

(2)其中function totalfee(&$fee,$serviceprice){}定義了函數、參數和參數引用。變量$fee是以參數引用的方式進入函數的。當函數的運行結果改變了變量$fee的引用時,在函數外的變量$fee的值也發生了改變,也就是函數改變了外部變量的值。

4.2.4 從函數中返回值

在上述例子中,都是把函數運算完成的值直接打印出來。但是,很多情況下,程序并不需要直接把結果打印出來,而是僅僅給出結果,并且把結果傳遞給調用這個函數的程序,為其所用。

這里需要用到return關鍵字。下面以綜合酒店客房價格和服務價格為例進行講解。

【例4.5】(實例文件:源文件\ch04\4.5.php)

運行結果如圖4-5所示。

圖4-5 程序運行結果

【案例分析】

(1)在函數function totalneedtopay($days,$roomprice)算法中,直接使用return把運算的值返回給調用此函數的程序。

(2)其中,echo totalneedtopay($rentdays,$roomprice);語句調用了此函數,totalneedtopay()把運算值返回給了echo語句,才有了上面的顯示。當然這里也可以不用echo來處理返回值,也可以對它進行其他處理,比如賦值給變量等。

4.2.5 對函數的引用

無論是PHP中的內置函數,還是程序員在程序中自定義的函數,都可以簡單地通過函數名調用。但是操作過程也有些不同,大致分為以下3種情況。

  • 如果是PHP的內置函數,如date(),可以直接調用。
  • 如果這個函數是PHP的某個庫文件中的函數,就需要用include()或require()命令把此庫文件加載,然后才能使用。
  • 如果是自定義函數,與引用程序在同一個文件中,就可以直接引用。如果此函數不在當前文件內,就需要用include()或require()命令加載。

對函數的引用實際上是對函數返回值的引用。

【例4.6】(實例文件:源文件\ch04\4.6.php)

運行結果如圖4-6所示。

圖4-6 程序運行結果

【案例分析】

(1)本實例首先定義一個函數,然后變量$bb將引用函數,最后輸出變量$bb,它實際上是$aa的值。

(2)和參數傳遞不同,在定義函數和引用函數時,都必須使用“&”符號,表明返回的是一個引用。

4.2.6 對函數取消引用

對于不需要引用的函數,可以做取消操作。取消引用使用unset()函數來完成,目的是斷開變量名和變量內容之間的綁定,此時并沒有銷毀變量內容。

【例4.7】(實例文件:源文件\ch04\4.7.php)

運行結果如圖4-7所示。

圖4-7 程序運行結果

本程序首先聲明一個變量和變量的引用,輸出引用后取消引用,再次調用原變量。從圖4-7可以看出,取消引用后對原變量沒有任何影響。

4.3 PHP 7的新變化1——聲明函數返回值的類型

在PHP 7中,用戶可以聲明函數返回值的類型??梢月暶鞯姆祷仡愋桶╥nt、float、bool、string、interfaces、array和callable。

下面通過案例來學習PHP 7如何聲明函數返回值的類型。

【例4.8】(實例文件:源文件\ch04\4.8.php)

以上程序執行結果如圖4-8所示。

圖4-8 聲明函數返回值的類型

4.4 PHP 7的新變化2——新增intdiv()函數

在PHP 7中,新增了整除函數intdiv()。語法格式如下:

     intdiv(a, b);

該函數返回值為a除以b的值并取整。

【例4.9】(實例文件:源文件\ch04\4.9.php)

本程序運行結果如圖4-9所示。

圖4-9 程序運行結果

4.5 PHP 7的新變化3——括號在變量或函數中變化

在PHP 7中,用括號把變量或者函數括起來將不再起作用。

【例4.10】(實例文件:源文件\ch04\4.10.php)

注意第二句的調用是用圓括號包了起來,但還是報這個嚴格錯誤,如圖4-10所示。

圖4-10 PHP 7中的報錯信息

PHP 7之前的版本是不會報第2個錯誤的。例如,在PHP 5中的運行結果如圖4-11所示。

圖4-11 PHP 5中的報錯信息

4.6 PHP 7的新變化4——參數處理機制的修改

在PHP 7中,處理參數的機制出現了新的變化。

1. 不再支持重復參數命名

比如下面的代碼執行的時候會報錯:

2. func_get_arg()和func_get_args()函數的調整

在PHP 7中,func_get_arg()和func_get_args()兩個函數將返回參數當前的值,而不是傳入時的值。當前的值有可能會被修改,所以當前值和傳入時的值不一定相同。

【例4.11】(實例文件:源文件\ch04\4.11.php)

在PHP 7中,上面的代碼會打印101,而不是100。運行結果如圖4-12所示。如果想打印原始的值,調用的順序調整一下即可,也就是將x++操作放到兩個函數的后面。

圖4-12 在PHP 7中的運行結果

在PHP 5或者更早的版本中,運行結果如圖4-13所示。

圖4-13 在PHP 5中的運行結果

3. 在打印異?;厮菪畔r將顯示修改后的值

例如下面的代碼:

在PHP 7中的運行結果:

在PHP 5中的運行結果:

這個調整不會影響代碼的運行,不過在調試的時候需要注意這個變化。

4.7 包含文件

如果想讓自定義的函數被多個文件使用,可以將自定義函數組織到一個或者多個文件中,這些收集函數定義的文件就是用戶自己創建的PHP函數庫。通過使用require ()和include()等函數可以將函數庫載入腳本程序中。

4.7.1 require和include

require()和include()語句不是真正意義的函數,屬于語言結構。通過include()和require()語句都可以實現包含并運行指定文件。

(1)require():在腳本執行前讀入它包含的文件,通常在文件的開頭和結尾處使用。

(2)include():在腳本讀到它的時候才將包含的文件讀進來,通常在流程控制的處理區使用。

require()和include()語句對于處理失敗方面是不同的。當文件讀取失敗后,require將產生一個致命錯誤,而include則產生一個警告。可見,如果遇到文件丟失需要繼續運行,則使用include;如果想停止處理頁面,則使用require。

【例4.12】(實例文件:源文件\ch04\4.12.php和test.php)

其中,4.12.php代碼如下:

test.php代碼如下:

運行test.php,結果如圖4-14所示。從結果可以看出,使用include時,雖然出現了警告,但是腳本程序仍然在運行。

圖4-14 程序運行結果

4.7.2 include_once和require_once

include_once和require_once語句在腳本執行期間包含并運行指定文件,作用與include和require語句類似,唯一的區別是,如果該文件的代碼被包含了,則不會再次包含,只會包含一次,從而避免函數重定義以及變量重賦值等問題。

4.8 流程控制

流程控制也叫控制結構,在一個應用中用來定義執行程序流程。它決定了某個程序段是否會被執行和執行多少次。

PHP中的控制語句分為3類:順序控制語句、條件控制語句和循環控制語句。其中,順序控制語句是從上到下依次執行的,這種結構沒有分支和循環,是PHP程序中最簡單的結構。下面主要講述條件控制語句和循環控制語句。

4.8.1 條件控制結構

條件控制語句中包含兩個主要的語句,一個是if語句,另一個是switch語句。

1. 單一條件分支結構(if語句)

if語句是最為常見的條件控制語句,格式為:

這種形式只是對一個條件進行判斷。如果條件成立,就執行命令語句,否則不執行。

if語句的流程控制圖如圖4-15所示。

圖4-15 if語句流程控制圖

【例4.13】(實例文件:源文件\ch04\4.13.php)

運行后刷新頁面,結果如圖4-16所示。

圖4-16 程序運行結果

【案例分析】

(1)此實例首先使用rand()函數隨機生成一個整數$num,然后判斷這個隨機整數是不是奇數,若是,則輸出上述結果,若不是,則不輸出任何內容,所以如果頁面內容顯示為空,就刷新頁面。

(2)rand()函數返回隨機整數,語法格式如下:

     rand(min,max)

此函數主要是返回min和max之間的一個隨機整數。如果沒有提供可選參數min和max,則rand()返回0到RAND_MAX之間的偽隨機整數。

2. 雙向條件分支結構(if…else語句)

如果是非此即彼的條件判斷,可以使用if…else語句。它的格式為:

     if(條件判斷語句){
            命令執行語句A;
     }else{
            命令執行語句B;
     }

這種結構形式首先判斷條件是否為真,如果為真,就執行命令語句A,否則執行命令語句B。

if…else語句程序流程控制圖如圖4-17所示。

圖4-17 if…else語句流程控制圖

【例4.14】(實例文件:源文件\ch04\4.14.php)

運行后結果如圖4-18所示。

圖4-18 程序運行結果

3. 多向條件分支結構(elseif語句)

在條件控制結構中,有時會出現多種選擇,此時可以使用elseif語句。它的語法格式為:

elseif語句程序流程控制圖如圖4-19所示。

圖4-19 elseif語句流程控制圖

【例4.15】(實例文件:源文件\ch04\4.15.php)

運行后結果如圖4-20所示。

圖4-20 程序運行結果

4. 多向條件分支結構(switch語句)

switch語句的結構給出不同情況下可能執行的程序塊,條件滿足哪個程序塊,就執行哪個語句。它的語法格式為:

其中,若“條件判斷語句”的結果符合某個“可能判斷結果”,就執行其對應的“命令執行語句”。如果都不符合,則執行default對應的默認項的“命令執行語句”。

switch語句的流程控制圖如圖4-21所示。

圖4-21 switch語句流程控制圖

【例4.16】(實例文件:源文件\ch04\4.16.php)

運行后結果如圖4-22所示。

圖4-22 程序運行結果

4.8.2 循環控制結構

循環控制語句主要包括3種,即while循環、do…while循環和for循環。while循環在代碼運行的開始檢查表述的真假;而do…while循環則在代碼運行的末尾檢查表述的真假,即do…while循環至少要運行一遍。

1. while循環語句

while循環的結構為:

其中,當“條件判斷語句”為true時,執行后面的“命令執行語句”,然后返回條件表達式繼續進行判斷,直到表達式的值為假才能跳出循環,執行后面的語句。

while循環語句的流程控制圖如圖4-23所示。

圖4-23 while語句流程控制圖

【例4.17】(實例文件:源文件\ch04\4.17.php)

運行后結果如圖4-24所示。

圖4-24 程序運行結果

本實例主要實現20以內的奇數輸出。從1~20依次判斷是否為奇數,如果是,則輸出;如果不是,則繼續下一次的循環。

2. do…while循環語句

do…while循環的結構為:

先執行do后面的“命令執行語句”,其中的變量會隨著命令的執行發生變化。當此變量通過while后的“條件判斷語句”判斷為false時,停止執行“命令執行語句”。

do…while循環語句的流程控制圖如圖4-25所示。

圖4-25 do…while循環語句流程控制圖

【例4.18】(實例文件:源文件\ch04\4.18.php)

運行后結果如圖4-26所示。從結果可以看出,while語句和do…while語句有很大的區別。

圖4-26 程序運行結果

3. for循環語句

for循環的結構為:

其中expr1為條件的初始值,expr2為判斷的最終值,通常都使用比較表達式或邏輯表達式充當判斷的條件,執行完命令語句后,再執行expr3。

for循環語句的流程控制圖如圖4-27所示。

圖4-27 for循環語句流程控制圖

【例4.19】(實例文件:源文件\ch04\4.19.php)

運行結果如圖4-28所示,從中可以看出命令語句執行了4次。

圖4-28 程序運行結果

4. foreach循環語句

foreach語句是常用的一種循環語句,經常被用來遍歷數組元素。它的格式為:

可以根據數組的情況分為兩種,即不包含鍵值的數組和包含鍵值的數組。

不包含鍵值的:

包含鍵值的:

每進行一次循環,當前數組元素的值就會被賦值給數組元素值變量,數組指針會逐一移動,直到遍歷結束為止。

【例4.20】(實例文件:源文件\ch04\4.20.php)

運行結果如圖4-29所示,從中可以看出命令語句執行了3次。

圖4-29 程序運行結果

5. 流程控制的另一種書寫格式

在一個含有多條件、多循環的語句中,包含多個“{}”,查看起來比較煩瑣。流程控制語言的另一種書寫方式是以“:”來代替左邊的大括號,使用endif;、endwhile;、endfor;、endforeach;和endswitch;來替代右邊的大括號,這種描述程序結構的可讀性比較強。常見的格式如下。

條件控制語句中的if語句:

條件控制語句中的switch語句:

循環控制語句中的while循環:

循環控制語句中的do…while循環:

循環控制語句中的for循環:

【例4.21】(實例文件:源文件\ch04\4.21.php)

運行結果如圖4-30所示。從效果圖可以看出,該代碼使用新的書寫格式實現了楊輝三角的排列輸出。

圖4-30 程序運行結果

6. 使用break/continue語句跳出循環

使用break關鍵字用來跳出(也就是終止)循環控制語句和條件控制語句中switch語句的執行,例如:

在這段程序中,while循環控制語句里面包含一個switch流程控制語句。在程序執行到break語句時,break會終止執行switch語句,或者是switch和while語句。其中,在“case 1”下的break語句跳出switch語句;“case 2”下的break 2語句跳出switch語句和包含switch的while語句;“default”下的break 1語句和“case 1”下的break語句一樣,只是跳出switch語句。其中,break后帶的數字參數是指break要跳出的控制語句結構的層數。

使用continue關鍵字的作用是跳開當前的循環迭代項,直接進入下一個循環迭代項,繼續執行程序。下面通過一個實例說明此關鍵字的作用。

【例4.22】(實例文件:源文件\ch04\4.22.php)

運行結果如圖4-31所示。

圖4-31 程序運行結果

其中,continue關鍵字在當n等于2的時候跳出本次循環,并且直接進入下一個循環迭代項,即n等于3。另外,continue關鍵字和break關鍵字一樣,都可以在后面直接跟一個數字參數,用來表示跳開循環的結構層數?!癱ontinue”和“continue 1”相同,“continue 2”表示跳開所在循環和上一級循環的當前迭代項。

4.9 實戰演練1—條件分支結構綜合應用

下面通過案例講述條件分支結構的綜合應用。

【例4.23】(實例文件:源文件\ch04\4.23.php)

運行結果如圖4-32所示。

圖4-32 程序運行結果

其中,最后4行由switch語句實現,其他輸出均由if語句實現。

4.10 實戰演練2—循環控制結構綜合應用

下面以遍歷已訂房間門牌號為例介紹循環控制語句的應用技巧。

【例4.24】(實例文件:源文件\ch04\4.24.php)

運行結果如圖4-33所示。

圖4-33 程序運行結果

其中,102~307由for循環實現。0:102~4:307由while循環實現。0-102和1-202由do…while循環實現。for循環和while循環都完全遍歷了數組$bookedrooms,而do…while循環由于條件為while($i < 2),因此do后面的命令執行了兩次。

4.11 高手甜點

甜點1:如何合理運用include_once()和require_once()?

答:include()和require()函數在其他PHP語句執行之前運行,引入需要的語句并加以執行。但是每次運行包含此語句的PHP文件時,include()和require()函數都要運行一次。include()和require()函數如果在先前已經運行過,并且引入相同的文件,則系統會重復引入這個文件,從而產生錯誤。而include_once()和require_once()函數只是在此次運行的過程中引入特定的文件或代碼,但是在引入之前,會先檢查所需文件或者代碼是否已經引入,如果引入將不再重復引入,從而不會造成沖突。

甜點2:程序檢查后正確,卻顯示Notice: Undefined variable,為什么?

PHP默認配置會報這個錯誤,就是警告將在頁面上打印出來,雖然這有利于暴露問題,但是現實使用中會存在很多問題。通用解決辦法是修改php.ini的配置,需要修改的參數如下:

(1)找到error_reporting = E_ALL,修改為error_reporting = E_ALL & ~E_NOTICE。

(2)找到register_globals = Off,修改為register_globals = On。

主站蜘蛛池模板: 固镇县| 建德市| 昌宁县| 博客| 韶山市| 眉山市| 江口县| 平凉市| 西盟| 达尔| 华宁县| 西安市| 财经| 仪陇县| 松潘县| 宁波市| 汽车| 洛浦县| 皋兰县| 江口县| 洞头县| 阜康市| 桐柏县| 扎鲁特旗| 博野县| 昌宁县| 上杭县| 河津市| 乐都县| 平顶山市| 本溪| 许昌县| 永春县| 道真| 独山县| 嵊泗县| 来宾市| 高清| 万宁市| 灵石县| 盐城市|