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

在工作中的重构期间,我想介绍一下stdClass *****作为从函数返回数据的方式,我试图find非主观的论据来支持我的决定。

有什么情况下最好使用一个而不是另一个?

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


有人会说,function必须尽可能less和具体,以便能够返回一个单一的值。 我决定使用stdClass是暂时的,因为我希望从长远来看为每个进程find正确的Value对象。

通常的做法是

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

    $person -> name = "John" -> surname = "Miller" -> address = "123 Fake St" 
  • 返回列表时使用数组:

      "John Miller" "Peter Miller" "Josh Swanson" "Harry Miller" 
  • 返回结构化信息列表时使用对象数组:

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

对象不适合保存数据列表,因为你总是需要一个键来解决它们。 数组可以完成这两个function – 保持任意列表和数据结构。

因此,如果需要,可以在第一个和第三个示例的对象上使用关联数组。 我会说,这只是一个风格和偏好的问题。

@Deceze在何时使用一个对象(validation,types检查和将来的方法)方面提出了很多好的观点。

使用stdClass来完成与数组相同的function并不是很有用,恕我直言,它只是增加了一个对象的开销,没有任何实际的好处。 你也错过了许多有用的数组函数(例如array_intersect )。 您至less应该创build自己的类来启用types检查,或者将方法添加到对象以使其值得使用对象。

我认为只要你的唯一目的是从一个函数调用中返回多个任意的数据types,就不会在数组上使用stdClass。

既然你不能在技术上原生返回多个值,你必须使用一个容器,它可以容纳PHP中所有其他的数据types。 这将是一个对象或数组。

 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); } 

以上所有都将起作用。 该arrays是一个微不足道的小部分更快,更less的工作types。 它也有一个明确的目的,与通用的stdClass(有点wishywashy,不是它)。 两者都只有一个隐式的接口,所以你将不得不看看文档或函数体来知道它们将包含什么。

如果你想不惜任何代价地使用对象,你可以使用ArrayObject或SplFixedArray ,但是如果你看看他们的API,你会说你需要他们的function来完成随机多个值的简单任务吗? 我不这么认为。 不要误解我的意思,如果你想使用stdClass,那就使用它。 这不像它会打破任何东西。 但是你也不会获得任何东西。 要添加至less一些好处,您可以为此创build一个名为ReturnValues的单独类。

可能是一个简单的标签类

 class ReturnValues {} 

或更多function的东西

 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); } } 

当然,这样做并没有多大的作用,并且通过一个暗示接口来完成这个值,但是现在至less这个类已经有了一个更明确的责任。 你可以从这个类inheritance来为特定的操作创buildReturnValue对象,并为它们提供一个明确的接口:

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

现在,开发人员只需查看API即可知道foo()将返回多个值。 当然,为每个可能返回多个值的操作编写具体的ReturnValue类可能会很快变得乏味。 而且我个人认为,这是为了最初的目的而过度工作的。

无论如何,希望是有道理的。

那么有三个不同之处:

  • 他们有一个身份。 这就是为什么传递数组参数的默认按值调用,而对于通过共享调用的对象。
  • 有一个语义上的差异。 如果你使用一个对象,任何读取代码的人都会理解,这个值代表模型的某种实体,而一个数组应该作为一个集合或者一个映射
  • 最后但并非最不重要的一点是,重构变得非常容易。 如果你想使用一个具体的类而不是stdClass,你只需要实例化另一个类。 这也可以让你添加方法。

格尔茨
back2dos

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

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

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

 echo getProperties()->name; 

我能find的唯一目标投票是:

json_decode默认使用stdClass,所以我们凡人在userland应该使用stdClass类似的情况。

在数组和stdclass的testing中,php处理dynamic属性的方式比关联数组慢。 我不是说这个来争论微型优化,而是如果你要做到这一点,你最好定义一个没有方法的数据类,并设置公共属性。 特别是如果你使用PHP 5.4 +。 在引擎盖下定义的属性直接映射到没有散列表的ac数组,因为dynamic的需要使用散列表。

这有一个额外的好处,以后成为一个完整的类没有任何重大的接口重做。