PHP魔术方法的实际应用--__get,__ set和__call

Maj*_*ons 13 php magic-methods

我一般都试图远离PHP的魔术方法,因为它们似乎混淆了对象的公共接口.也就是说,至少在我读过的代码中,它们似乎被越来越多地使用了,所以我不得不问:对何时使用它们有什么共识?使用这三种魔术方法有什么共同的模式吗?

jwu*_*ler 5

主要原因是您不需要输入太多内容。例如,您可以将它们用于 ORM 记录并充当隐式 setter/getter:

使用__call()

$user = new User();
$user->setName("Foo Bar");
$user->setAge(42);
$user->save();
Run Code Online (Sandbox Code Playgroud)

使用__set()

$user->name = "Foo Bar";
$user->age = 42;
Run Code Online (Sandbox Code Playgroud)

它映射到一个简单的数组:

array(
    "name" => "Foo Bar",
    "age"  => 42
)
Run Code Online (Sandbox Code Playgroud)

将这样的数组写入数据库比进行大量手动调用来收集所有需要的信息要容易得多。__set()与公共成员相比,还有__get()另一个优势:您可以验证/格式化您的数据。


Den*_*rdy 4

__call()

我见过它用于实现行为,例如通过可插入接口向类添加额外的函数。

伪代码如下:

$method = function($self) {};
$events->register('object.method', $method);
$entity->method(); // $method($this);
Run Code Online (Sandbox Code Playgroud)

它还使得编写大部分相似的函数变得更加容易,例如在 ORM 中。例如:

$entity->setName('foo'); // set column name to 'foo'
Run Code Online (Sandbox Code Playgroud)

__get()/__set()

我主要看到它用于包装对私有变量的访问。

ORM 是我想到的最好的例子:

$entity->name = 'foo'; // set column name to 'foo'
Run Code Online (Sandbox Code Playgroud)