PHP進階(第八彈:函數)

基本語法

自定義函數語法如下:

function 函數名稱([參數名稱[=默認值]]) {
    函數體;
    return 返回值;
}

要注意,函數名稱不能包含特殊字符,可以包含數字字母下劃線,以字母或下劃線開頭。
函數名稱不區分大小寫。
函數名稱不支持重名,如果重名在運行時會報錯:Fatal eror: Cannot redeclare….。

可以使用funciton_exists檢測函數名稱是否存在,存在返回true,不存在返回false:

var_dump(funciton_exists('test'));

在函數體內使用全局變量

如下例,i和j是兩個全局變量,但是在函數體內也是無法直接訪問的,這樣會報錯:

<?php
$i=1;
$j=2;

function test(){
    var_dump($i,$j);
}

test();

通過global關鍵字或$GLOBALS超全局變量可以在函數體內訪問全局變量:

<?php
$i=1;
$j=2;

function test(){
    global $i;
    global $j;
    // 也可以寫在一行裏面:global $i,$j;
    var_dump($i,$j);

    // 也可以在函數體內使用global定義新的全局變量
    global $m;
    $m=3;

    // 還可以通過$GLOBALS超全局變量來訪問
    print_r($GLOBALS);
    echo $GLOBALS['i'];
    echo $GLOBALS['j'];
    // 也可以修改全局變量的值
    $GLOBALS['i']=10;
}

test();
var_dump($);

函數傳值和傳引用的區別

傳值:默認情況下,函數參數通過值傳遞,所以即使在函數內部改變參數的值也不會改變函數外部的值。
傳引用:可以通過在參數前添加&符號,代表通過引用傳遞參數,在函數內部對其所做更改會影響外部的值。

<?php
// 傳值
function test1($i){
    $i+=1;
}
function test2(&$i){
    $i+=1;
}
$i=2;
test1($i);
var_dump($i);// 輸出會是2
test2($i)
var_dump($i);// 輸出會是3
// 注意,只有變量才能當做引用被傳遞,
// 如果這麼寫:test2(3),會報錯:
// Fatal error:Only variables can be passed by reference...

特殊形式的函數

可變函數

在PHP中如果將函數名稱賦予字符串類型的變量,但是在使用該變量時,如果帶有小括號,那麼PHP引擎將解析爲函數,如:

<?php
header('content-type:text/html;charset=utf-8');
$funcName='md5';
echo $funcName('tom');// 相當於調用了md5('tom')

// 對於自定義函數也是如此
function test(){
    echo 'test';
}
$funcName='test';
$funcName();// 相當於調用了test()

要注意的是,可變函數不能用於像echo,print,unset(),isset(),empty(),include,require以及類似的語言結構,需要自己封裝之後實現。

回調函數

回調函數就是調用函數的時候將另一個函數的名稱當做參數傳遞進去,並且在函數體中進行調用。

<?php
header('content-type:text/html;charset=utf-8');
function hi(){
    echo 'Hi world!';
}
function hello(){
    echo 'Hello world!';
}
funtion sayWhat($funcName){
    $funcName();// 通過可變函數的形式進行調用
}

sayWhat('hello');

系統函數中也有應用了回調函數的,比較經常用到的有array_maparray_walkarray_filter

以上例子是通過可變函數的形式在函數體中進行調用的,還可以通過call_user_func()call_user_func_array()進行調用。如:

call_user_func('md5','abc');  // 調用md5函數,傳參數爲'abc'
call_user_func('test','1','2');  // 調用test函數,傳參數爲'1''2'
call_user_func_array('test',array('1','2'));  // 同上,調用test函數,以數組的形式傳參數'1''2'

匿名函數

匿名函數也叫閉包函數,允許臨時創建一個沒有指定名稱的函數,最經常用作回調函數參數的值。
匿名函數也可以作爲變量的值來使用。

匿名函數可以這樣定義:

$func=funciton(){
    return 'hello';
};
echo $func();

$func=funciton($name){
    return 'hello'.$name;
};
echo $func();

還可以通過create_function()來定義:

$func=create_function('','echo "hello";');
$func();

$func=create_function('$x,$y','return $x+$y');
echo $func(1,2);

不過這種方法比較難以使用。

遞歸函數

如果函數A需要調用函數B,而發現函數B的代碼實現與函數A完全相同,此時就需要封裝爲遞歸函數。
像PHP實現目錄的遍歷,目錄的複製、刪除非空目錄操作必須通過遞歸函數實現。無限極分類也可以通過遞歸實現。

遞歸函數通俗講就是自己調用自己的函數,通過特定條件結束執行。

包含文件

可以使用requirerequire_onceincludeinclude_once來包含文件,如:

<?php
require 'common.php';
...

使用requirerequire_once包含不存在的文件時,會產生一個致命錯誤和一個警告,程序終止執行。
使用includeinclude_once包含不存在的文件時,會產生兩個警告,程序繼續執行。
requirerequire_once的區別在於,require包含同一個文件多次時,就真的包含了多次,而require_once引用同一個文件多次時,只會包含一次。

發佈了165 篇原創文章 · 獲贊 47 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章