我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

php编程语言中,class类中有一系列的隐藏的魔术方法,本文讨论其中的__call()__callStatic()这两个魔术方法。它们是分别用于什么地方呢?如何触发?如何获得参数?

苏南大叔:php教程,如何理解类的魔术函数__call(),__callStatic()? - 魔术函数call
php教程,如何理解类的魔术函数__call(),__callStatic()?(图1-1)

苏南大叔的“程序如此灵动”技术博客,记录苏南大叔的编程经验文章。本文测试环境:win10nginx@1.15.11php@8.2.10-nts

__call(),访问成员方法

__call($name,$arguments),访问一个【不能访问】的成员方法时触发。
测试代码:

class SN
{
    public function __call($name,$arguments)
    {
        echo "======", __METHOD__, PHP_EOL;
        echo "试图调用方法:", $name, PHP_EOL;
        echo "试图传递参数:", PHP_EOL;
        var_dump($arguments);
    }
    private function study2(){
        echo "私有方法,也会触发__call()";
    }
}
$sn = new SN;
$sn->study("西语", "韩语");
$sn->study2("西语", "韩语");

输出:

======SN::__call
试图调用方法:study
试图传递参数:
array(2) {
  [0]=>
  string(6) "西语"
  [1]=>
  string(6) "韩语"
}

======SN::__call
试图调用方法:study2
试图传递参数:
array(2) {
  [0]=>
  string(6) "西语"
  [1]=>
  string(6) "韩语"
}

__callStatic(),静态成员方法

__callStatic($name,$arguments),访问一个【不能访问】的成员静态方法时触发。
测试代码:

class SN2
{
    public static function __callStatic($name,$arguments)
    {
        echo "======", __METHOD__, PHP_EOL;
        echo "试图调用方法:", $name, PHP_EOL;
        echo "试图传递参数:", PHP_EOL;
        var_dump($arguments);
    }
    private static function learn2(){
        echo "私有静态方法,也会触发__callStatic()";
    }
}
SN2::learn("韩语", "日语");
SN2::learn2("韩语", "日语");

输出:

======SN2::__callStatic
试图调用方法:learn
试图传递参数:
array(2) {
  [0]=>
  string(6) "韩语"
  [1]=>
  string(6) "日语"
}

======SN2::__callStatic
试图调用方法:learn2
试图传递参数:
array(2) {
  [0]=>
  string(6) "韩语"
  [1]=>
  string(6) "日语"
}

正确理解:“不能访问”

下面的例子里面,为了禁用__clone(),设置对应方法为private。然而private function __clone()因为无法访问,则会触发public function __call(),是不是有点意思?

class SN
{
    public function __call($name,$arguments)
    {
        echo "======", __METHOD__, PHP_EOL;
        echo "试图调用方法:", $name, PHP_EOL;
        echo "试图传递参数:", PHP_EOL;
        var_dump($arguments);
    }
    private function __clone(){
        echo "私有方法,也会触发__call()";
    }
}
$sn = new SN;
$sn->__clone();

输出:

======SN::__call
试图调用方法:__clone
试图传递参数:
array(0) {
}

定义了这个public function __call()之后,就像在固若金汤的类定义上开了个后门...

相关文章

结束语

很显然,只要外部无法访问到对应的方法,就会触发魔术函数__call(),__callStatic()。这种“无法访问”包括:没有定义相关方法,或者权限设置为私有的方法。

愿不愿意查看一下苏南大叔的更多php经验文章呢?请点击:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   php