在 Node.js 模块库中有很多好用的模块。接下来我们为大家介绍几种常用模块的使用: 序号 模块名 & 描述 1 OS…
August 24, 2016
PHP: 在类(class)中加载动态函数, 变量函数或半变量函数 variable function/method
最终实例在下方
以前用过cakephp, 他们的数据库查询还是蛮强大的, 后来好奇它的类的写法,比如:
<?php $this->Post->findByTitle('My First Blog Post'); $this->Author->findByLastName('Rogers');
- findBy<fieldName>
- string $value
- findAllBy<fieldName>
- string $value
findAllBy 或者 findBy 后面可以跟变量, 它大概的方法就是使用了三个核心内置函数: __call, method_exists() 和 call_user_func_array (或者call_user_func), 下面先讲解他们各自的含义和用法:
__call()
定义和用法
__call() 这个方法用来监视一个对象中的其它方法。如果你试着调用一个对象中不存在或被权限控制中的方法,__call 方法将会被自动调用。
注:通常被称为魔法函数。
语法: __call(name, arguments)
参数 | 描述 |
---|---|
name | 方法名 |
arguments | 传递的参数 |
例子
<?php class MyClass { public function __call($name, $arguments) { // 注意: $name 区分大小写 echo "调用了方法: '$name'<br/> "; echo '参数是:'.implode(', ', $arguments). "\n"; } } $obj = new MyClass; $obj->callMe('abc','123'); //运行结果: //调用了方法:callMe //参数是:abc,123
method_exists()
定义和用法
检查类的方法是否存在于指定的 object中。
语法: method_exists(object,method_name)
参数 | 描述 |
---|---|
object | 规定的对象示例或者类名。 |
method_name | 规定的方法名。 |
例子
<?php class Test { public function explicit( ) { // ... } public function __call( $meth, $args ) { // 魔术方法,当调用的方法不存在时自动调用此方法 } } $Tester = new Test(); // method_exists() -方法是否存在 var_export(method_exists($Tester, 'anything')); // false // is_callable() - 检测参数是否可调用 var_export(is_callable(array($Tester, 'anything'))); // true ?>
call_user_func()
定义和用法
调用指定函数,并传入参数。
语法
- call_user_func(callback, parameter)
参数 | 描述 |
---|---|
callback | 调用的函数名称 |
parameter | 传入的参数 |
例子
<?php error_reporting(E_ALL); function increment(&$var) { $var++; } $a = 0; call_user_func('increment', $a); echo $a."\n"; call_user_func_array('increment', array(&$a)); // PHP 5.3前 版本可用 echo $a."\n"; //输出: //0 //1
call_user_func_array()
定义和用法
用一个数组作为参数调用一个回调函数·返回值为回调函数执行的结果或者为false
语法
- call_user_func_array(callback , param_arr)
参数 | 描述 |
---|---|
callback | 要调用的回调函数,可以是函数或者类方法 |
param_arr | 传入的参数 |
例子
<?php function foobar($arg, $arg2) { echo __FUNCTION__, " got $arg and $arg2\n"; } class foo { function bar($arg, $arg2) { echo __METHOD__, " got $arg and $arg2\n"; } } // 调用 foobar() 函数并传入两个参数 call_user_func_array("foobar", array("one", "two")); // 调用 $foo->bar() 方法并传入两个参数 $foo = new foo(); call_user_func_array(array($foo, "bar"), array("three", "four")); //输出: //foobar got one and two //foo::bar got three and four
也可以参考:call_user_func和call_user_func_array的用法
官方有下面的实例:
<?php class A { function __construct() { $a = func_get_args(); $i = func_num_args(); if (method_exists($this,$f='__construct'.$i)) { call_user_func_array(array($this,$f),$a); } } function __construct1($a1) { echo('__construct with 1 param called: '.$a1.PHP_EOL); } function __construct2($a1,$a2) { echo('__construct with 2 params called: '.$a1.','.$a2.PHP_EOL); } function __construct3($a1,$a2,$a3) { echo('__construct with 3 params called: '.$a1.','.$a2.','.$a3.PHP_EOL); } } $o = new A('sheep'); $o = new A('sheep','cat'); $o = new A('sheep','cat','dog'); // results: // __construct with 1 param called: sheep // __construct with 2 params called: sheep,cat // __construct with 3 params called: sheep,cat,dog ?>
主要的函数解释完了, 下面的就写一个简单的实例, 以实现上面cakephp中的findBy用法:
<?php class post { public function __call($name, $arguments) { if (method_exists($this,$name)) call_user_func_array(array($this,$name),$arguments); else { if(stripos(' '.$name,'findBy')) call_user_func(array($this,'findBy'),array(str_ireplace('findBy','',$name)=>implode('',$arguments))); else echo 'error'; } } function findAll($data) { echo 'All Here: '.(is_array($data) ? implode(',',$data) : $data).'<br>'; } function findBy($data) { echo '<pre>'; print_r($data); echo '</pre>'; } } $post = new post; $post->findAll('justcode.ikeepstudying.com'); $post->findAll(array('justcode','ikeepstudying','com')); $post->findByTitle('justcode.ikeepstudying.com');
效果如下:
更多参考:
PHP: 关键字global 和 超全局变量$GLOBALS的用法、解释、区别
JavaScript使用PHP函数 PHP extensions in JavaScript
原文: PHP: 在类(class)中加载动态函数, 变量函数或半变量函数 variable function/method
One Comment