從本章中,我們瞭解
.建立可以調用的函數以便重用代碼
.把參數傳遞給函數並且從函數傳回值和指令碼的不同部分中的變數和資料進行互動
.把代碼和函數組存入到其他檔案中,並且我們的指令碼內包含這些檔案.
3.1基本代碼重用:函數
3.1.1 定義和調用函數
關鍵字function通知php這是一個函數,後面跟著的是函數的名稱,它可以是字母、數字、字元或底線
函數名稱之後是參數列表,然後是函數體。在其它語言中名稱相同、但是參數列表不同的函數,php不支援這一特性。 複製代碼 代碼如下:<?php
function booo_spooky()
{
echo "I am booo_spooky. This name is okay!<br/>\n";
}
function ____333434343434334343()
{
echo <<<DONE
I am ____333434343434334343. This is an awfully
unreadable function name. But it is valid.
DONE;
}
//
// This next function name generates:
//
// Parse error: syntax error, unexpected T_LNUMBER,
// expecting T_STRING in
// /home/httpd/www/phpwebapps/src/chapter03/playing.php
// on line 55
//
// Function names cannot start with numbers
//
function 234letters()
{
echo "I am not valid<br/>\n";
}
//
// Extended characters are ok.
//
function grüß_dich()
{
echo "Extended Characters are ok, but be careful!<br/>\n";
}
//
// REALLY extended characters are ok too!! Your file will
// probably have to be saved in a Unicode format though,
// such as UTF-8 (See Chapter 5).
//
function 日本語のファンクション()
{
echo <<<EOT
Even Japanese characters are ok in function names, but be
extra careful with these (see Chapter 5).
EOT;
}
?>
3.1.2 把參數傳遞給函數
基本文法:為了把參數傳遞給函數,在調用函數時需要把參數值 括在括弧中,以逗號分隔。每個被傳遞的參數可
以是任何合法運算式,可以是變數、常量值、運算子的結果,甚至可以是函數調用。 複製代碼 代碼如下:<?php
function my_new_function($param1, $param2, $param3, $param4)
{
echo <<<DONE
You passed in: <br/>
\$param1: $param1 <br/>
\$param2: $param2 <br/>
\$param3: $param3 <br/>
\$param4: $param4 <br/>
DONE;
}
//
// call my new function with some values.
//
$userName = "bobo";
$a = 54;
$b = TRUE;
my_new_function($userName, 6.22e23, pi(), $a or $b);
?>
按引用傳遞:預設情況下,只有變數的值被傳遞給函數。因此,對這個參數或者變數的任何改動都只是在函數局部有效 複製代碼 代碼如下:$x = 10;
echo "\$x is: $x<br/>\n";
function change_parameter_value($param1)
{
$param1 = 20;
}
echo "\$x is: $x<br/>\n";
?>
輸出: $x is :10
$x is :10
如果你的目的是函數實際地修改傳遞給它的變數,而不僅僅處理其值的拷貝,那麼可以用引用(reference)傳遞的功能。這是通過使用&字元完成的
複製代碼 代碼如下:<?php
function increment_variable(&$increment_me)
{
if (is_int($increment_me) || is_float($increment_me))
{
$increment_me += 1;
}
}
$x = 20.5;
echo "\$x is: $x <br/>\n"; // prints 20.5
increment_variable(&$x);
echo "\$x is now: $x <br/>\n"; // prints 21.5
?>
參數的預設值
在你期望參數具有支配地位的特定值的情況下,稱為預設參數值(default argumentvalue) 複製代碼 代碼如下:<?php
function perform_sort($arrayData, $param2 = "qsort")
{
switch ($param)
{
case "qsort":
qsort($arrayData);
break;
case "insertion":
insertion_sort($arrayData);
break;
default:
bubble_sort($arrayData);
break;
}
}
?>
可變數量的參數:
php能夠把任意數量的參數傳遞給函數,然後使用func_num_args、func_get_arg和func_get_args取得參數值 複製代碼 代碼如下:<?php
function print_parameter_values()
{
$all_parameters = func_get_args();
foreach ($all_parameters as $index => $value)
{
echo "Parameter $index has the value: $value<br/>\n";
}
echo "-----<br/>\n";
}
print_parameter_values(1, 2, 3, "fish");
print_parameter_values();
?>
3.1.3 從函數傳回值
一些其他語言把在退出之前只執行一些代碼的子常式和執行一引起代碼並且把值返回調用者的函數區分開來,php和它們不同,所有php函數在返回調用者時
都有一個值和它相關聯。對於沒有明確的傳回值的函數,傳回值為null 複製代碼 代碼如下:<?php
function does_nothing()
{
}
$ret = does_nothing();
echo '$ret: ' . (is_null($ret) ? '(null)' : $ret) . "<br/>";
?>
如果希望返回非null時,利用return把它和一個運算式關聯 複製代碼 代碼如下:<?php
function is_even_number($number)
{
if (($number % 2) == 0)
return TRUE;
else
return FALSE;
}
?>
當你希望從函數返回多個值 時,把結果作為數組傳遞迴來是方便的方式 複製代碼 代碼如下:<?php
function get_user_name($userid)
{
//
// $all_user_data is a local variable (array) that temporarily
// holds all the information about a user.
//
$all_user_data = get_user_data_from_db($userid);
//
// after this function returns, $all_user_data no
// longer exists and has no value.
//
return $all_user_data["UserName"];
}
?>
3.1.4 函數內的變數範圍
函數層級變數:
聲明它們的函數內是合法,並且在函數的調用之間不記憶它們的值 複製代碼 代碼如下:<?php
$name = "Fatima";
echo "\$name: $name<br/>\n";
function set_name($new_name)
{
echo "\$name: $name<br/>\n";
$name = $new_name;
}
set_name("Giorgio");
echo "\$name: $name<br/>\n";
?>
靜態變數:
static作為首碼的變數在函數調用之間保持它們的值不變,如果聲明變數時為其賦值了,在運行當前指令碼時,php只在第一次遇到這個變數時執行賦值 複製代碼 代碼如下:<?php
function increment_me()
{
// the value is set to 10 only once.
static $incr=10;
$incr++;
echo"$incr<br/>\n";
}
increment_me();
increment_me();
increment_me();
?>
指令碼內聲明的變數("全域變數") 複製代碼 代碼如下:<?php
$name = "Fatima";
echo "\$name: $name<br/>\n";
function set_name($new_name)
{
echo "\$name: $name<br/>\n";
$name = $new_name;
}
set_name("Giorgio");
echo "\$name: $name<br/>\n";
?>
l輸出結果:
$name: Fatima
$name:
$name: Fatima
如果在 內部組函數加一個globa ,那麼輸出結果
$name: Fatima
$name: Fatima
$name: Giorgio
3.1.5 函數範圍和可用性
3.1.6 把函數作為變數使用 複製代碼 代碼如下:<?php
function Log_to_File($message)
{
// open file and write message
}
function Log_to_Browser($message)
{
// output using echo or print functions
}
function Log_to_Network($message)
{
// connect to server and print message
}
//
// we're debugging now, so we'll just write to the screen
//
$log_type = "Log_to_Browser";
//
// now, throughout the rest of our code, we can just call
// $log_type(message) and change where it goes by simply
// changing the above variable assignment!
//
$log_type("beginning debug output");
?>
但是php包含很多不能用作變數函數的語言結構,這種結構的明顯例子是echo、print、var_dump、print_r、isset、unset、is_null is_type
3.2 中級代碼重用:使用和包含檔案
3.2.1 把程式碼群組織到檔案中
對通用功能進行分組: 如果希望把很多函數儲存到單一位置上,典型情況是一個檔案,即程式碼程式庫(code library)
產生一致的介面 複製代碼 代碼如下:<?php
// circle is (x, y) + radius
function compute_circle_area($x, $y, $radius)
{
return ($radius * pi() * pi());
}
function circle_move_location(&$y, &$x, $deltax, $deltay)
{
$x += $deltax;
$y += $deltay;
}
function compute_circumference_of_circle($radius)
{
return array("Circumference" => 2 * $radius * pi());
}
?>
通過使用這此函數具有一致的名稱、參數順序以及傳回值 ,可以顯著地減少失敗的可能性和代碼中的缺陷。 複製代碼 代碼如下:<?php
//
// all routines in this file assume a circle is passed in as
// an array with:
// "X" => x coord "Y" => y coord "Radius" => circle radius
//
function circles_compute_area($circle)
{
return $circle["Radius"] * $circle["Radius"] * pi();
}
function circles_compute_circumference($circle)
{
return 2 * $circle["Radius"] * pi();
}
// $circle is passed in BY REFERENCE and modified!!!
function circles_move_circle(&$circle, $deltax, $deltay)
{
$circle["X"] += $deltax;
$circle["Y"] += $deltay;
}
?>
3.2.2 選擇檔案名稱和位置
為了防止web使用者開啟.inc檔案,我們使用兩種機制防止這種情況發生,首先,在構成文檔分類樹中,我們確保web伺服器不允許使用者瀏覽或者載入
不希望他們進行這些操作,在16章保護web應用程式中介紹,然後,然後將配置瀏覽器允許使用者瀏覽.php和.html檔案,但是不能瀏覽.inc檔案
防止這種問題的第二個途徑不把代碼入在文檔樹中,或存入其它目錄,並且要麼明確地在我們的代碼中引用這個目錄,通知php總是查看這個目錄
3.2.3 在指令碼中包含庫檔案
include 和require,這兩個區別在於,當找不到檔案時,require輸出錯誤,而include輸出警告。 複製代碼 代碼如下:<?php
include('i_dont_exit.inc');
require('i_dont_exit.inc');\
?>
include和require在哪裡尋找檔案
你可以指定明確的路經:
require("/home/httpd/lib/frontend/table_gen.inc');
require('http://www.cnblogs.com/lib/datafuncs.inc');
require(d:\webapps\libs\data\connetions.inc');
如果沒有指定明確路徑,php就在目前的目錄中尋找要包含的檔案,然後尋找php.ini檔案中的include_path設定中列出的目錄.
在windows是include_path=".;c:\php\include;d:\webapps\libs“設定完成後,不要忘記重新啟動web伺服器。
include和require做了什麼
包含在指令碼標記中的任何內容都作為一般 php指令碼處理。
清單3-1和清單3-2顯示php指令碼和用於包含的簡單檔案
清單3-1
3.2.4 把包含用於頁面模板化
<p align='center'>
<b>
<?php echo $message; ?>
</b>
</p>
清單3-2 複製代碼 代碼如下:<html>
<head>
<title>Sample</title>
</head>
<body>
<?php
$message = "Well, Howdy Pardner!";
include('printmessage.inc');
?>
</body>
</html>
檔案包含和函數範圍
當把函數從指令碼移動到包含檔案時,會如何影響函數作用範圍及調用它們的能力。
如果一個函數在另一個檔案中,並且這個檔案沒有通過include和require包含在當前指令碼中,那麼調用是非法的
為了避免這個問題,在指令碼開頭包含其他檔案是個好主意。
當共用變成問題時
為了避免重複載入共用檔案,可以用require_once()和include_once()語言結構防止函數或者結構重複定義的問題