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();

?>
 
 
原文地址:https://www.cnblogs.com/youxin/p/3251427.html