1. 解決作用域問題
在上一節談到了PHP中函數的作用域問題,如果說類還不夠說明問題,那麼在這篇文章中的作用域例子,也許對您更有說服力。
那麼,我們如何能在PHP的函數中訪問外部的變量呢?
在PHP中,存在一個概念叫做全局作用域,也就是說,如果你不使用函數(未來會有類的概念),那麼你創建的變量可以在頁面的任何地方訪問。那麼,我們怎麼解決函數體內的問題呢?
我們可以使用global關鍵字:
<?php $name="kym"; function Test() { global $name; echo($name); } Test(); ?>
這樣的話,我們就相當於得到了對全局變量$name的一個引用,而不需要重新創建一個$name變量了。
在PHP手冊中有這樣一句話:使用全局變量等效於在$GLOBALS變量中創建一個對變量的引用。那麼我們就可以模仿這個語義寫出這樣的代碼:
<?php $name="kym"; function Test() { $temp=&$GLOBALS["name"]; echo($temp); } Test(); ?>
其實這兩種是等效的代碼。看上去這樣使用變量很麻煩,但是這樣其實避免了很多副作用的產生,如Java,C#是面向對象的語言,但是在PHP中,一切都在一個頁面,甚至多個頁面中,那麼如果不使用這樣的辦法,很容易產生函數的副作用(誤修改)。
2. 默認參數
第一次聽過這個概念應該是在C++中,之後學了C#,就沒有接觸過這個概念了,不過個人還是非常喜歡這個特性的。
這樣就可以不必要為一個函數寫一堆麻煩的重載函數了。
寫個最簡單的例子:
<?php function Test($name="kym") { echo($name); } Test(); Test("others"); ?>
是不是不需要寫一個重載函數了呢?
但是在這裡需要注意兩點:
A. 在為參數設置默認值時,只能設置最簡單的常量,而不能包含復雜的表達式。
B. 需要設置默認值的參數必須放在最後。這個類似於C#中的可變參數。
3. 可變參數
在C#中,就存在這樣一個概念叫可變參數,寫個簡單的例子:
protected void LinkButton1_Click(object sender, EventArgs e) { Response.Write(GetSum(1, 2, 3, 4, 5)); } public int GetSum(params int[] elements) { int sum = 0; for (int i = 0; i < elements.Length; i++) { sum += elements[i]; } return sum; }
在寫例子之前,我先來介紹三個與可變參數相關的函數。
func_get_args()返回函數的所有參數的數組
func_get_arg()返回一個來自參數的特定參數
func_num_args()返回參數的個數。
好,那麼接下來就寫一個和C#版本對應的PHP版本。
<?php function GetSum() { if(func_num_args()==0) { return 0; } $sum=0; for($i=0;$i<func_num_args();$i++) { $sum+=func_get_arg($i); } return $sum; } echo(GetSum(1,2,3,4)); ?>
4. 可變函數
我不知道為什麼要翻譯成這個名字,其實就是根據變量的名字來調用相應的函數。
很類似於JS中的這個eval,如下所示:
<script> function Execute(functionName) { eval(functionName+"()"); } function Test() { alert("111"); } Execute("Test"); </script>
這個就是傳進來一個函數名,然後來執行對應的函數。那麼在PHP中,其實也是一樣的,而且更簡單了。
<?php function Test($func) { $func(); } function First(){echo("first");} Test("First"); ?>