PHP核心技术——魔术方法
魔术方法:
- 魔术方法是以两个下画线开头、具有特殊作用的一些方法,可以看做PHP的“语法糖”。
 
set和get方法:
class Account{
    private $user=1;
    private $pwd=2;
    public function __set($name,$value)
    {
        echo "Setting".$name." to ".$value."\r\n";
        $this->$name=$value;
    }
    public function __get($name)
    {
        if (!isset($this->$name)) {
            echo "not default";
            $this->$name="setting default";
        }
        return $this->$name;
    }
}
$a=new Account();
echo $a->user;
echo "-----------\n";
$a->name=5;
echo $a->name;
echo "-----------\n";
echo $a->big;
- 而PHP则在一个类中只允许有一个构造函数
 - PHP提供的“重载”指动态地“创建”类属性和方法。因此,set和get方法被归到重载里。
 
call和callStatic方法:
- 当调用一个不可访问的方法(如未定义,或者不可见)时,call()会被调用。其中name参数是要调用的方法名称。arguments参数是一个数组,包含着要传递给方法的参数
 
  class callFun
  {
      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 'wrong',PHP_EOL;
                  break;
          }
      }
  }
  $a =new callFun;
  $a->make(5);
  $a->make(5,6);
- 这段代码通过使用callStatic这一魔术方法进行方法的动态创建和延迟绑定,实现一个简单的ORM模型。
 
abstract class ActiveRecord{
        protected static $table;
        protected $fieldvalues;
        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){
            $klass=get_called_class();
            $domain=new $klass();
            $domain->fieldvalues=array();
            $domain->select=$query;
            foreach($klass::$fields as $field=>$type){
                $domain->fieldvalues[$field]='TODO:set from sql result';
            }
            return $domain;
        }
}
class Customer extends ActiveRecord{
    protected static $table='custdb';
    protected static $fields=array(
        'id'=>'int',
        'email'=>'varchar',
        'lastname'=>'varchar'
    );
}
class Sales extends ActiveRecord{
    protected static $table='salesdb';
    protected static $fields=array(
    'id'=>'int',
    'item'=>'varchar',
    'qty'=>'int'
    );
}
assert("select * from custdb where id=123"==Customer::findById(123)->select);
assert("TODO:set from sql result"==Customer::findById(123)->email);
assert("select * from salesdb where id=321"==Sales::findById(321)->select);
assert("select * from custdb where Lastname='Denoncourt'"==Customer::findByLastname('Denoncourt')->select);
toString方法:
- 当进行测试时,需要知道是否得出正确的数据。比如打印一个对象时,看看这个对象都有哪些属性,其值是什么,如果类定义了toString方法,就能在测试时,echo打印对象体,对象就会自动调用它所属类定义的toString方法,格式化输出这个对象所包含的数据。如果没有这个方法,那么echo一个对象将报错,例如“Catchable fatal error:Object of class Account could not be converted to string”语法错误,实际上这是一个类型匹配失败错误。不过仍然可以用print_r()和var_dump()函数输出一个对象。当然,toString是可以定制的,所提供的信息和样式更丰富。
 
class Account
{
    public $user=1;
    private $pwd=2;
    //自定义的格式化输出方法
    public function __toString()
    {
        return "{$this->user}, {$this->pwd}";
    }
}
$a = new Account();
echo $a;
echo PHP_EOL;
print_r($a);
参考资料
- [PHP核心技术与最佳实践]
 
PHP核心技术——魔术方法的更多相关文章
- PHP中的魔术方法和魔术常量
		
看上去好像挺烦人,但只要通过例子测试一下,就明白了.不做测试,只是看,第二天还是不明白.当然我在抄其他人的日志,然后希望能是自己的理解就好,原文地址PHP的魔术方法和魔术敞亮简介和使用--LaraBo ...
 - PHP基础知识之魔术方法
		
__construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sle ...
 - 前端学PHP之面向对象系列第二篇——魔术方法
		
× 目录 [1]构造方法 [2]析构方法 [3]不可访问属性[4]对象复制[5]字符串[6]对象不存在[7]自动加载类[8]串行化[9]函数调用 前面的话 php在面向对象部分有很多相关的魔术方法,这 ...
 - PHP中的魔术方法(2)
		
