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

时间:2010-07-07 10:08:01

标签: php oop stdclass

在工作中进行大量重构的过程中,我希望引入stdClass *****作为从函数返回数据的方法,并且我试图找到支持我的决定的非主观参数。 / p>

是否有任何情况何时最好使用一个而不是另一个?

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


有些人会说函数必须尽可能少且具体,才能返回一个值。我决定使用stdClass是暂时的,因为我希望从长远来看为每个进程找到正确的Value Objects。

7 个答案:

答案 0 :(得分:59)

通常的方法是

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

     $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"
    

对象不适合保存数据列表,因为您始终需要一个键才能解决这些问题。数组可以实现两种功能 - 保持任意列表和数据结构。

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

@Deceze在何时使用对象(验证,类型检查和未来方法)方面提出了许多好处。

答案 1 :(得分:41)

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

答案 2 :(得分:18)

我不认为在数组上使用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相比,它也有一个明确定义的目的(有点白痴,不是这样)。两者都只有一个隐式接口,因此您必须查看文档或函数体以了解它们将包含的内容。

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

可以是一个简单的标记类

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

当然,它并没有做太多的事情,并且从中获取值仍然是通过一个隐含的界面完成的,但至少该类现在有更明确的责任。您可以从此类扩展为特定操作创建ReturnValue对象,并为这些对象提供显式接口:

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

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

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

答案 3 :(得分:4)

嗯,有3个不同之处:

  • 他们有身份。这就是为什么传递数组参数的默认值是按值调用和对象通过共享调用
  • 存在语义差异。如果你使用一个对象,任何阅读代码的人都会理解,该值代表模型的某种权利,而数组应该作为集合或地图。
  • 最后但并非最不重要的是,重构变得非常容易。如果你想使用一个具体的类而不是stdClass,你所要做的就是实例化另一个类。这也允许您添加方法。

格尔茨
back2dos

答案 4 :(得分:2)

我能找到的唯一目标投票是:

json_decode默认使用stdClass,因此我们在userland中的凡人应该使用stdClass来处理类似情况。

答案 5 :(得分:1)

我发现数组上的stdClass对象非常有用,因为我需要保持代码干净,并且有点类似句子的可读性。以函数getProperties()为例,它返回一组属性,比如一个人的数据(姓名,年龄,性别)。如果getProperties()将返回一个关联数组,当您想要使用其中一个返回的属性时,您将编写两条指令:

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

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

echo getProperties()->name;

答案 6 :(得分:1)

在array vs stdclass的测试中,php处理动态属性的方式比关联数组慢。我不是说这是为了争论微优化,而是如果你要做到这一点,最好定义一个没有方法的数据类并设置公共属性。 Esp如果您使用的是PHP 5.4+。在引擎盖下,定义的属性直接映射到没有散列表的c数组,而动态的需要使用散列表。

这有额外的好处,后来成为一个没有任何主要界面重做的完整课程。