第五章 代碼重用與函數編寫
1.require()和include()函數
- 二者幾乎是相同的,唯一區別在于函數失敗后,require()函數會給出一個致命的錯誤;而include()只是給出一個警告。
- 通常來說,PHP語句放在HTML文件中時,它們是不會被處理的。
- 但是如果通過require()和include()來載入html文件時,文件內的任何PHP命令就都會被處理了。
- require_once()和include_once()函數:這兩個函數是require()和include()函數的變體,是確保一個包含的文件只能被引入一次,使用這兩個函數可以防止錯誤的引入同樣的函數庫兩次。
- require()和 inlude()函數運行速度更快。
- 舉例:可以將一個網頁的首頁簡單分為頭部,內容和底部來看,并分別編寫它們的代碼。
-
header.php代碼如下
<html> <head> <title>磕基的公募基金課程</title> <style type="text/css"> h1 { color: rgb(153,0,0); font-size: 24pt; text-align: center; } .menu { color: rgb(153,0,0); font-size: 16pt; text-align: center; font-weight: bold; } td {background: #363636;} p { color: black; font-size: 12pt; text-align: justify; } p.foot{ color: white; font-size: 9pt; text-align: center; font-weight: bold; } a:link,a:visited,a:active {color:white;} </style> </head> <body> <!--頁面頭部--> <table width="100%" cellpadding="12" cellspacing="0" border="0"> <tr bgcolor="black"> <td align="left"></td> <td> <h1>磕基</h1> </td> <td align="right"></td> </tr> </table> <!--菜單--> <table width="100%" bgcolor="white" cellpadding="4" cellspacing="4"> <tr> <td width="25%">  <span class="menu">主頁</span> </td> <td width="25%">  <span class="menu">課程</span> </td> <td width="25%">  <span class="menu">在行</span> </td> <td width="25%">  <span class="menu">公眾號</span> </td> </tr> </table>
-
home.php主頁內容部分代碼如下
<?php require_once('header.php'); ?> <!--網頁內容--> <p>歡迎來到磕基的頁面,你可以畫一些時間來了解我們</p> <p>我們提供最專業的公募基金理財課程</p> <?php require_once('footer.php'); ?>
-
footer.php網頁底部代碼如下
<!--頁面底部--> <table width="100%" bgcolor="black" cellpadding="12" border="0"> <tr> <td> <p class="foot">© 北京二叁叁文化傳播有限責任公司</p> <p class="foot">點擊查看<a href="../feedback.html">更多內容</a></p> </td> </tr> </table>
-
最終效果如圖
-
2.函數
- 調用未定義的函數
- 如果調用的函數出錯,PHP會報出一個錯誤信息。
- 調用未定義函數出錯
-
遇到該類信息,對幾個事情進行檢查。
- 函數名稱的拼寫是否正確;
- 該函數是否存在于所用的PHP版本中;
- 所調用的函數是PHP擴展的一部分,而該部分并沒有被載入。
- 如果調用的函數出錯,PHP會報出一個錯誤信息。
- 函數名稱是不區分大小寫的;因此,命名函數的規則就是都用小寫字母。
- 變量名是區分大小寫的,而函數名則不區分。
- 函數的命名
- 函數命名的限制
- 函數名稱不能和已有的函數重名;
- 函數名稱只能包含字母(a-zA-Z)、數字(0-9)和下劃線(_);
- 函數名稱不能以數字開始
- PHP不允許函數重載,所以用戶自定義函數不能與PHP內置的函數或已定義的函數重名。
- 函數命名的限制
- 使用參數
- 參數允許將數據傳給函數的。
- 參數分為形參和實參
- 所謂形參,全稱為“形式參數”,其不是實際存在變量,所以也有的叫做虛擬參數;它主要是在定義函數名和函數體時所用到的參數,目的是用來接收調用該函數時傳入的參數。
- 而實參的全稱顧名思義,則是“實際參數”,其是在調用傳遞函數的參數;這個參數可以是變量、常量、表達式或函數等,但要注意的是無論何種類型,都必須有確定的值。
- 以下面代碼為例:
echo "<table border="1">";
reset($data);
$value=current($data);
while($value){
echo"<tr><td>".$value."</td></tr>\n";
$value=next($data);
}
echo "</table>";
}
$myArray=array('Line one','Line two','Line three.');
create_table($myArray);- 這里面create_table(\$data)中的\$data就是形參,因為其并不是實際存在的變量。 - 而最下面的create_table(\$myArray)中的\$myArray則是實參,因為$myArray包含的是一個數組,其具有實際值array('Line one','Line two','Line three.')。
- 傳參的時候如果有可選值,則不用全部給出,參數將會根據所給出的參數個數從左到右順序進行賦值。
- 不能漏掉一個可選參數而直接給參數列表中的最后一個參數賦值。
3.作用域
- PHP作用域規則:
- 函數作用域:在函數內部聲明的變量作用域是從聲明它們的那條語句開始到函數末尾,其變量被稱為局部變量;
- 全局作用域:在函數外部聲明的變量作用域是從聲明它們的那條語句開始直到文件末尾,其變量被稱為全局變量;
- 某些特殊的超級全局變量在函數內部和外部都是可見的。(如:$GLOBALS、$_SERVER、$_REQUEST等)
- 使用require()和include()并不影響作用域。
- 這兩個語句如果用于函數內部,則適用函數作用域;
- 如果用于函數外部,則適用全局作用域。
- 關鍵字“global”可以用來手動制定一個在函數中定義或使用的變量具有全局作用域;
- 刪除某個變量可以使用unset($variable_name),該函數可以手動刪除某個變量,刪除之后,該變量就不在參數所指定的作用域中了。
- 函數作用域和全局作用域的區別以如下代碼為例:
$i="lyangye";
function fn(){
echo '函數內部未聲明全局變量的$i='.@$i."<br/>";
global $i;
echo '函數內部聲明了全局變量的$i='.$i."<br/>";
$var="content";
echo '函數內部的局部變量$var='.$var."<br/>";
}
fn();
echo '函數外部的$i='.$i."<br />";
-最終效果如圖
- 如果想要從函數外部引入全局變量,需要使用global命令來聲明其后的變量是全局變量;否則的話PHP函數會認為該變量是個新的局部變量。
- 函數的作用域不同于變量的作用域
4.值傳遞與引用傳遞
- 通常情況下,函數獲取參數的方式是值傳遞。當傳遞一個參數的時候,所創建的新的變量($var_副本)可以看做是原變量($var)的副本(復制品);對于該復制品,可以對其進行任意的修改,而能夠函數外部的變量值不改變。
- 而當需要函數外的原變量($var)也跟著函數內的副本變量($var_副本)一起改變時,就需要是用引用傳遞;意思就是當修改了函數內的副本變量時($var_副本),函數外的原變量($var)也會跟著一起變化
- 可以通過在函數定義的參數名前加一個地址符(&)來制定參數的引用傳遞。
- 以下面代碼為例:
-
值傳遞:
//值傳遞 function maoPiao($value,$amount=1){ $value=$value+$amount; } $value=10; maoPiao($value); echo $value;
- 值傳遞$value效果
引用傳遞
//引用傳遞 function maoPiao(&$value,$amount=1){ $value=$value+$amount; } $value=10; maoPiao($value); echo $value;
-
引用傳遞$value效果
- 所以引用傳遞可以用來做變量的增量運算。
//引用傳遞 function maoPiao(&$value,$amount=1){ $value=$value+$amount; } $value=10; echo '調用maoPiao函數之前的$value='.$value."<br />"; maoPiao($value); echo '調用maoPiao函數之后的$value='.$value."<br/>";
最終效果
5.return關鍵字
-
return的作用是終止函數的執行,在其下面的所有函數內代碼都將被忽略。
- 以下面代碼為例:
function testReturn(){ echo "這個內容將會被打印"; return; echo "這個內容不會被打印"; } testReturn();
- 輸出效果
-
return的正確用法:
- 滿足特定條件之后終止函數。
function larger($x,$y){ if((!isset($x))||(!isset($y))){ echo "輸入的內容不符合規范,請重新輸入"; return; } if($x>=$y){ echo $x."<br />"; }else { echo $y."<br />"; } } larger(2);
-  - ``` function larger($x,$y){ if((!isset($x))||(!isset($y))){ echo "輸入的內容不符合規范,請重新輸入"; return; } if($x>=$y){ echo $x."<br />"; }else { echo $y."<br />"; } } larger(2,10); ``` - 
-
返回函數值
return也可以用來將函數的結果的值進行返回,便于其他代碼的調用。
-
用return返回值的話,上述代碼可以修改為:
``` function larger($x,$y){ if((!isset($x))||(!isset($y))){ return flase; } if($x>=$y){ return $x; }else { return $y; } } $a=5; $b=10; echo larger($a,$b); ```
- 最終顯示效果和上述代碼一樣
- 遞歸函數
- 所謂遞歸函數就是函數調用其自身;
- 很多情況下,遞歸可以用來取代循環;
- 遞歸函數比循環慢而且要占用更多內存,所以盡可能少用遞歸;
- 這是因為遞歸在每次調用函數的時候都會在內存中生成一段該函數的新副本,相應的也將產生多次函數調用的開銷。
if(strlen($str)>0){
reverseR(substr($str,1));
}
echo substr($str,0,1)."
";
return;
}
reverseR('Hello');
```- 遞歸的顯示效果
6.名稱空間
- 名稱空間是一個抽象的容器,其可以包含用戶所定義的函數,常量以及類。
- 優點:
- 一個名稱空間中的所有函數、類和常量都將自動冠以名稱空間前綴;
- 非全路徑的類、函數和常量名稱將在運行時解析,在查看全局空間之前,將首先查看名稱空間。