何时使用PHP stdClass

时间:2014-01-25 17:16:19

标签: php oop

以下代码来自Google的recaptcha库。他们使用了一个单独的类,而不是使用stdClass。我理解为什么如果它们预先设置属性(对于给定值或甚至为NULL)会有帮助,但是在这种情况下不明白为什么它们这样做。这样做是否有任何价值,或者stdClass更合适?

class ReCaptchaResponse {
        var $is_valid;
        var $error;
}
$recaptcha_response = new ReCaptchaResponse();
$recaptcha_response->is_valid = false;
$recaptcha_response->error = 'incorrect-captcha-sol';

5 个答案:

答案 0 :(得分:3)

  

这样做是否有任何价值,或者stdClass是否更合适

  1. ReCapchaResponse比stdClass
  2. 更友好
  3. 增加了在将来扩展课程的可能性,而无需修改其他部分。
  4.   

    为什么要使用stdClass?我们不能在所有相同的情况下使用数组吗?

    如果要将数据从一个函数传递到另一个函数并修改数据,则可以使用stdClass。您可以使用关联数组执行相同的操作,但如果您错过了引用调用,则可能会出现错误。

    $a = array();
    function test1(&$a) {
        $a['key'] = 1234;
    }
    test($a);
    
    function test2($a) { // possible error
        $a['key'] = 1234;
    }
    test2($a);
    
    $a = new stdClass();
    function test3($a) {
        $a->key = 1234;
    }
    test3($a);
    

    但在实际情况下,这种类型的结构极不可能。

答案 1 :(得分:2)

这部分是一个意见问题,但我个人从未使用stdClass,我从来没有理解这样做的意义。

对象的目的是封装数据和行为,无论是通过向对象添加公共和私有方法,使用继承和多态来构建项目,还是仅具有明确定义的命名类型。

在某些语言中,例如JavaScript,一个对象作为通用键值存储很有用,即使属性是完全临时添加的;在PHP中,该角色可以通过关联数组简单有效地填充。

有些人会使用stdClass个对象作为键值存储,但是通过这样做会失去对数组周围所有函数的使用。 As ZubaiR points out above一个对象将被传递/分配为一种指针(与通过引用传递变量相同),而不是根据需要进行复制,因此表现不同,但如果你不是故意使用OOP的“封装”方面(在这种情况下你可能会创建一个类),很难说这是好事还是只是一个混乱的机会。

在其他语言中,例如C,有一种定义自定义“struct”类型的方法,具有预定义的命名成员。 PHP没有这种类型,但是一个简单的无方法类就像你展示的类非常接近。

其他语言中不适用于PHP的另一个优点是对象的基类可以具有某些功能,甚至 - 如在JavaScript或Ruby中 - 允许您添加某些功能。在PHP中,stdClass完全是惰性的,无法编辑,as pointed out elsewhere实际上并未用作其他对象的基类;只有“魔法”才能成为投射内容或"juggled"object类型时的目标类。

使用命名类的直接好处包括:

  • PHP引擎,以及IDE和代码嗅探器等工具,知道“应该”存在哪些属性,如果设置了无效属性,可以发出警告,例如:通过拼写错误
  • 您可以检查传递的特定值是否是正确的对象类型(使用instanceOf)而不是
  • 您可以稍后轻松扩展该对象以获得额外功能,或使其成为继承层次结构的一部分等。

答案 2 :(得分:0)

例如,将此类视为将来的接口和可扩展性。 ReCaptchaResponse也是stdClass。

你应该向作者询问他的想法。

答案 3 :(得分:0)

ReCaptchaResponsestdClass更易于阅读和理解。

但是以编程方式它是一样的。

答案 4 :(得分:0)

我个人永远不会编写任何实例化stdClass实例的新代码。

通过创建自己的类,即使您根本不添加任何功能,也可以明确说明该对象代表什么,例如,API客户端返回的结果,并且使用该API的人可以键入提示类,以确保通过该类型的对象。

此外,如果您将对象用作简单的数据容器,通常可以实施ArrayAccessCountable以及IteratorIteratorAggregate-这样,您可以遍历它或像访问数组一样访问它,这非常有用。