• PHP 重载 __call() _callStatic方法


    在C++和java中,可以函数参数的个数或类型来进行重载。但php是弱类型的语言,无法采用传统的方法。若下面这样;

    class Person{
         function fun1($a)
        {
            echo 'fun1 '.$a.'<br/>';
        }
        function fun1($a,$b)
        {
            echo 'fun1 '.$a.' '.$b.' <br/>';
        }
    }
    $t=new Person();
     $t->fun1(1);

    会报错:

    Fatal error: Cannot redeclare PropertyTest::fun1()。

    所以php采用了一套新的方法。

    __call() is triggered when invoking inaccessible methods in an object context.

    PHP5 的对象新增了一个专用方法 __call(),这个方法用来监视一个对象中的其它方法。如果你试着调用一个对象中不存在的方法,__call 方法将会被自动调用。

    例七:__call

    <?php
    class foo {
      function __call($name,$arguments) {
        print("Did you call me? I'm $name!");
      }
    } $x = new foo();
    $x->doStuff();
    $x->fancy_stuff();
    ?>

    这个特殊的方法可以被用来实现“过载(overloading)”的动作,这样你就可以检查你的参数并且通过调用一个私有的方法来传递参数。

    例八:使用 __call 实现“过载”动作

    <?php
    class Magic {
      function __call($name,$arguments) {
        if($name=='foo') {
      if(is_int($arguments[0])) $this->foo_for_int($arguments[0]);
      if(is_string($arguments[0])) $this->foo_for_string($arguments[0]);
        }
      }   private function foo_for_int($x) {
        print("oh an int!");
      }   private function foo_for_string($x) {
        print("oh a string!");
      }
    } $x = new Magic();
    $x->foo(3);
    $x->foo("3");
    ?>

    引自:

    _call___callStatic这两个函数是php类 的默认函数,

    __call() 在一个对象的上下文中,如果调用的方法不能访问,它将被触发

    __callStatic() 在一个静态的上下文中,如果调用的方法不能访问,它将被触发

    实例:

    <?php
    abstract class Obj
    {
    protected $property = array();
    
    abstract protected function show();
    
    public function __call($name,$value)
    {
    if(preg_match("/^set([a-z][a-z0-9]+)$/i",$name,$array))
    {
    $this->property[$array[1]] = $value[0];
    return;
    }
    elseif(preg_match("/^get([a-z][a-z0-9]+)$/i",$name,$array))
    {
    return $this->property[$array[1]];
    }
    else
    {
    exit("<br>;Bad function name '$name' ");
    }
    
    }
    }
    
    class User extends Obj
    {
    public function show()
    {
    print ("Username: ".$this->property['Username']."<br>;");
    //print ("Username: ".$this->getUsername()."<br>;");
    print ("Sex: ".$this->property['Sex']."<br>;");
    print ("Age: ".$this->property['Age']."<br>;");
    }
    }
    
    class Car extends Obj
    {
    public function show()
    {
    print ("Model: ".$this->property['Model']."<br>;");
    print ("Sum: ".$this->property['Number'] * $this ->property['Price']."<br>;");
    }
    }
    
    $user = new User;
    $user ->setUsername("Anny");
    $user ->setSex("girl");
    $user ->setAge(20);
    $user ->show();
    
    print("<br>;<br>;");
    
    $car = new Car;
    $car ->setModel("BW600");
    $car ->setNumber(5);
    $car ->setPrice(40000);
    $car ->show();
    ?>

    更多参考:hhttp://php.net/manual/zh/language.oop5.overloading.php 提供了很多例子。

    http://www.garfieldtech.com/blog/magical-php-call

    php 5.3 后新增了 __call 与__callStatic 魔法方法。

    __call 当要调用的方法不存在或权限不足时,会自动调用__call 方法。

    __callStatic 当调用的静态方法不存在或权限不足时,会自动调用__callStatic方法。

    __call($funcname, $arguments)

    __callStatic($funcname, $arguments)


    参数说明:

    $funcname String 调用的方法名称。

    $arguments Array 调用方法时所带的参数。

    __call 例子

    <?php
    
    class Member{
    
        protected $memberdata = array();
    
        public function __call($func, $arguments){
            list($type, $name) = explode('_', $func);
        
            if(!in_array($type, array('set','get')) || $name==''){
                return '';
            }
    
            switch($type){
                case 'set':
                    $this->memberdata[$name] = $arguments[0];
                    break;
                
                case 'get':
                    return isset($this->memberdata[$name])? $this->memberdata[$name] : '';
                    break;
                
                default:
            }
    
        }
    
    }
    
    
    class User extends Member{
    
        public function show(){
            if($this->memberdata){
                foreach($this->memberdata as $key=>$member){
                    echo $key.':'.$member.'<br>';
                }
            }
        }
    
    }
    
    
    class Profession extends Member{
    
        public function show(){
            if($this->memberdata){
                foreach($this->memberdata as $key=>$member){
                    echo $key.':'.$member.'<br>';
                }
            }
        }
    
    }
    
    $userobj = new User();
    $userobj->set_name('fdipzone');
    $userobj->set_age(29);
    $userobj->show();
    
    $probj = new Profession();
    $probj->set_profession('IT SERVICE');
    $probj->set_price(2500);
    $probj->show();
    
    ?>

    __callStatic例子

    <?php
    
    class Member{
    
        protected static $memberdata = array();
    
        public static function __callStatic($func, $arguments){
    
            list($type, $name) = explode('_', $func);
            
            if(!in_array($type, array('set','get')) || $name==''){
                return '';
            }
    
            $feature = get_called_class();
    
            switch($type){
                case 'set':
                    self::$memberdata[$feature][$name] = $arguments[0];
                    break;
    
                case 'get':
                    return isset(self::$memberdata[$feature][$name])? self::$memberdata[$feature][$name] : '';
                    break;
    
                default:
            }
        
        }
    
    }
    
    
    class User extends Member{
    
        public static function show(){
    
            $feature = get_called_class();
    
            if(self::$memberdata[$feature]){
                foreach(self::$memberdata[$feature] as $key=>$member){
                    echo $key.':'.$member.'<br>';
                }
            }
        }
    
    }
    
    
    class Profession extends Member{
    
        public static function show(){
    
            $feature = get_called_class();
    
            if(self::$memberdata[$feature]){
                foreach(self::$memberdata[$feature] as $key=>$member){
                    echo $key.':'.$member.'<br>';
                }
            }
        }
    
    }
    
    User::set_name('fdipzone');
    User::set_age(29);
    User::show();
    
    Profession::set_profession('IT SERVICE');
    Profession::set_price(2500);
    Profession::show();
    
    ?>
     
     
  • 相关阅读:
    EasyNVR视频平台无法输出RTSP流地址排查步骤
    EasyNVR平台实现播流地址超时无法播放功能过程分享
    EasyNVR视频平台集成出现播放一段时间后自动断开的情况排查及优化
    EasyNVR-ARM版云终端频繁死机重启原因分析
    EasyNVR用户登录修改为IP+用户名限制的修改过程分享
    EasyNVR视频平台设备通道页面显示错误的调整方法
    【解决方案】视频智能监控系统为酒店智能化建设提供一体化融合解决方案
    1051 Pop Sequence (25 分)
    1089 Insert or Merge (25 分)
    1085 Perfect Sequence (25 分)
  • 原文地址:https://www.cnblogs.com/youxin/p/3251427.html
Copyright © 2020-2023  润新知