在PHP面向对象的代码中,何时应该使用stdClass,何时应该使用数组?
在PHP面向对象的代码中,何时应该使用stdClass,何时应该使用数组?这个问题的出现是因为当我们想要从一个函数调用中返回多个任意数据类型时,使用stdClass没有任何合理的优势。由于在PHP中无法本地返回多个值,我们必须使用一个可以容纳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相比,它还具有明确定义的用途(stdClass有点含糊不清,不是吗)。它们都只有一个隐式接口,所以你必须查看文档或函数体来知道它们将包含什么内容。
如果你想要以任何代价使用对象,你可以使用ArrayObject或SplFixedArray,但是如果你查看它们的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类可能会很快变得乏味。就我个人而言,我认为这对于最初的目的来说过于过度设计。
总之,希望这有一些意义。
有趣的"ReturnValues"建议。
谢谢。我认为它的两个主要优点是:使返回的对象在语义上更清晰,并使其接口显式化。如果这些都不重要,那么在我看来,这种方法就没有用处。
我喜欢这种在特定领域/目的中是通用的类的想法。它有可能真正增加功能,而stdClass只是关联数组的另一种表示形式。
我认为稍微更易读的语法对大多数开发者来说是主要的好处。然而,使用`$options = ['a'=>'str', 'b'=>'str'];`几乎同样简洁,并且允许使用为数组构建的许多本地/强大的函数。因此,除非我需要匹配JSON结构,否则我会坚持使用数组。
在PHP面向对象代码中,何时应该使用stdClass,何时应该使用数组?
通常的方法是:
- 当返回一个具有固定分支的定义数据结构时,使用对象;
- 当返回一个列表时,使用数组;
- 当返回一个结构化信息的列表时,使用对象数组。
对象不适合保存数据列表,因为你总是需要一个键来访问它们。数组可以同时满足这两个功能-保存任意列表和数据结构。
因此,如果你愿意,你可以在第一个和第三个例子中使用关联数组来代替对象。我认为这只是一个风格和偏好的问题。
在何时使用对象方面,有一些很好的观点(验证、类型检查和未来的方法)。我非常喜欢和赞同第一和第二个观点。
我要求"非主观性的"论点,但遗憾的是没有给出。我将坚持你的答案(按照他人的投票)作为我从现在开始要遵循的:数组用于列表;stdClass用于"多值"/属性。
我强烈不同意这一观点。如果你只有数据,即使是结构化数据,你也应该使用数组。对象是数据和相关行为的组合体。使用stdClass作为数组只是对stdClass的滥用。
同意GordonM的观点,通过使用stdClass来制造一个合适的对象只会带来更多的伤害。在我看到stdClass被开发人员使用的几乎所有情况下,它都是在滥用动态属性——这让人非常困惑,不知道类的结构是什么,即使这个结构被遵守,因为几乎每次使用都涉及到"即兴"填充属性。如果可能会错过属性或者不能费心创建一个真正的类,还不如使用数组。
这不是一个客观的答案。
对于。此外,我在看到一个开发人员使用stdClass时,该开发人员都是在使用它的幻觉,认为代码是"面向对象的",但实际上并不是。在我看来,stdClass可能唯一有用的地方可能是在测试案例中。我不记得我曾经以这种方式使用过它。我认为它应该从PHP语言中被废除。