1.__get.__set这两个方法是为在类和他们的父类中没有声明的属性而设计的__get( $property ) 当调用一个未定义的属性时访问此方法__set( $property, $value ...
 - 魔术方法__sleep 和 __wakeup
		
感觉序列化和反序列化用得倒是比较少了,而json_encode和json_decode用得相对多,都是转化成串,进行入库.传输等.json更方便,但是序列化和反序列化结合这两个魔术方法使用倒还行< ...
 - Python魔术方法-Magic Method
		
介绍 在Python中,所有以"__"双下划线包起来的方法,都统称为"Magic Method",例如类的初始化方法 __init__ ,Python中所有的魔 ...
 - php魔术方法使用场景
		
php魔术方法-----__tostring(),__invoke,__call(),__callStatic ... __tostring(),__invoke() __tostring()方法是在 ...
 - PHP中的魔术方法:__construct, __destruct , __call, __callStatic,__get, __set, __isset, __unset , __sleep, __wakeup, __toString, __set_state, __clone and __autoload
		
1.__get.__set 这两个方法是为在类和他们的父类中没有声明的属性而设计的: __get( $property ) 当调用一个未定义的属性时访问此方法: __set( $property, $ ...
 - PHP 类中的魔术方法
		
定义: PHP类中以两个下画线“__”开头的方法被称为魔术方法. 分类: 例如:构造方法:__construct:析构方法:__destruct:动态重载:__set().__get().__call ...
 
随机推荐
- POJ 1703 Find them, Catch them(确定元素归属集合的并查集)
			
Find them, Catch them Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 52925 Accepted: ...
 - 指纹协查统计sql
			
select dic.name, NVL(zc.zc_djzs,0),NVL(zc.zc_shzs,0),NVL(zc.zc_bzzs,0), NVL(zt.zt_djzs,0),NVL(zt.zt ...
 - Spring coud微服务框架具体实现关键说明
			
搭建一个微服务,考虑的问题涉及到运维,数据管理,性能,并发等方方面面.项目中使用Spring coud 搭建微服务,从技术选型,到技术实现都要全方面考虑服务化的问题.下面简单总结下搭建过程用的技术说明 ...
 - java环境变量配置(win7)
			
JDK1.8 1.单击“计算机-属性-高级系统设置”,单击“环境变量”.在“系统变量”栏下单击“新建”,创建新的系统环境变量. 2. (1)新建->变量名"JAVA_HOME&quo ...
 - 15JavaScript switch语句
			
1.JavaScript switch 语句 使用 switch 语句来选择要执行的多个代码块之一. 语法: switch(n) { case 1: 执行代码块 1 break; case 2: 执行 ...
 - 苹果App Store提交app审核时EULA(终端用户软件使用条款)的注意事项等政策解读
			
写在前面,今天是2014年10月14日,以下内容可能会随着时间的推进而失效,请注意时效性 当在App Store提交app审核的时候,苹果通常会要求开发者提供一个EULA,苹果默认提供了一个,地址: ...
 - html input file accept
			
*.3gpp audio/3gpp, video/3gpp 3GPP Audio/Video*.ac3 audio/ac3 AC3 Audio*.asf allpication/vnd.ms-asf ...
 - [修正] Firemonkey Android 文字斜粗体显示不全的问题
			
问题:Firemonkey Android 平台显示斜粗体文字时,文字右方会有显示不全的问题. 修正代码: 请将 FMX.FontGlyphs.Android.pas 复制到自己的工程目录下,再修改如 ...
 - 一图看懂hadoop分布式文件存储系统HDFS工作原理
			
一图看懂hadoop分布式文件存储系统HDFS工作原理
 - 自学tensorflow——1.框架初步了解以及构建简单的计算图计算
			
1.初步了解 tensorflow是谷歌的一款开源深度学习框架.运行前,需要先定义好计算图,最后通过会话启动计算图,这么做的目的是为了防止数据在python和c++(tensorflow底层)传输的时 ...