4

我不确定PHP中的方法__get和方法的价值是什么。__set

这是在数组中设置值的代码。

class myclass {
public $sotre = array();

public function __set($arraykey,$value){
    echo 'Setting '.$arraykey.' to '.$value;
    $this->store[$arraykey] = $value;
} 
}

$obj = new myclass;
$obj->a = 'arfan';

这是另一个代码。

 class myclass {
public $sotre = array();

public function setvalue($arraykey,$value){
    echo 'Setting '.$arraykey.' to '.$value;
    $this->store[$arraykey] = $value;
} 
}

$obj = new myclass;
$obj->setvalue('a','arfan');

这两个函数做同样的事情。

使用__get/__set魔术方法的代码:

class myclass {
public $store = 
array(
    'a'=>'arfan',
    'b'=>'azeem',
    'c'=>'hader'
);

public function __get($arraykey){
    echo 'Getting array key '.$arraykey.'<br />';
    if(array_key_exists($arraykey,$this->store)){
        return $this->store[$arraykey];
    }
}

public function getvalue($arraykey){
    echo 'Getting array key '.$arraykey.'<br />';
    if(array_key_exists($arraykey,$this->store)){
        return $this->store[$arraykey];
    }
}
}

$obj = new myclass;
 echo $obj->a;

$obj = new myclass;
echo $obj->getvalue('a');

如您所见,这两个功能都做同样的工作。

我很困惑为什么 PHP 开发人员会使用魔法方法__get/__set什么时候可以自己实现?

我敢肯定它们有一些用处,但我一定遗漏了一些东西。

4

4 回答 4

12

这不是关于它们做什么,而是它们何时被调用。

__set() is run when writing data to inaccessible properties.

__get() is utilized for reading data from inaccessible properties.

所以如果你想

echo $object->propertDoesnExists; //it will call get

但是这个

$object->propertDoesnExists = 1; //it will call set

使用 get 和 set 方法的一个很好的例子是here

使用MagicMethods使代码更易于阅读且更短。

还有更多有趣的MagicMethods

我还注意到您使用$store的是 PUBLIC 数组!这没有任何意义。如果您将其标记为公开,则无需使用方法即可访问它。这不是重点。当您使用方法或魔术方法来获取/设置变量时,这是因为方法可以让您更好地控制您想要分配或获取变量时,您可以进行一些验证,检查错误等。将变量设为公开被称为非常糟糕的约定. 在项目的每个地方都可以在类外访问公共成员,如果发生错误需要检查很多代码,当通过方法访问的私有成员出现问题时,可能只有两种方法可以检查(get/set)。

于 2013-05-20T09:53:56.270 回答
1

因为已经告诉过有什么区别,所以我将尝试解释其目的。

这些神奇的功能实际上是为一些代码清除而设计的。有些人认为 call$object->property比 call 更清楚$object->getProperty()

当您使用链接时会更清楚,即。object->getDatabase()->getTable()->getRow()->getType()->convertToString()->makeUppercase()等使用“隐藏属性”更清楚。

使用魔法方法并不能解决一些问题(比如通过引用调用),但有时它更容易阅读。

使用属性在某些语言中非常流行(例如 Object Pascal,即 Delphi 或 FreePascal),您的类可以具有以下内容:

property count: Integer read getCount write getCount;

其中getCount()setCount()都是私有的或受保护的。编码人员可以将它们视为变量,但会调用方法。

__get()在 PHP 中, (and __set()) 魔术方法也有一些优点。通常,当您致电不存在的财产时,会发出通知。但是,如果您实现__get()方法,则不会给出通知,并且您可以编写__get()方法,例如NULL在任何情况下返回该属性不存在,或处理错误或其他任何情况。

对于这可能有什么危险(但也有可能),请看这里的最后一个例子。

于 2013-05-20T10:04:20.547 回答
0

这种神奇的方法就像捷径一样。其他语言,如 Python、C# 和 Ruby 也实现了此功能。

我认为当您需要将 PHP 代码放入 HTML 模板时,这会更有用:

foreach($items as $item):
    ?>
    <li>
        Title: <?php echo $item->getTitle(); ?> <br/>
        Description: <?php echo $item->getLongDescription(); ?> <br/>
        URL: <?php echo $item->getAbsoluteUrl(); ?> <br/>
    </li>
    <?php
endforeach;

这比上面的更具可读性:

foreach($items as $item):
    ?>
    <li>
        Title: <?php echo $item->title; ?> <br/>
        Description: <?php echo $item->longDescription; ?> <br/>
        URL: <?php echo $item->absoluteUrl; ?> <br/>
    </li>
    <?php
endforeach;

所以,你是对的,绝对没有区别,这只是一种让事情变得更容易的方法。

于 2013-05-20T10:08:15.813 回答
0

__set()在将数据写入不可访问的属性时运行。

__get()用于从不可访问的属性中读取数据。

前任。

public void __set ( string $name , mixed $value )

前任。

public mixed __get ( string $name )
于 2015-12-15T19:46:34.620 回答