• 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核心技术与最佳实践]
  • 相关阅读:
    用MySQL的注意事项
    在win下mysql备份恢复命令概述
    SQL查询结果集对注入的影响与利用
    DIV CSS完美兼容IE6/IE7/FF的通用方法
    使用css实现透视的效果
    ASP.NET几个性能优化的方法
    ASP.NET实现页面传值的几种方法
    ASP.NET配置文件Web.config 详细解释
    黑客域名劫持攻击详细步骤
    FCKeditor的几点修改小结
  • 原文地址:https://www.cnblogs.com/geniusrun/p/10607683.html
Copyright © 2020-2023  润新知