php __set(),__ get和简单的seting,获取函数之间的区别

时间:2013-05-20 09:50:50

标签: php oop magic-methods

我不确定在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 个答案:

答案 0 :(得分: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!没有任何意义。如果您将其标记为公开,则无需使用方法即可访问。这不是重点。当您使用方法或魔术方法来获取/设置变量时,因为方法可以在您想要分配或获取变量时提供更好的控制,您可以进行一些验证,检查错误等。将变量设置为公共被称为非常糟糕的约定。公共成员可以在项目的每个地方访问类外,如果发生错误,需要检查很多代码,当通过方法访问的私有成员出现问题时,可能只有2种方法需要检查(获取/设置)。

答案 1 :(得分:1)

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

这些神奇的功能实际上是为了一些代码清除。有些人认为调用$object->property比调用$object->getProperty()更明确。

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

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

在一些语言中使用属性非常流行(比如Object Pascal,即Delphi或FreePascal),你的类可以有类似的东西:

property count: Integer read getCount write getCount;

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

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

对于这可能存在的危险(也包括可能性),请查看最后一个示例here

答案 2 :(得分: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;

所以,你是对的,绝对没有区别,它只是一种让事情变得简单的方法。

答案 3 :(得分:0)

将数据写入不可访问的属性时会运行

__set()

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

实施例

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

EX。

public mixed __get ( string $name )