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

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

<?php
class HandsonBoy
{
private $name = 'chenqionghe';
private $age = 18;
public function __call($name,$arguments)
{
switch(count($arguments))
{
case 2:
echo $arguments[0] * $arguments[1],PHP_EOL;
break;
case 3:
echo array_sum($arguments),PHP_EOL;
break;
default:
echo '参数不对',PHP_EOL;
break;
}
}
}
$a = new HandsonBoy();
$a->make(5);
$a->make(5,6);
以上代码模拟了类似其他语言中的根据参数类型进行重载.跟__call配套的魔方方法是__callStatic.
当然,使用魔术方法"防止调用不存在的方法面报错",并不是魔术方法的本质.实际上,魔术方法使用方法的动态创建变为可能.这在MVC等框架设计中是很有用的语法.假设一个控制器调用了不存在的方法,那么只要定义了__call魔术方法,就能很友好地处理这种情况.
以下代码通过使用_callStatic这一魔术方法进行方法的动态创建和延迟绑定,实现一个简单的ORM模型
<?php
abstract class ActiveRecord
{
protected static $table;
protected $fieldvalue;
public $select;
static function findById($id)
{
$query = "SELECT * FROM " . static::$table . " WHERE id=$id";
return self::createDomain($query);
}
function __get($fieldname)
{
return $this->fieldvalues[$fieldname];
}
static function __callStatic($method,$args)
{
$field = preg_replace('/^findBy(\w*)$/', '$1' , $method);
$query = "SELECT * FROM " . static::$table . " WHERE $field='$args[0]'";
return self::createDomain($query);
}
private static function createDomain($query)
{
$class = get_called_class();//获取静态方法调用的类名
$domain = new $class();
$domain->fieldvalues = array();
$domain->select = $query;
foreach ($class::$fields as $field => $type)
{
$domain->fieldvalues[$field] = 'TODO:set from sql result by ' . $field;
}
return $domain;
}
}
class Customer extends ActiveRecord
{
protected static $table = 'custdb';
protected static $fields = array(
'id' => 'int',
'email' => 'int',
'lastname' => 'varchar'
);
}
class Sales extends ActiveRecord
{
protected static $table = 'salesdb';
protected static $fields = array(
'id' => 'int',
'item' => 'varchar',
'qty' => 'int'
);
}
var_dump(Customer::findById(123)->select);
var_dump(Customer::findById(123)->email);
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. shiro简单配置 (写的不错 收藏一下)

    抄袭的连接:https://blog.csdn.net/clj198606061111/article/details/24185023 注:这里只介绍spring配置模式. 因为官方例子虽然中有更加 ...

  2. MFC改变坐标系

    1.在MainFrm中的PreCreateWindow中设置默认窗口大小 BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { if( !C ...

  3. JavaScript基础视频教程总结(101-110章)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  4. template模板的使用方法

    模板 WXML提供模板(template),可以在模板中定义代码片段,然后在不同的地方调用. 定义模板 使用name属性,作为模板的名字.然后在<template/>内定义代码片段 使用模 ...

  5. scrollIntoView() 调用元素就可以出现在视窗中

    /* 如果滚动页面也是DOM没有解决的一个问题.为了解决这个问题,浏览器实现了一下方法, 以方便开发人员如何更好的控制页面的滚动.在各种专有方法中,HTML5选择了scrollIntoView() 作 ...

  6. html、css基础整理

    1.块元素与行内元素之间的转换: HTML可以将元素分类方式分为行内元素.块状元素和行内块状元素三种.这三者是可以互相转换的,使用display属性能够将三者任意转换: (1)display:inli ...

  7. 解压->静态库.a文件

    1. cd /Volumes/HHD/PQS/apple/Public 2. file com_PQS.a com_PQS.a: Mach-O universal binary with 5 arch ...

  8. 【高速接口-RapidIO】2、RapidIO串行物理层的包与控制符号

    一.RapidIO串行物理层背景介绍 上篇博文提到RapidIO的物理层支持串行物理层与并行物理层两种,由于Xilinx 部分FPGA内部已经集成了串行高速收发器,所以用FPGA实现RapidIO大多 ...

  9. Python selenium webdriver设置js操作页面滚动条

    js2 = "window.scrollTo(0,0);" #括号中为坐标 当不知道需要的滚动的坐标大小时: weizhi2 = driver.find_element_by_id ...

  10. WebView的知识

    一.基本介绍 WebView是一个显示页面的组件. 二.基本使用 访问网页需要网络,所以在AndroidManifest.xml文件中添加网络权限. <uses-permission andro ...