如何防止调用不存在的方法而出错,使用__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);

参考:https://jingyan.baidu.com/article/48a42057fd2890a92425043c.html

转:https://www.cnblogs.com/chenqionghe/p/4735703.html?tvd

参考:http://www.php.net/manual/zh/language.oop5.magic.php

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. Linux中find命令用法全汇总,看完就没有不会用的!

    Linux中find命令用法全汇总,看完就没有不会用的! 中琦2513 马哥Linux运维 2017-04-10   糖豆贴心提醒,本文阅读时间7分钟 Linux 查找命令是Linux系统中最重要和最 ...

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

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

  5. __call()和__callStatic()方法

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

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

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

  7. JS做类型检测到底有几种方法?看完本文就知道了!

    JS有很多数据类型,对于不同数据类型的识别和相互转换也是面试中的一个常考点,本文主要讲的就是类型转换和类型检测. 数据类型 JS中的数据类型主要分为两大类:原始类型(值类型)和引用类型.常见的数据类型 ...

  8. 如果你每次面试前都要去背一篇Spring中Bean的生命周期,请看完这篇文章

    前言 当你准备去复习Spring中Bean的生命周期的时候,这个时候你开始上网找资料,很大概率会看到下面这张图: 先不论这张图上是否全面,但是就说这张图吧,你是不是背了又忘,忘了又背? 究其原因在于, ...

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

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

随机推荐

  1. [转] Log4j 配置 的webAppRootKey参数问题

    在tomcat下部署两个或多个项目时,web.xml文件中最好定义webAppRootKey参数,如果不定义,将会缺省为“webapp.root”,如下:<!-- 应用路径 --> < ...

  2. Web安全测试指南--权限管理

    垂直权限提升: 编号 Web_Author_01 用例名称 垂直权限提升测试 用例描述 测试用户是否具有使用超越其角色范围之外的权限. 严重级别 高 前置条件 1.  目标系统拥有不同等级的角色和权限 ...

  3. AS3.0 Vector的运用

    使用Vector类编程 一个array(数组)就像是把一套变量组织在一起的容器.单个数组可以含有许多不同的值.你可以储存和取得数组中的单个值(也就是数组elements(元素)).你也可以通过直接操作 ...

  4. iOS开发--地图与定位

    概览 现在很多社交.电商.团购应用都引入了地图和定位功能,似乎地图功能不再是地图应用 和导航应用所特有的.的确,有了地图和定位功能确实让我们的生活更加丰富多彩,极大的改变了我们的生活方式.例如你到了一 ...

  5. mac远程链接 windows

    https://bbs.feng.com/read-htm-tid-10516042.html 一.利用电脑系统自带的远程(喜欢懒人版的方法,或者小白用户,可以跳过这个方法看下一个) 1.打开mac, ...

  6. 新手遇到的问题:Easy UI的对话框老是在页面载入完毕后自己主动弹出

    因为是第一次接触Easy UI,还不是非常熟悉,尝试了一下对话框功能,还是非常不错的.但问题是页面载入完毕后.全部的对话框都自己主动弹出来了,百度了好久,也没有详细说明确的,貌似别人都没有这个问题哦 ...

  7. windows 服务器不能使用剪贴板解决办法

    您可以在系统资源中先结束rdpclip.exe进程,然后重新打开c:\windows\system32\rdpclip.exe即可

  8. META http-equiv="refresh" 实现网页自动跳转

    使用说明: < HEAD> < TITLE>刷新内容< /TITLE> < META HTTP-EQUIV="REFRESH" CONTE ...

  9. 将思维转向rss

    本屌丝因为穷住在了离市区比较远的农民房,平时上下班单程地铁时间接近一小时.在这漫长的一小时里,总得干点什么来蹉跎这段时光,看手机是最容易实现的事情.最地铁信号不好,手机也没什么好看的. 经过高人指点说 ...

  10. ActiveMQ订阅模式持久化实现

    实现步骤:1.配置发送xml,applicationContext-send.xml <?xml version="1.0" encoding="UTF-8&quo ...