PHP - 重载


在 C++ 或 Java 中,该术语表示一个类可以多次使用同名但具有不同参数和/或返回类型的类方法。在 PHP 中,重载(overloading)有不同的解释。这是一个可以动态创建属性和方法的功能。

PHP 魔术方法(方法名称以双下划线开头)用于设置动态属性和方法。

用于重载目的的魔术方法在与尚未声明或在当前范围内不可见的属性或方法交互时调用。

属性重载

PHP 魔术方法示例是 __construct()__destruct()__tostring(),etc. PHP 使用以下魔术方法来重载属性。


public __set ( string $name , mixed $value ) : void
public __get ( string $name ) : mixed
public __isset ( string $name ) : bool
public __unset ( string $name ) : void

这里

  • 运行 __set() 是为了将数据写入受保护、私有或不存在的不可访问属性。
  • __get() 从无法访问的属性中读取数据。
  • __isset() 在无法访问的属性上调用 isset() 或 empty()
  • __unset() 在无法访问的属性上调用 unset() 时调用。

上面使用的 $name 参数是要设置或检索的属性的名称。__set() 方法的 $value 参数指定要分配给属性的值。

__isset() 方法检查是否已设置某个属性。__unset() 方法将删除该属性。

属性重载 仅在 对象上下文 中有效。在任何 静态上下文 中,都不会触发这些魔术方法。因此,不应将它们声明为 static

例子

在下面的代码中,设置并检索了一个名为 myprop 的动态属性,该属性未在类中声明。


<?php
   class myclass {
      public function __set($name, $value) {
         echo "将 $name 属性设置为 $value \n";
         $this->$name = $value;
      }

      public function __get($name) {
         echo "$name 属性的值为 ";
         return $this->$name;
      }
   }

   $obj = new myclass();

   # 这将调用__set()方法
   $obj->myproperty="Hello World!";

   # 此调用__get()方法
   echo "正在检索myproperty: " . $obj->myproperty . PHP_EOL;
?>

它将产生以下输出 -

将 myproperty 属性设置为 Hello World!
正在检索myproperty: Hello World!

__set() 和 __get() 神奇方法还设置和检索一个被声明为 private 的属性。在  中添加以下语句(在函数定义之前)


 private $myproperty;

你可以检查属性,在 myclass 定义 __isset() 方法 -


public function __isset($name) {
   return isset($this->$name);
}

检查是否使用此语句设置了该属性 -


 var_dump (isset($obj->myproperty));

在本例中,which 返回 true

要使用 myclass 中定义的 __unset() 方法取消设置动态创建的属性 -


public function __unset($name) {
   unset($this->$name);
}

以下代码将返回 false -


 var_dump (isset($obj->myproperty));

方法重载

用于动态设置方法的两个魔术方法是 __call() 和 __callStatic()


public __call (string $name , array $arguments) : mixed
public static __callStatic (string $name , array $arguments) : mixed

当在对象上下文中调用不可访问(未定义或私有)方法时,将触发 __call()。另一方面,当在静态上下文中调用无法访问的方法时,会触发 __callStatic()

例子

以下示例演示了 PHP 中的方法重载


<?php
   class myclass {
      public function __call($name, $args) {
      
         // $name的值区分大小写。
         echo "使用以下命令 $name 调用对象方法" . implode(" ", $args). "\n";
      }
      public static function __callStatic($name, $args) {
         echo "使用以下命令 $name 调用静态方法" . implode(" ", $args). "\n";
      }
   }
   $obj = new myclass();

   # 这将调用__call()魔术方法
   $obj->mymethod("Hello World!");

   # 这将调用__callStatic()方法
   myclass::mymethod("Hello World!");
?>

它将产生以下输出 -

使用以下命令 mymethod 调用对象方法Hello World!
使用以下命令 mymethod 调用静态方法Hello World!

注意:使用 “->” 运算符表示该方法是 实例方法,而 “::” 运算符表示该方法是 静态方法