php的魔术方法__call()是在访问对象中不存在的方法时会自动调用该方法,可以在该方法中给出错误提示信息反馈回调用用户。但是魔术方法__call()不只这样用,可以实现像codeIgniter的数据库查询构造器类的链式方法生成sql语句。
//codeIgniter的链式方法 $result = $this->db ->select("*") ->from($this->dbTable) ->where(‘name‘, $name) ->where(‘title‘, $title) ->order_by(‘title‘, ‘DESC‘) ->get();
下面是用魔术方法__call()实现上面的链式方法
——连贯操作
<?php //声明一个DB类(数据库操作类)的简单操作模型 class DB{ private $sql = array( ‘field‘ => ‘‘, ‘where‘ => ‘‘, ‘order‘ => ‘‘, ‘limit‘ => ‘‘, ‘group‘ => ‘‘, ‘having‘ => ‘‘ ); //连贯操作调用field(),where(),order(),limit(),group(),having()方法,组合sql语句 function __call($methodName, $arge){ //将第一个参数(代表不存在方法的方法名)全部转化为小写方式,获取方法名称 $methodName = strtolower($methodName); //如果调用的方法名和成员属性数组$sql下标相对应,则将第二个参数赋给数组中下标对应的元素 if(array_key_exists($methodName, $this->sql)){ $this->sql[$methodName] = $arge[0]; }else{ echo ‘<br><br>调用类‘ . get_class($this) . ‘中的方法‘ . $methodName . ‘()不存在。‘; } //返回自己的对象,则可以继续调用本对象中的方法,形成连贯操作 return $this; } //简单的应用,没有实际意义,只是输出连贯操作后组合的一条sql语句,是连贯操作最后调用的一个方法 function select(){ echo "SELECT FROM {$this->sql[‘field‘]} user {$this->sql[‘where‘]} {$this->sql[‘order‘]} {$this->sql[‘limit‘]} {$this->sql[‘group‘]} {$this->sql[‘having‘]}"; } } $db = new DB; //连贯操作,也可以分为多行连续调用多个方法 $db->field(‘sex, count(sex)‘) ->where(‘where sex in ("男", "女")‘) ->group(‘group by sex‘) ->having(‘having avg(age) > 25‘) ->select(); //如果调用的方法不存在,也会有提示,下面演示的就是调用一个不存在的方法query() $db->query(‘SELECT * FROM user‘);
代码实现效果: