zoukankan      html  css  js  c++  java
  • PHP中的__call和__callStatic方法(未看完)

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

     参考: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

  • 相关阅读:
    【牛客网】Finding Hotel
    【牛客网】Longest Common Subsequence
    【ZOJ】4012 Your Bridge is under Attack
    【LOJ】#2210. 「HNOI2014」江南乐
    可能是一篇(抄来的)min25学习笔记
    【LOJ】#3020. 「CQOI2017」小 Q 的表格
    【51nod】1602 矩阵方程的解
    【51nod】1634 刚体图
    【51nod】1407 与与与与
    【51nod】1776 路径计数
  • 原文地址:https://www.cnblogs.com/fps2tao/p/8030156.html
Copyright © 2011-2022 走看看