<P style="FONT-SIZE: 12pt; MARGIN: 0in; COLOR: #366092; FONT-FAMILY: 宋体"><SPAN style="FONT-WEIGHT: bold">魔术函数
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in"><SPAN style="FONT-FAMILY: 宋体">魔术函数是<SPAN style="FONT-FAMILY: 'Courier New'">PHP<SPAN style="FONT-FAMILY: 宋体">中内置的语言特性,当程序执行到某种情况时,如果定义了这些魔术函数<SPAN style="FONT-FAMILY: 'Courier New'">(PHP<SPAN style="FONT-FAMILY: 宋体">手册中称之为“<SPAN style="FONT-FAMILY: 'Courier New'">Overloading<SPAN style="FONT-FAMILY: 宋体">”<SPAN style="FONT-FAMILY: 'Courier New'">)<SPAN style="FONT-FAMILY: 宋体">,则<SPAN style="FONT-FAMILY: 'Courier New'">PHP<SPAN style="FONT-FAMILY: 宋体">会调用他们,同时也会传入相应的参数,可以认为是<SPAN style="FONT-FAMILY: 'Courier New'">PHP<SPAN style="FONT-FAMILY: 宋体">执行过程中的钩子函数。常见的魔术函数有<SPAN style="FONT-FAMILY: 'Courier New'">construct,destruct,call,get,set,isset,unsetsleep,wakeup,toString,clone <SPAN style="FONT-FAMILY: 宋体">以及<SPAN style="FONT-FAMILY: 'Courier New'">autoload <SPAN style="FONT-FAMILY: 宋体">。它们 <SPAN style="FONT-FAMILY: 宋体">可以用来自动加载包含文件,实现延迟执行(类似于<SPAN style="FONT-FAMILY: 'Courier New'">.Net<SPAN style="FONT-FAMILY: 宋体">中的属性访问器)、垃圾回收、对象<SPAN style="FONT-FAMILY: 'Courier New'">clone<SPAN style="FONT-FAMILY: 宋体">等操作,举个<SPAN style="FONT-FAMILY: 'Courier New'">autoload<SPAN style="FONT-FAMILY: 宋体">的例子,其他魔术函数参见 <SPAN style="FONT-FAMILY: 'Courier New'">Magic Method<SPAN style="FONT-FAMILY: 宋体">。
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in"><SPAN style="FONT-FAMILY: 'Courier New'">autoload($class_name)<SPAN style="FONT-FAMILY: 宋体">:用来自动加载包含文件,省得<SPAN style="FONT-FAMILY: 'Courier New'">include<SPAN style="FONT-FAMILY: 宋体">,<SPAN style="FONT-FAMILY: 'Courier New'">require<SPAN style="FONT-FAMILY: 宋体">,对性能有一定影响,但一般情况下可忽略。
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 宋体">下面是一个简单的例子
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">function autoload($class_name)
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">{
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">require_once $class_name . '.class.PHP';
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">}
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in"><SPAN style="FONT-FAMILY: 宋体">把它放入<SPAN style="FONT-FAMILY: 'Courier New'">common.PHP<SPAN style="FONT-FAMILY: 宋体">等全局包含文件中,当新建一个对象时,比如<SPAN style="FONT-FAMILY: 'Courier New'"> $obj=new Class_A<SPAN style="FONT-FAMILY: 宋体">,如果<SPAN style="FONT-FAMILY: 'Courier New'">PHP<SPAN style="FONT-FAMILY: 宋体">无法找到<SPAN style="FONT-FAMILY: 'Courier New'">Class_A<SPAN style="FONT-FAMILY: 宋体">,则会把<SPAN style="FONT-FAMILY: 'Courier New'">"Class_A" <SPAN style="FONT-FAMILY: 宋体">作为参数<SPAN style="FONT-FAMILY: 'Courier New'">$class_name<SPAN style="FONT-FAMILY: 宋体">,执行<SPAN style="FONT-FAMILY: 'Courier New'"> autoload<SPAN style="FONT-FAMILY: 宋体">函数。这样就可以达到自动包含头文件的目的了。
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: Calibri">
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 宋体">另外附赠几个常量和函数:
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in"><SPAN style="FONT-FAMILY: 'Courier New'">FILE <SPAN style="FONT-FAMILY: 宋体">:魔术常量,获取当前源代码文件的路径(含文件名)
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in"><SPAN style="FONT-FAMILY: 'Courier New'">CLASS<SPAN style="FONT-FAMILY: 宋体">:魔术常量,获取当前类的类名(区分大小写的)。
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in"><SPAN style="FONT-FAMILY: 'Courier New'">array get_included_files ( void )<SPAN style="FONT-FAMILY: 宋体">:内置函数,返回通过<SPAN style="FONT-FAMILY: 'Courier New'">include(),include_once(),require() <SPAN style="FONT-FAMILY: 宋体">或<SPAN style="FONT-FAMILY: 'Courier New'">require_once()<SPAN style="FONT-FAMILY: 宋体">包含的文件列表,但不包括通过<SPAN style="FONT-FAMILY: 'Courier New'">PHP.ini<SPAN style="FONT-FAMILY: 宋体">配置文件中所设置的<SPAN style="FONT-FAMILY: 'Courier New'">auto_prependfile<SPAN style="FONT-FAMILY: 宋体">项。另外<SPAN style="FONT-FAMILY: 'Courier New'">getrequired_files<SPAN style="FONT-FAMILY: 'Courier New'">()<SPAN style="FONT-FAMILY: 宋体">只是<SPAN style="FONT-FAMILY: 'Courier New'">get_included_files ( void )<SPAN style="FONT-FAMILY: 宋体">的别名。
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in"><SPAN style="FONT-FAMILY: 'Courier New'">string dirname ( string path )<SPAN style="FONT-FAMILY: 宋体">:返回路径中的目录部分。
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">
<P style="FONT-SIZE: 12pt; MARGIN: 0in; COLOR: #366092; FONT-FAMILY: 宋体"><SPAN style="FONT-WEIGHT: bold">匿名函数
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in"><SPAN style="FONT-FAMILY: 宋体">在<SPAN style="FONT-FAMILY: 'Courier New'">PHP5.3<SPAN style="FONT-FAMILY: 宋体">以前使用匿名函数,可以通过<SPAN style="FONT-FAMILY: 'Courier New'">create_function<SPAN style="FONT-FAMILY: 'Courier New'">()<SPAN style="FONT-FAMILY: 宋体">来创建匿名函数,
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">$func=create_function('$a,$b','
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">if ($a == $b)
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">{
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">return 0;
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">}
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">return ($a< $b) ? -1 : 1;
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">');
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in"><SPAN style="FONT-FAMILY: 宋体">在<SPAN style="FONT-FAMILY: 'Courier New'">PHP5.3<SPAN style="FONT-FAMILY: 宋体">中,可以直接使用<SPAN style="FONT-FAMILY: 'Courier New'">lamda<SPAN style="FONT-FAMILY: 宋体">表达式
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">$func=function($a,$b)
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">{
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 'Courier New'">if ($a == $b)
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 'Courier New'">{
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 'Courier New'">return 0;
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 'Courier New'">}
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 'Courier New'">return ($a< $b) ? -1 : 1;
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">}
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in"><SPAN style="FONT-FAMILY: 宋体">然后可以作为参数传入其他函数,如:<SPAN style="FONT-FAMILY: 'Courier New'">usort($arr,$func); <SPAN style="FONT-FAMILY: 宋体">也可以直接调用,<SPAN style="FONT-FAMILY: 'Courier New'">$func(3,4);
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in"><SPAN style="FONT-FAMILY: 宋体">在<SPAN style="FONT-FAMILY: 'Courier New'">PHP5.3<SPAN style="FONT-FAMILY: 宋体">中使用闭包
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">function foo($arg1)
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">{
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 'Courier New'">$var=3;
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 'Courier New'">$inner=function($innerArg) use($arg1,$var)
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 'Courier New'">{
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 'Courier New'"> return $innerArg+$arg1/$var;
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 'Courier New'">};
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 'Courier New'">echo $inner(5);
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">}
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in"><SPAN style="FONT-FAMILY: 宋体">闭包被当成一个内置类,但是没有<SPAN style="FONT-FAMILY: 'Courier New'">javascript<SPAN style="FONT-FAMILY: 宋体">那么灵活,这个类不能有属性。<SPAN style="FONT-FAMILY: 'Courier New'">$inner->a=5;<SPAN style="FONT-FAMILY: 宋体">是非法的。
<P style="FONT-SIZE: 12pt; MARGIN: 0in; COLOR: #366092; FONT-FAMILY: Calibri">
<P style="FONT-SIZE: 12pt; MARGIN: 0in; COLOR: #366092; FONT-FAMILY: 宋体"><SPAN style="FONT-WEIGHT: bold">嵌套函数
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 宋体">嵌套函数可以在父函数体里面定义函数,如:
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">function outer()
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">{
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'"> $out_var=1;
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'"> function inner()
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'"> {
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in"><SPAN style="FONT-FAMILY: 'Courier New'"> var_dump($out_var);<SPAN style="FONT-FAMILY: 'Courier New'">//<SPAN style="FONT-FAMILY: 宋体">输出<SPAN style="FONT-FAMILY: 'Courier New'">NULL<SPAN style="FONT-FAMILY: 宋体">,无法访问到<SPAN style="FONT-FAMILY: 'Courier New'">$out_var<SPAN style="FONT-FAMILY: 宋体">,声明<SPAN style="FONT-FAMILY: 'Courier New'">global<SPAN style="FONT-FAMILY: 宋体">也不行,<SPAN style="FONT-FAMILY: 'Courier New'">$out_var<SPAN style="FONT-FAMILY: 宋体">不是全局变量
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'"> echo "call inner\n";
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'"> }
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'"> //echo "call outer\n";
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in"><SPAN style="FONT-FAMILY: 'Courier New'"> inner();<SPAN style="FONT-FAMILY: 'Courier New'">//<SPAN style="FONT-FAMILY: 宋体">如果不调用<SPAN style="FONT-FAMILY: 'Courier New'">inner(),<SPAN style="FONT-FAMILY: 宋体">则在访问<SPAN style="FONT-FAMILY: 'Courier New'">outer()<SPAN style="FONT-FAMILY: 宋体">时也不会被调用
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">}
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">outer();
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in"><SPAN style="FONT-FAMILY: 'Courier New'">inner();<SPAN style="FONT-FAMILY: 'Courier New'">//<SPAN style="FONT-FAMILY: 宋体">虽然,函数是全局的,必须先调用<SPAN style="FONT-FAMILY: 'Courier New'">outer()<SPAN style="FONT-FAMILY: 宋体">,否则<SPAN style="FONT-FAMILY: 'Courier New'">inner()<SPAN style="FONT-FAMILY: 宋体">调用会报错(函数未定义)
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">
<P style="FONT-SIZE: 12pt; MARGIN: 0in; COLOR: #366092; FONT-FAMILY: 宋体"><SPAN style="FONT-WEIGHT: bold">条件函数
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">$debug=false;
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">if($debug===true)
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">{
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'"> function foo()
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'"> {
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'"> echo "foo";
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'"> }
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">}
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">foo();
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in"><SPAN style="FONT-FAMILY: 宋体">相当于条件编译了,从这里我们可以猜测到,为什么上文中<SPAN style="FONT-FAMILY: 'Courier New'">outer()<SPAN style="FONT-FAMILY: 宋体">调用之前,<SPAN style="FONT-FAMILY: 'Courier New'">inner()<SPAN style="FONT-FAMILY: 宋体">是无法调用的。因为<SPAN style="FONT-FAMILY: 'Courier New'">inner<SPAN style="FONT-FAMILY: 宋体">在<SPAN style="FONT-FAMILY: 'Courier New'">outer()<SPAN style="FONT-FAMILY: 宋体">调用之前还未被“编译”(只是猜测,未深入研究)。
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 宋体">
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">
<P style="FONT-SIZE: 12pt; MARGIN: 0in; COLOR: #366092; FONT-FAMILY: 宋体"><SPAN style="FONT-WEIGHT: bold">函数动态调用
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: Calibri">
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 宋体">函数名可以是变量名。
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">function foo()
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">{
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 'Courier New'">echo "call foo";
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">}
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">$func='foo';
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">$func();
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in"><SPAN style="FONT-FAMILY: 宋体">此方式比较危险,建议使用白名单方式将可用的函数名写在配置文件中,或者函数名都有统一前缀,比如<SPAN style="FONT-FAMILY: 'Courier New'">$func="act_".$funcName;<SPAN style="FONT-FAMILY: 宋体">。另外在调用之前可用<SPAN style="FONT-FAMILY: 'Courier New'">function_exists<SPAN style="FONT-FAMILY: 'Courier New'">($funcName)<SPAN style="FONT-FAMILY: 宋体">来检查函数是否存在。
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 宋体">
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in"><SPAN style="FONT-FAMILY: 宋体">通过内置函数调用函数,<SPAN style="FONT-FAMILY: 'Courier New'">call_user_func<SPAN style="FONT-FAMILY: 'Courier New'">(<SPAN style="FONT-FAMILY: 'Courier New'">callback function <SPAN style="FONT-FAMILY: 'Courier New'">,<SPAN style="FONT-FAMILY: 'Courier New'">[,mixed parameter [,mixed ...]] <SPAN style="FONT-FAMILY: 'Courier New'">)<SPAN style="FONT-FAMILY: 宋体">,对于不确定的函数名,确定的参数可以使用此函数调用,如果参数也不确定可以通过<SPAN style="FONT-FAMILY: 'Courier New'">call_user_func_array( callback function,array param_arr )
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in"><SPAN style="FONT-FAMILY: 宋体">另外,可以通过<SPAN style="FONT-FAMILY: 'Courier New'">get_defined_functions<SPAN style="FONT-FAMILY: 'Courier New'">()<SPAN style="FONT-FAMILY: 宋体">来获取所有已定义的函数(注意是所有,包括内置函数)
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 宋体">调用类的方法则传入一个数组作为参数,此数组第一个元素是实例或类名,第二个元素是方法名:
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">class myclass
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">{
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'"> public $age=21;
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 'Courier New'">
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'"> function echo_age()
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'"> {
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'"> echo $this->age;
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'"> }
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'"> static function s_echo_age()
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'"> {
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'"> echo 22;
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'"> }
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'"> function i_echo_age()
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'"> {
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'"> echo 23;
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'"> }
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">}
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">$c=new myclass;
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">$classname = "myclass";
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in"><SPAN style="FONT-FAMILY: 'Courier New'">//<SPAN style="FONT-FAMILY: 宋体">调用实例方法,如果<SPAN style="FONT-FAMILY: 'Courier New'">call_user_func(array($classname,'echo_age'));<SPAN style="FONT-FAMILY: 宋体">则会报错,<SPAN style="FONT-FAMILY: 'Courier New'">$this<SPAN style="FONT-FAMILY: 宋体">未指向任何实例
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">call_user_func(array($c,'echo_age'));
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">echo "\n";
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in"><SPAN style="FONT-FAMILY: 'Courier New'">//<SPAN style="FONT-FAMILY: 宋体">调用实例方法,如果没有引用<SPAN style="FONT-FAMILY: 'Courier New'">$this<SPAN style="FONT-FAMILY: 宋体">变量,则不会有问题
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">call_user_func(array($classname,'i_echo_age'));
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">echo "\n";
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in"><SPAN style="FONT-FAMILY: 'Courier New'">//<SPAN style="FONT-FAMILY: 宋体">调用静态方法,传入类名或实例均可
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">call_user_func(array($classname,'s_echo_age'));
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">echo "\n";
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">call_user_func(array($c,'s_echo_age'));
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">
<P style="FONT-SIZE: 12pt; MARGIN: 0in; COLOR: #366092; FONT-FAMILY: 宋体"><SPAN style="FONT-WEIGHT: bold">获取函数参数
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: Calibri">
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 宋体">通过此方式可以实现非常灵活的重载,但容易使逻辑变得负责,适度使用。
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in"><SPAN style="FONT-FAMILY: 'Courier New'">func_get_arg ( int arg_num )<SPAN style="FONT-FAMILY: 宋体">获取第<SPAN style="FONT-FAMILY: 'Courier New'">arg_num<SPAN style="FONT-FAMILY: 宋体">个参数(从<SPAN style="FONT-FAMILY: 'Courier New'">0<SPAN style="FONT-FAMILY: 宋体">开始计数)
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in"><SPAN style="FONT-FAMILY: 'Courier New'">func_num_args<SPAN style="FONT-FAMILY: 'Courier New'">()<SPAN style="FONT-FAMILY: 宋体">获取参数总个数
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in"><SPAN style="FONT-FAMILY: 'Courier New'">func_get_args<SPAN style="FONT-FAMILY: 'Courier New'">()<SPAN style="FONT-FAMILY: 宋体">获取所有参数。
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 宋体">
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in"><SPAN style="FONT-FAMILY: 宋体">用三行代码实现<SPAN style="FONT-FAMILY: Calibri">Gof<SPAN style="FONT-FAMILY: 宋体">中的一个设计模式<SPAN style="FONT-FAMILY: 'Courier New'">:
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">function call_it($func)
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">{
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 'Courier New'">$args=func_get_args();
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in 0in 0in 0.375in"><SPAN style="FONT-FAMILY: 'Courier New'">array_shift($args);<SPAN style="FONT-FAMILY: 'Courier New'">//<SPAN style="FONT-FAMILY: 宋体">去掉第一个参数,那是函数名
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 'Courier New'">call_user_func_array($func,$args);
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">}
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">function add($a,$b)
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">{
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'"> echo $a+$b;
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">}
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">function sqr($a)
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">{
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'"> echo $a*$a;
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">}
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">call_it('add',1,2);
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">echo "\n";
<P style="FONT-SIZE: 10.5pt; MARGIN: 0in; FONT-FAMILY: 'Courier New'">call_it('sqr',2);