如何防止调用不存在的方法而出错,使用__call魔术重载方法.

__call方法原型如下:
mixed __call(string $name,array $arguments)
当调用一个不可访问的方法(如未定义,或者不可见时), __call()就会被调用.其中$name参数是要调用的方法名称.$arguments参数是一个数组,包含者要传递给方法的参数,
如下所示:

  1. <?php
  2. class HandsonBoy
  3. {
  4. private $name = 'chenqionghe';
  5. private $age = 18;
  6. public function __call($name,$arguments)
  7. {
  8. switch(count($arguments))
  9. {
  10. case 2:
  11. echo $arguments[0] * $arguments[1],PHP_EOL;
  12. break;
  13. case 3:
  14. echo array_sum($arguments),PHP_EOL;
  15. break;
  16. default:
  17. echo '参数不对',PHP_EOL;
  18. break;
  19. }
  20. }
  21. }
  22. $a = new HandsonBoy();
  23. $a->make(5);
  24. $a->make(5,6);
以上代码模拟了类似其他语言中的根据参数类型进行重载.跟__call配套的魔方方法是__callStatic.
当然,使用魔术方法"防止调用不存在的方法面报错",并不是魔术方法的本质.实际上,魔术方法使用方法的动态创建变为可能.这在MVC等框架设计中是很有用的语法.假设一个控制器调用了不存在的方法,那么只要定义了__call魔术方法,就能很友好地处理这种情况.
以下代码通过使用_callStatic这一魔术方法进行方法的动态创建和延迟绑定,实现一个简单的ORM模型
  1. <?php
  2. abstract class ActiveRecord
  3. {
  4. protected static $table;
  5. protected $fieldvalue;
  6. public $select;
  7. static function findById($id)
  8. {
  9. $query = "SELECT * FROM " . static::$table . " WHERE id=$id";
  10. return self::createDomain($query);
  11. }
  12. function __get($fieldname)
  13. {
  14. return $this->fieldvalues[$fieldname];
  15. }
  16. static function __callStatic($method,$args)
  17. {
  18. $field = preg_replace('/^findBy(\w*)$/', '$1' , $method);
  19. $query = "SELECT * FROM " . static::$table . " WHERE $field='$args[0]'";
  20. return self::createDomain($query);
  21. }
  22. private static function createDomain($query)
  23. {
  24. $class = get_called_class();//获取静态方法调用的类名
  25. $domain = new $class();
  26. $domain->fieldvalues = array();
  27. $domain->select = $query;
  28. foreach ($class::$fields as $field => $type)
  29. {
  30. $domain->fieldvalues[$field] = 'TODO:set from sql result by ' . $field;
  31. }
  32. return $domain;
  33. }
  34. }
  35. class Customer extends ActiveRecord
  36. {
  37. protected static $table = 'custdb';
  38. protected static $fields = array(
  39. 'id' => 'int',
  40. 'email' => 'int',
  41. 'lastname' => 'varchar'
  42. );
  43. }
  44. class Sales extends ActiveRecord
  45. {
  46. protected static $table = 'salesdb';
  47. protected static $fields = array(
  48. 'id' => 'int',
  49. 'item' => 'varchar',
  50. 'qty' => 'int'
  51. );
  52. }
  53. var_dump(Customer::findById(123)->select);
  54. var_dump(Customer::findById(123)->email);
  55. var_dump(Sales::findByLastname('Denoncourt')->select);

PHP中的__call和__callStatic方法的更多相关文章

  1. PHP中的__call和__callStatic方法(未看完)

    如何防止调用不存在的方法而出错,使用__call魔术重载方法. __call方法原型如下: mixed __call(string $name,array $arguments) 当调用一个不可访问的 ...

  2. PHP 魔术方法 __call 与 __callStatic 方法

    PHP 魔术方法 __call 与 __callStatic 方法 PHP 5.3 后新增了 __call 与 __callStatic 魔法方法. __call 当要调用的方法不存在或权限不足时,会 ...

  3. php中__call() 和 __callStatic方法的使用

    __call 与__callStatic 魔法方法是php5.3后新增的,二者的应用场景: 1.当要调用的方法不存在或权限不足时,会自动调用__call 方法. 2.当调用的静态方法不存在或权限不足时 ...

  4. __call()和__callStatic()方法

    __call() 当对象访问不存在的方法时,__call()方法会被自动调用__callStatic() 当对象访问不存在的静态方法时,__callStatic()方法会被自动调用 这两个方法在PHP ...

  5. PHP魔术方法之__call与__callStatic方法

    <?php class human{ private function t(){ } //魔术方法__call /* $method 获得方法名 $arg 获得方法的参数集合 */ public ...

  6. 魔术方法之__call与__callStatic方法

    <?php class human{ private function t(){ } /** * 魔术方法__call * * @param string $method 获得方法名 * @pa ...

  7. PHP中的11个魔术方法总结:__construct,、__destruct、__call等

    PHP中的魔术方法总结 :__construct, __destruct , __call, __callStatic,__get, __set, __isset, __unset , __sleep ...

  8. php中__call与__callstatic()使用

    php 5.3 后新增了 __call 与__callStatic 魔法方法. __call 当要调用的方法不存在或权限不足时,会自动调用__call 方法. __callStatic 当调用的静态方 ...

  9. PHP中的11个魔术方法

    1.__get.__set 这两个方法是为在类和他们的父类中没有声明的属性而设计的 __get( $property )       当调用一个未定义的属性时访问此方法__set( $property ...

随机推荐

  1. 走进JDK(十一)------LinkedHashMap

    概述LinkedHashMap 继承自 HashMap,在 HashMap 基础上,通过维护一条双向链表,解决了 HashMap 不能随时保持遍历顺序和插入顺序一致的问题.除此之外,LinkedHas ...

  2. formdata的使用方法

    function upload_single_file(value){ if(value==''){ layer.msg('请添加文件',{time:1500}) }else{ var formDat ...

  3. jQuery源码框架fn解读

    (function( window, undefined ){ var jQuery = (function(){ var jQuery = function( selector, context ) ...

  4. springmvc 整合Controller出现实例化两次问题

    启动项目的时候,发现初始化控制层的时候,初始化(使用构造方法打印日志的方式)了两次的情况. 后来检查配置: <context:component-scan base-package=" ...

  5. Javascript Engine, Java VM, Python interpreter, PyPy – a glance

    提要: url anchor (ajax) => javascript engine (1~4 articles) => java VM vs. python interpreter =& ...

  6. eclipse 带sts插件

    https://pan.baidu.com/s/1c1M11ss 密码:ucjl

  7. 大数据开发主战场hive (企业hive应用)

    hive在大数据套件中占很的地位,分享下个人经验. 1.在hive日常开发中,我们首先面对的就是hive的表和库,因此我要先了解库,表的命名规范和原则 如 dwd_whct_xmxx_m 第1部分为表 ...

  8. CSS中清除浮动的作用以及如何清除浮动

    1.什么是浮动,浮动的作用 “浮动”从字面上来理解就是“悬浮移动.非固定”的意思.块级元素(div.table.span…)是以垂直方向排列,而在前端界面中往往要使用水平布局块级元素使界面更美观.这就 ...

  9. zookeeper原理与安装

    Zookeeper是一个开源的分布式的,为分布式应用提供协调服务的Apache项目. 1.   Zookerper工作机制 2.   Zookeeper工作特点 3.   Zookeeper文件系统: ...

  10. delphi压缩与解压_不需要特别的控件

    unit unzip; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...