[TOC]
# 函數的定義
> 函數是什么?
函數(`function`)是一段完成指定任務的已命名代碼塊。函數可以遵照給它的一組值或參數完成特定的任務,并且可能返回一個值。在PHP中有兩種函數:`自定義函`數與`系統函數`。
函數的優越性:
* 控制程序設計的復雜性
* 提高軟件的可靠性
* 提高軟件的開發效率
* 提高軟件的可維護性
* 提高程序的重用性
# 自定義函數
#### 自定義函數語法格式:
創建函數
```
function 函數名稱([參數1 [,參數2 [,…]]]){
程序內容敘述(也叫函數體);
[return 返回值;] //如需函數有返回值時使用
}
```
調用函數:
```
函數名稱([參數1 [,參數2 [,…]]];
```
###### 1.自定義函數的名稱:
它是函數在程序代碼中的識別名稱,函數名可以是以字母或下劃線開頭后跟零個或多個字母、下劃線和數字的任何字符串。函數名不區分大小寫。命名函數時不可使用已聲明的函數,或PHP內建的函數名稱。
###### 2.參數:
所謂的參數就是用來把數值由函數外部傳入函數體中,并用來加以運算處理。參數之間用" ,"號隔開。當函數不需要任何數值傳入時,可以省略參數。
###### 3.返回值:
當調用函數時需要它返回一些數值,那么就要函數體中用return語句實現。格式如下:
```
return 返回值; //返回值也可以是一個表達式
exit(); //無返回值 void
```
實例:
```
<?php
echo "用函數求累加:<br>";
function test($a)
{
$sum=0;
for($i=0;$i<=$a;$i++)
$sum+=$i;
return $sum;
}
echo "50的累加是:".test(50)."<br>";
echo "100的累加是:".test(100)."<br>";
?>
```
在PHP中,函數可以在被調用之前定義,也可以在被調用之后定義。
`function_exists()` - - 判斷函數是否存在。
# PHP變量的范圍
#### 變量的范圍
當主程序調用函數時,PHP 會暫時停止目前主要程序流程的運行,并傳遞必要的運算參數給目標函數使用,以執行函數的程序碼片段。
在函數執行結束后,函數會回傳執行結果所得的數值,并將執行流程轉回原本主程序中斷的地方,繼續執行運作。
####變量的能見度
所謂變量的能見度,意指變量在程序中的可作用范圍。當一個變量執行賦值動作后,會隨著聲明局部的差異,而有不同的作用范圍。大致上來說變量會依據聲明的局部分為下列兩種:**局部變量**和**全局變量**
#### 局部變量(內部變量)
在函數之中聲明的變量就是局部變量,并且該變量只有在函數范圍之中才能加以使用。如果其它程序局部需要調用使用該變量值時,必須透過「return」指令,來將其傳回至主程序區塊以作后續處理。
```
<?php
$a=0;
function print_A(){
$a = 3; //定義局部變量
echo "在函數中顯示局部變量 a 值: $a <p>";
return $a;
}
$b = print_A();
echo "在函數外顯示局部變量 b 值: $b <br>";
echo $a;
?>
```
#### 全局變量
在函數范圍之外所聲明的變量就是全局變量。由于函數可以視為單獨的程序片段,所以局部變量會復蓋全局變量的能見度,因此在函數中并無法直接調用使用全局變量。
函數中若要使用全局變量時,必須要利用`global`關鍵字定義目標變量,以告訴函數主體此變量為全局。
```
<?php
$A="Hello !!"; //定義全局變量
function print_A() { //定義函數 print_A()
global $A; //利用 global 關鍵字聲明變量 A 為全局變量
echo $A;
}
print_A();
?>
```
也可以使用預定義的全局變量數組`$GLOBALS`.這是一個特殊變量在程序運行時自動創建。格式:`echo $GLOBALS["A"];`
> **注意事項**
在函數中聲明全局變量時,其名字要與全局變量一致
通過unset($var)可以手動刪除變量,變量會在內存中被釋放,也就不在全局作用域中了。
使用require與include包含不會影響作用域
通過參數列表傳遞給函數的變量,對于函數來說是局部變量,除非在傳遞時帶有&引用符號
#### 靜態變量
靜態變量只存在于函數作用域內。一般的函數內變量在函數結束后會釋放,比如局部變量,但是靜態變量卻不會。就是說,下次再調用這個函數的時候,該變量的值會保留下來。
只要在變量前加上關鍵字static,該變量就成為靜態變量了。
```
<?php
function test()
{
static $nm = 1;
$nm = $nm * 2;
print $nm."<br />";
}
// 第一次執行,$nm = 2
test();
// 第一次執行,$nm = 4
test();
// 第一次執行,$nm = 8
test();
?>
```
# 聲明及應用各種形式的PHP函數
> 無論是使用系統函數還是自定義的函數,我們都要可通過如下函數的三要素來了解一個函數:
* 函數的功能描述
* 函數的參數
* 函數的返回值
#### 常規參數的函數
常規參數的函數格式說明:
```
string example(string name,int age,double height)
```
所謂的常規參數的函數,就是實參和形參應該個數相等、類型一致。就像C或Java等強類型型語言。
上面函數有三個參數,調用時傳遞的參數個數和順序必須一致。
```
string chr(int $ascii) //返回指定的字符
float ceil(float $value) //進一法取整
array array_combine(array $keys,array $values)//合并一個數組
string implode(string $glue,array $pieces)
```
#### 偽類型參數的函數
偽類型參數的函數格式說明:
```
mixed funName(mixed $a, number $b, callback $c)
```
PHP是弱類型語言,不僅在聲明變量時不需要指定類型,當然在聲明函數時也不需要指定類型,所以在PHP中函數的每個參數,都可以為其傳遞任意類型的值。
三種偽類型: `mixed`、`number` 和 `callback`。
```
bool empty(mixed $var) //檢查一個變量是否為空
bool usort(array &$array,callback $cmp_function)
//使用用戶自定義的比較函數對數組中的值進行排序
number abs(mixed $number) //絕對值
```
#### 引用參數的函數
引用參數的函數格式說明:
```
void funName(array &args)
```
相對于按值傳遞模式,并不會將父程序中的指定數值或目標變量傳遞給函數,而是把該數值或變量的內存儲存區塊相對地址導入函數之中。因此當該數值在函數中有任何變動時,會連帶對父程序造成影響。
> 注意:如果在函數的形參中使用"&"修飾的參數,在調用該函數時必須傳入一個變量給這個參數,而是不能傳遞一個值。
```
<?php
//使用常規參數傳值
function test($arg) {
$arg = 200; //在函數中改變參數$a的值為200
}
$var = 100; //在父程序中聲明一個全局變量$var,初值為100
test($var); //調用test函數,并將變量$var的值100傳給函數的參數$arg
echo $var; //輸出100。$var的值沒有變化
//使用"&"引用參數傳值
function test( &$arg ) {
$arg = 200; //改變參數$a的值為200,$arg是引用參數,外部變量$var也被修改
}
$var = 100; //在父程序中聲明一個全局變量$var,初值為100
test($var); //調用test函數,并將變量$var的引用傳給函數的參數$arg
echo $var; //輸出200。$var的值在函數中修改變量$arg時被修改
?>
```
#### 默認參數的函數
默認參數("[ ]"中的)的函數格式說明:
```
mixed funName(string name [,string value [,int num]])
```
在php中,支持函數的默認方式調用。如果在調用函數時沒有指定參數的值,在函數中會使用參數的默認值。
> 注意:默認參數必須列在所有沒有默認值參數的后面。
```
<?php
/**
自定義一個函數名稱為person,用于打印一個人的屬性
@param string $name 人的名子屬性字符串,默認值為"張三"
@param int $age 人的年齡屬性,默認值為20
@param string $sex 人的性別屬性,默認值為"男"
*/
function person( $name="張三", $age=20, $sex="男" ){
echo "我的名字是:{$name}, 我的年齡為:{$age}, 性別: {$sex} <br>";
}
person(); //在調用函數時三個參數都沒有傳值,全部使用默認參數
person("李四"); //第一個默認參數被傳入的值覆蓋,后兩個參數使用默認參數
person("王五", 22); //前兩個默認參數被傳入的值覆蓋,最后一個使用默認參數
person("賈六", 18, "女"); //在調用函數時,三個默認參數都被傳入的值覆蓋
?>
```
#### 可變個數參數的函數
可變個數參數的函數格式說明:
```
mixed funName(string arg1 [,string ...] )
```
通常用戶定義函數時,設置的參數數量是有限的。如果希望函數可以接受任意數量的參數,需使用以下函數:
```
func_get_args() //返回一個數組,包含所有參數
func_num_args() //返回參數總數
func_get_arg() //接收一個數字參數,返回指定參數
```
```
<?php
/**
聲明一個函數more_args(),用于打印參數列表的值
雖然沒有聲明參數列表,但可以傳入任意個數,任意類型的參數值
*/
function more_args() {
$args = func_get_args(); //將所有傳遞給腳本函數的參數當做一個數組返回
for($i=0; $i<count($args); $i++) { //使用for循環遍歷數組$args
echo "第".$i."個參數是".$args[$i]."<br>"; //分別輸出傳入函數的每個參數
}
}
more_args("one", "two", "three", 1, 2, 3); //調用函數并輸入多個參數
function more_args() {
for($i=0; $i<func_num_args(); $i++) { //使用for循環遍歷數組$args
echo "第".$i."個參數是".func_get_arg($i)."<br>";//分別輸出傳入函數的每個參數
}
}
more_args("one", "two", "three", 1, 2, 3); //調用函數并輸入多個參數
?>
```
#### 回調函數
回調函數格式說明:
```
mixed funName(callback arg)
```
所謂回調函數,就是指調用函數時并不是傳遞一個標準的變量作為參數,而是將另一函數作為參數傳遞到調用的函數中。
1. 變量函數
2. 使用變量函數聲明和應用的回調函數
3. 借助call_user_func_array()函數自定義回調函數
4. 類靜態函數和對象的方法回調
###### 變量函數
```
<?php
/** 聲明第一個函數one, 計算兩個數的和
@param int $a 計算和的第一個運算元
@param int $b 計算和的第二個運算元
@return int 返回計算后的結果
*/
function one( $a, $b ) {
return $a + $b;
}
/** 聲明第二個函數two, 計算兩個數的平方和
*/
function two($a, $b) {
return $a*$b + $b*$b;
}
$result = "one"; //將函數名"one"賦給變量$result, 執行$result()時則調用函數one()
//$result = "two"; //將函數名"two"賦給變量$result, 執行$result()時則調用函數two()
echo "運算結果是:".$result(2, 3); //變量$result的函數名值,就調用哪個函數
?>
```
###### 回調函數
```
<?php
// 聲明回調函數filter, 在0-100的整數中通過自定義條件過濾不要的數字
function filter( $fun ) {
for($i=0; $i <= 100; $i++) {
//將參數變量$fun加上一個圓插號$fun(), 則為調用和變量$fun值同名的函數
if( $fun($i) )
continue;
echo $i.'<br>';
}
}
//聲明一個函數one, 如果參數是3的倍數就返回true, 否則返回false
function one($num) {
return $num%3 == 0;
}
// 聲明一個函數two, 如果參數是一個回文數(翻轉后還等于自己的數)返回true, 否則返回false
function two($num) {
return $num == strrev($num);
}
filter("one"); //打印出100以內非3的倍數,參數"one"是函數one()的名稱字符串,是一個回調
echo '--------------------<br>';
filter('two'); //打印出100以內非回文數,參數"two"是函數two()的名稱字符串,是一個回調
?>
```
###### 借助call_user_func_array()函數自定義回調函數
```
<?php
/** 聲明一個函數fun(), 功能只輸出兩個字符串,目的是作為call_user_func_array()回調參數
@param string $msg1 需要傳遞一個字符串作為參數
@param string $msg2 需要傳遞另一個字符串作為參數
*/
function fun($msg1, $msg2) {
echo '$msg1 = '.$msg1;
echo '<br>';
echo '$msg2 = '.$msg2;
}
/** 通過系統函數call_user_func_array() 調用函數fun()
第一個參數為函數fun()的名稱字符串
第二個參數則是一個數組,每個元素值會按順序傳遞給調用的fun()函數參數列表中
*/
call_user_func_array('fun', array('canshu1', 'canshu2'));
?>
```
###### 匿名函數
匿名函數(Anonymous functions),也叫閉包函數(closures),允許 臨時創建一個沒有指定名稱的函數。最經常用作回調函數(callback)參數的值。當然,也有其它應用的情況。
```
<?php
$greet?=?function($name){
printf("Hello?%s\r\n",?$name);
};
$greet('World');
$greet('PHP');
?>
```
###### 遞歸函數
* 所謂的函數遞歸調用,就是函數可以在其聲明的執行敘述之中調用執行自己。
* 通常在此類型的函數之中會附加一個條件判斷敘述,以判斷是否需要執行遞歸調用,并且在特定條件下終止函數的遞歸調用動作,把目前流程的主控權交回上一層函數執行。因此當某個執行遞歸調用的函數,沒有附加條件判斷敘述時可能會造成無限循環的錯誤情形.
* 函數遞歸調用最大的好處在于可以精簡程序中繁雜重復調用程序,并且能以這種特性來執行一些較為復雜的運算動作。
```
<?php
/**
聲明一個名稱為test的函數,用于測試遞歸
$param int $n 需要一個整數作為參數
*/
function test( $n ) { //聲明一個名為test的函數,有一個參數
echo $n."??"; //在函數開始處輸出參數的值和兩個空格
if($n>0){ //判斷參數是否大于0
test($n-1); //如果參數大于0則調用自己,并將參數減1后再傳入
}else{ //判斷參數不大于0
echo " <--> "; //輸出分界字符串
}
echo $n."??"; //在函數結束處輸出參數的值和兩個空格
}
test(10); //調用test()函數將整數10傳給參數
?>
```
#### 使用自定義函數庫
代碼重用:
* 通過重復使用已有的代碼,提高開發效率,降低成本
`include( )`和`require( )` 函數。
* require( )將一個文件在預處理期間被導入,像把該文件粘貼到使用函數的地方。
* include( )與require ( )幾乎等價,區別在于在腳本執行時包含,當處理失敗時,include( )產生一個警告而require( )則導致一個致命錯誤。
> ##include_once( )和require_once( )函數##
兩個函數在腳本執行期間包括并運行指定文件。與include( )語句及require( )類似,唯一區別是如果該文件中的代碼已經被包括了,則不會再次包括,只會包括一次。這兩個函數應該用于在腳本執行期間同一個文件有可能被包括超過一次的情況下,你想確保它只被包括一次以避免函數重定義,變量重新賦值等問題。
***
>Have a try
使用循環語句實現下列代碼:要求時間的每個圖像(要求圖像的都使用函數定義)

- 前言
- Ⅰ.PHP基礎知識
- 1.PHP基本語法(一)
- 2.PHP基本語法(二)
- 3.流程控制結構
- 4.PHP函數
- 5.數組
- 6.字符串
- 7.PHP正則表達式
- 8.PHP的日期和時間
- 9.GD庫圖像處理
- 10.文件處理系統
- 11.文件上傳和下載
- 12.數據庫之MySQL(概述)
- Ⅱ.ThinkPHP5入門實踐
- 一、先看到頁面
- 1.1只展示頁面
- 1.2給視圖傳遞數據
- 1.3使用公共模板
- 1.4使用模板布局
- 二、簡單的數據庫操作
- (1)查
- (2)增
- (3)改
- (4)刪
- (5)鏈式操作
- 三、初級-階段性綜合應用
- (1)注冊
- (2)登錄
- 四、各種基本操作
- 1.操作Session
- 2.操作Cookie
- 3.文件上傳
- 五、富文本編輯器
- 集成wangEditor
- 集成UEditor
- 六、驗證碼
- 圖片驗證碼
- Ⅲ.常用類庫的使用
- 一、PHPExcel表格導入
- 二、PHPExcel表格導出
- 三、阿里大于短信驗證碼
- 四、時間戳操作Time
- 五、郵件發送
- 六、PHP操作Python
- Ⅳ.實例講解
- 一、病房管理系統
- 寫在前面
- 1.引導頁
- 2.公共模板
- 3.登錄
- 4.功能引導頁集合
- 5.修改密碼
- 6.員工信息注冊
- 7.員工信息更新
- 8.員工信息刪除
- 9.病人信息注冊
- 10.病人信息更新
- 11.出院手續辦理
- 12.病人信息刪除
- 13.科室信息查詢
- 14.醫護信息查詢
- 15.病房信息查詢
- 16.病歷信息查詢
- 加群驗證
- 必看推薦閱讀【不斷更新】