首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >PHP魔术方法的实际应用- __get、__set和__call

PHP魔术方法的实际应用- __get、__set和__call
EN

Stack Overflow用户
提问于 2011-05-12 22:46:23
回答 6查看 4.3K关注 0票数 13

我通常尽量避免使用PHP的魔术方法,因为它们似乎混淆了对象的公共接口。也就是说,它们似乎越来越多地被使用,至少在我读过的代码中是这样,所以我不得不问:在什么时候使用它们有什么共识吗?使用这三种神奇方法有什么共同的模式吗?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-05-12 23:00:27

__call()

我见过它用于实现行为,就像通过可插拔接口向类添加额外的函数一样。

伪代码如下:

代码语言:javascript
复制
$method = function($self) {};
$events->register('object.method', $method);
$entity->method(); // $method($this);

它还使得编写大多数类似的函数变得更容易,比如在ORM中。例如:

代码语言:javascript
复制
$entity->setName('foo'); // set column name to 'foo'

__get()/__set()

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

ORM是脑海中浮现的最好的例子:

代码语言:javascript
复制
$entity->name = 'foo'; // set column name to 'foo'
票数 4
EN

Stack Overflow用户

发布于 2011-05-12 22:50:52

主要原因是您不需要键入那么多内容。比方说,您可以将它们用于ORM记录,并充当隐式setter/getter:

使用__call()

代码语言:javascript
复制
$user = new User();
$user->setName("Foo Bar");
$user->setAge(42);
$user->save();

使用__set()

代码语言:javascript
复制
$user->name = "Foo Bar";
$user->age = 42;

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

代码语言:javascript
复制
array(
    "name" => "Foo Bar",
    "age"  => 42
)

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

票数 4
EN

Stack Overflow用户

发布于 2011-05-12 23:31:59

它允许你这样做:

代码语言:javascript
复制
class myclass {
    private $propertybag;

    public function __get($name) {
        if(isset($this->propertybag[$name]) {return $this->propertybag[$name];}
        throw new Exception("Unknown property " . (string) $name);
    }

 }

然后,您可以在一行中从SQL查询填充$propertybag,而不是一个接一个地设置一大堆属性。

此外,它还允许您拥有特定的属性,这些属性是只读的(即不允许通过__set()修改)。例如,可能对ID字段有用。

此外,您还可以将代码放入__get()__set()中,这样您就可以做一些比获取或设置单个变量更复杂的事情。例如,如果您有一个storeID字段,您可能还想提供一个storeName属性。您可以通过交叉引用查找在__get()中实现它,因此您可能不需要将名称实际存储在类中。当然,不希望在__get()中实现storeName

有很多可能性。

当然,使用魔法方法也有一些缺点。对我来说,最大的问题是你失去了IDE中的自动完成功能。这对你可能重要,也可能无关紧要。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5979830

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档