|
魔術(shù)函數(shù)
魔術(shù)函數(shù)是php中內(nèi)置的語(yǔ)言特性,當(dāng)程序執(zhí)行到某種情況時(shí),如果定義了這些魔術(shù)函數(shù)(php手冊(cè)中稱之為“Overloading”),則php會(huì)調(diào)用他們,同時(shí)也會(huì)傳入相應(yīng)的參數(shù),可以認(rèn)為是php執(zhí)行過程中的鉤子函數(shù)。常見的魔術(shù)函數(shù)有__construct, __destruct , __call, __get, __set, __isset, __unset __sleep, __wakeup, __toString, __clone 以及__autoload 。它們 可以用來(lái)自動(dòng)加載包含文件,實(shí)現(xiàn)延遲執(zhí)行(類似于.NET中的屬性訪問器)、垃圾回收、對(duì)象clone等操作,舉個(gè)__autoload的例子,其他魔術(shù)函數(shù)參見 Magic Method。
__autoload($class_name):用來(lái)自動(dòng)加載包含文件,省得include,require,對(duì)性能有一定影響,但一般情況下可忽略。
下面是一個(gè)簡(jiǎn)單的例子
function __autoload($class_name)
{
require_once $class_name . '.class.php';
}
把它放入common.php等全局包含文件中,當(dāng)新建一個(gè)對(duì)象時(shí),比如 $obj=new Class_A,如果php無(wú)法找到Class_A,則會(huì)把"Class_A" 作為參數(shù)$class_name,執(zhí)行 __autoload函數(shù)。這樣就可以達(dá)到自動(dòng)包含頭文件的目的了。
另外附贈(zèng)幾個(gè)常量和函數(shù):
__FILE__ :魔術(shù)常量,獲取當(dāng)前源代碼文件的路徑(含文件名)
__CLASS__:魔術(shù)常量,獲取當(dāng)前類的類名(區(qū)分大小寫的)。
array get_included_files ( void ):內(nèi)置函數(shù),返回通過include(), include_once(), require() 或require_once()包含的文件列表,但不包括通過php.ini配置文件中所設(shè)置的auto_prepend_file項(xiàng)。另外get_required_files()只是get_included_files ( void )的別名。
string dirname ( string path ):返回路徑中的目錄部分。
匿名函數(shù)
在php5.3以前使用匿名函數(shù),可以通過create_function()來(lái)創(chuàng)建匿名函數(shù),
$func=create_function('$a,$b', '
if ($a == $b)
{
return 0;
}
return ($a< $b) ? -1 : 1;
');
在php5.3中,可以直接使用lamda表達(dá)式
$func=function($a,$b)
{
if ($a == $b)
{
return 0;
}
return ($a< $b) ? -1 : 1;
}
然后可以作為參數(shù)傳入其他函數(shù),如:usort($arr,$func); 也可以直接調(diào)用,$func(3,4);
在php5.3中使用閉包
function foo($arg1)
{
$var=3;
$inner=function($innerArg) use($arg1,$var)
{
return $innerArg+$arg1/$var;
};
echo $inner(5);
}
閉包被當(dāng)成一個(gè)內(nèi)置類,但是沒有Javascript那么靈活,這個(gè)類不能有屬性。$inner->a=5;是非法的。
嵌套函數(shù)
嵌套函數(shù)可以在父函數(shù)體里面定義函數(shù),如:
function outer()
{
$out_var=1;
function inner()
{
var_dump($out_var);//輸出NULL,無(wú)法訪問到$out_var,聲明global也不行,$out_var不是全局變量
echo "call inner/n";
}
//echo "call outer/n";
inner();//如果不調(diào)用inner(),則在訪問outer()時(shí)也不會(huì)被調(diào)用
}
outer();
inner();//雖然,函數(shù)是全局的,必須先調(diào)用outer(),否則inner()調(diào)用會(huì)報(bào)錯(cuò)(函數(shù)未定義)
條件函數(shù)
$debug=false;
if($debug===true)
{
function foo()
{
echo "foo";
}
}
foo();
相當(dāng)于條件編譯了,從這里我們可以猜測(cè)到,為什么上文中outer()調(diào)用之前,inner()是無(wú)法調(diào)用的。因?yàn)?/SPAN>inner在outer()調(diào)用之前還未被“編譯”(只是猜測(cè),未深入研究)。
函數(shù)動(dòng)態(tài)調(diào)用
函數(shù)名可以是變量名。
function foo()
{
echo "call foo";
}
$func='foo';
$func();
此方式比較危險(xiǎn),建議使用白名單方式將可用的函數(shù)名寫在配置文件中,或者函數(shù)名都有統(tǒng)一前綴,比如$func="act_".$funcName;。另外在調(diào)用之前可用function_exists ($funcName)來(lái)檢查函數(shù)是否存在。
通過內(nèi)置函數(shù)調(diào)用函數(shù),call_user_func(callback function ,[, mixed parameter [, mixed ...]] ),對(duì)于不確定的函數(shù)名,確定的參數(shù)可以使用此函數(shù)調(diào)用,如果參數(shù)也不確定可以通過call_user_func_array( callback function, array param_arr )
另外,可以通過get_defined_functions()來(lái)獲取所有已定義的函數(shù)(注意是所有,包括內(nèi)置函數(shù))
調(diào)用類的方法則傳入一個(gè)數(shù)組作為參數(shù),此數(shù)組第一個(gè)元素是實(shí)例或類名,第二個(gè)元素是方法名:
class myclass
{
public $age=21;
function echo_age()
{
echo $this->age;
}
static function s_echo_age()
{
echo 22;
}
function i_echo_age()
{
echo 23;
}
}
$c=new myclass;
$classname = "myclass";
//調(diào)用實(shí)例方法,如果call_user_func(array($classname , 'echo_age'));則會(huì)報(bào)錯(cuò),$this未指向任何實(shí)例
call_user_func(array($c, 'echo_age'));
echo "/n";
//調(diào)用實(shí)例方法,如果沒有引用$this變量,則不會(huì)有問題
call_user_func(array($classname, 'i_echo_age'));
echo "/n";
//調(diào)用靜態(tài)方法,傳入類名或?qū)嵗?/SPAN>
call_user_func(array($classname, 's_echo_age'));
echo "/n";
call_user_func(array($c, 's_echo_age'));
獲取函數(shù)參數(shù)
通過此方式可以實(shí)現(xiàn)非常靈活的重載,但容易使邏輯變得負(fù)責(zé),適度使用。
func_get_arg ( int arg_num )獲取第arg_num個(gè)參數(shù)(從0開始計(jì)數(shù))
func_num_args()獲取參數(shù)總個(gè)數(shù)
func_get_args()獲取所有參數(shù)。
用三行代碼實(shí)現(xiàn)Gof中的一個(gè)設(shè)計(jì)模式:
function call_it($func)
{
$args=func_get_args();
array_shift($args);//去掉第一個(gè)參數(shù),那是函數(shù)名
call_user_func_array($func,$args);
}
function add($a,$b)
{
echo $a+$b;
}
function sqr($a)
{
echo $a*$a;
}
call_it('add',1,2);
echo "/n";
call_it('sqr',2);
php技術(shù):PHP函數(shù)常用用法小結(jié),轉(zhuǎn)載需保留來(lái)源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。