什么时候应该使用 stdClass,什么时候应该在 php oo 代码中使用数组?

在进行大规模重构的过程中,我希望引入 stdClass * * * * 作为从函数返回数据的一种方式,我正试图找到非主观的参数来支持我的决定。

有没有什么情况下,什么时候用一个比另一个更好?

使用 stdClass 而不是数组有什么好处?


有些人会说,函数必须尽可能地小和具体,才能返回一个单独的值。我使用 stdClass 的决定是暂时的,因为我希望长期为每个进程找到正确的值对象。

18602 次浏览

通常的方法是

  • 返回具有固定分支的已定义数据结构时使用对象:

     $person
    -> name = "John"
    -> surname = "Miller"
    -> address = "123 Fake St"
    
  • Use arrays when returning a list:

      "John Miller"
    "Peter Miller"
    "Josh Swanson"
    "Harry Miller"
    
  • Use an array of objects when returning a list of structured information:

      $person[0]
    -> name = "John"
    -> surname = "Miller"
    -> address = "123 Fake St"
    
    
    $person[1]
    -> name = "Peter"
    -> surname = "Miller"
    -> address = "345 High St"
    

Objects are not suitable to hold lists of data, because you always need a key to address them. Arrays can fulfill both functions - hold arbitrary lists, and a data structure.

Therefore, you can use associative arrays over objects for the first and third examples if you want to. I'd say that's really just a question of style and preference.

@Deceze makes a number of good points on when to use an object (Validation, type checking and future methods).

使用 stdClass来实现与数组相同的功能并不是非常有用,因为它只是增加了对象的开销,而没有任何实际的好处。您还错过了许多有用的数组函数(例如 array_intersect)。您至少应该创建自己的类以启用类型检查,或者向对象添加方法以使其值得使用对象。

有三个不同之处:

  • 这就是为什么传递数组参数的默认值是 按价值调用,传递对象的默认值是 通过分享打电话
  • 有一个语义上的区别。如果使用对象,任何读取代码的人都会理解,该值表示模型的某种实体,而数组应该充当集合或映射
  • 最后但并非最不重要的是,重构变得非常容易。如果希望使用具体的类而不是 stdClass,那么只需要实例化另一个类。它还允许您添加方法。

你好
反击

我不认为在数组上使用 stdClass 有任何合理的优势,只要您的唯一目的是 从函数调用返回多个任意数据类型

由于在技术上不能本地返回多个值,因此必须使用一个容器来容纳 PHP 中可用的所有其他数据类型。它可以是一个对象或者一个数组。

function fn1() { return array(1,2); }
function fn2() { return array('one' => 1, 'two' => 2); }
function fn3() { return (object) array(1,2); }
function fn4() { return (object) array('one' => 1, 'two' => 2); }

以上所有方法都可行。数组的速度快得可以忽略不计,输入工作也更少。与通用的 stdClass 相比,它还有一个明确定义的用途(这有点模棱两可,不是吗)。两者都只有一个隐式接口,因此您必须查看文档或函数体才能知道它们将包含什么。

如果您想不惜一切代价使用对象,您可以使用 数组对象SplFixedArray,但是如果您查看它们的 API,您会说您需要它们的功能来完成返回随机多个值的简单任务吗?我不这么认为。但是不要误解我的意思: 如果您想使用 stdClass,那么就使用它。又不会弄坏什么东西。但你也不会得到任何东西。为了至少增加一些好处,您可以为此创建一个名为 Return nValue 的单独类。

可能是一个简单的标记类

class ReturnValues {}

或者更实用的东西

class ReturnValues implements Countable
{
protected $values;
public function __construct() { $this->values = func_get_args(); }
public function __get($key) return $this->values[$key]; }
public function count() { return count($this->values); }
}

当然,它并没有做很多事情,从中获取值仍然是通过一个隐式接口完成的,但是至少类现在有了一个更清晰定义的职责。您可以从这个类进行扩展,为特定操作创建 Return nValue 对象,并为它们提供一个显式接口:

class FooReturnValues extends ReturnValues
{
public function getFoo() { return $this->values['foo']; }
public function getBar() { return $this->values['foo']; }
}

现在开发人员只需查看 API 就可以知道返回哪些多个值 foo ()。当然,必须为每个可能返回多个值的操作编写具体的 Return nValue 类可能会很快变得乏味。就我个人而言,我觉得这个设计过于复杂了。

不管怎样,希望你能理解。

当我需要保持代码整洁并且有些像句子一样可读时,我发现数组上的 stdClass 对象非常有用。以函数 getProperties()为例,它返回一组属性,比如关于一个人的数据(姓名、年龄、性别)。如果 getProperties()返回一个关联数组,当你想使用其中一个返回的属性时,你需要写两条指令:

$data = getProperties();
echo $data['name'];

另一方面,如果 getProperties()返回一个 stdClass,那么你可以只用一条指令来写:

echo getProperties()->name;

我能找到的唯一客观的信任票是:

json_decode默认使用 stdClass,因此我们用户界的普通人应该在类似情况下使用 stdClass。

在数组和标准类的测试中,php 处理动态属性的速度比关联数组慢。我这样说不是为了讨论微观优化,而是如果你要这样做,你最好定义一个没有方法和设置公共属性的数据类。如果你使用的是 php 5.4 + 。在引擎盖下定义的属性直接映射到一个 c 数组,其中没有哈希表,而动态的属性需要使用哈希表。

这有额外的好处,以后成为一个完整的类没有任何主要的接口重新工作。