为什么返回对象而不是数组?

时间:2011-07-15 17:32:52

标签: php

我在WordPress中做了很多工作,我注意到有更多的函数返回对象而不是数组。除非您特别要求数组,否则数据库结果将作为对象返回。错误作为对象返回。在WordPress之外,大多数API都会为您提供一个对象而不是一个数组。

我的问题是,为什么他们使用对象而不是数组?在大多数情况下,它并不重要,但在某些情况下,我发现物体不仅难以加工而且能够缠绕我的头部。是否有使用对象的性能原因?

我是一名自学成才的PHP程序员。我有文科学位。如果我错过了计算机科学的一个基本方面,请原谅我。 ;)

15 个答案:

答案 0 :(得分:61)

这些是我更喜欢一般物体的原因:

  • 对象不仅包含数据,还包含功能。
  • 对象具有(在大多数情况下)预定义的结构。这对API设计非常有用。此外,您可以将属性设置为public,protected或private。
  • 对象更适合面向对象的开发。
  • 在大多数IDE中,自动完成仅适用于对象。

以下是阅读内容:

答案 1 :(得分:24)

在您从事大型软件项目多年之前,这可能不是您将要深入理解的内容。许多新的计算机科学专业的学生会给你一个答案,包括所有正确的单词(封装,数据功能和可维护性),但很少有人会真正理解为什么所有这些东西都很好。

让我们来看几个例子。

  • 如果返回了数组,则需要预先计算所有值,或者需要返回许多小值,您可以使用这些值来构建更复杂的值。

考虑一个返回WordPress帖子列表的API方法。这些帖子都有作者,作者有姓名,电子邮件地址,甚至可能有他们的传记。

如果要返回数组中的所有帖子,则必须限制自己返回一组帖子ID:

[233, 41, 204, 111]

或返回一个类似于:

的大型数组
[ title: 'somePost', body: 'blah blah', 'author': ['name': 'billy', 'email': 'bill@bill.com', 'profile': ['interests': ['interest1', 'interest2', ...], 'bio': 'info...']] ]
[id: '2', .....]]

返回ID列表的第一种情况对您没有多大帮助,因为您需要为每个ID进行API调用,以获取有关该帖子的一些信息。

第二种情况将提供比90%的时间更多的信息并且做更多工作(特别是如果这些字段中的任何一个非常复杂的构建)。

另一方面,对象可以让您访问所需的所有信息,但实际上尚未提取该信息。在使用对象时,可以懒惰地确定字段的值(即,当需要值时,而不是事先)。

  • 阵列公开的数据和功能多于预期的

回到返回的海量数组的示例。现在有人可能会构建一个应用程序来迭代post数组中的每个值并打印它。如果更新API以向该post数组添加一个额外的元素,那么应用程序代码将会破坏,因为它将打印一些它可能不应该的新字段。如果API返回的post数组中的项目顺序发生更改,那么也会破坏应用程序代码。因此,返回一个数组会创建一个对象无法创建的各种可能的依赖项。

  • 功能

对象可以在其中保存信息,以便为您提供有用的功能。例如,post对象可以足够聪明以返回上一个或下一个帖子。数组不可能为你做到这一点。

  • 灵活性

上述对象的所有好处有助于创建更灵活的系统。

答案 2 :(得分:10)

  

我的问题是,为什么他们使用对象而不是数组?

可能有两个原因:

  • WordPress很老了
  • 在大多数情况下,
  • 数组更快,内存更少
  • 更容易序列化
  

是否有使用对象的性能原因?

没有。但还有很多其他好的原因,例如:

  • 您可以在对象(方法,闭包等)中存储逻辑
  • 您可以使用界面强制对象结构
  • IDE中更好的自动完成
  • 您没有收到未定义数组键的通知
  • 最后,您可以轻松地将任何对象转换为数组

OOP!= AOP:)

(例如,在Ruby中,一切都是对象。以前PHP是程序/脚本语言。)

答案 3 :(得分:7)

WordPress(以及相当多的其他PHP应用程序)出于概念而非技术原因使用对象而不是数组。

一个对象(即使只是一个stdClass的实例)是一个事物的表示。在WordPress中可能是帖子,评论或用户。另一方面,数组是一组东西。 (例如,帖子列表。)

从历史上看,PHP没有很好的对象支持,因此数组在早期就变得非常强大。 (例如,具有任意键而不仅仅是零索引的能力。)利用PHP 5中提供的对象支持,开发人员现在可以选择使用数组或对象作为键值存储。就个人而言,我更喜欢WordPress方法,因为我喜欢对象和数组提供的“实体”和“集合”之间的语法差异。

答案 4 :(得分:5)

  

我的问题是,为什么他们(Wordpress)使用对象而不是数组?

这是一个很好的问题,不容易回答。我只能假设在Wordpress中使用stdClass对象很常见,因为它们使用的数据库类默认将记录作为stdClass对象返回。他们已经习惯了(8年甚至更长时间)就是这样。我不认为这个简单的事实背后有更多的想法。

  

关联数组的语法糖    - 自PHP 3以来 Zeev Suraski about the standard object

  • stdClass对象并不比数组好。他们几乎是一样的。这是由于语言的一些历史原因以及stdClass对象实际上是有限的,实际上只是value objects在一个非常基本的意义上。
  • stdClass个对象存储其成员的值,就像每个条目的数组一样。就是这样。
  • 只有PHP怪物能够使用私有成员创建stdClass个对象。没有太大的好处 - 如果有的话 - 这样做。
  • stdClass个对象没有任何方法/功能。所以在Wordpress中没有使用它。
  • array相比,处理列表或半结构化数据的功能要少得多。

但是,如果您已经习惯了数组,那么只需转换:

$array = (array) $object;

您可以将以前作为对象的数据作为数组进行访问。或者你喜欢它反过来:

$object = (object) $array;

只会删除无效的成员名称,例如数字。所以要小心一点。但我认为你得到的是全局:只要是关于stdClass的数组和对象,就没有太大区别。

相关:

答案 5 :(得分:4)

对象比数组更强大。 作为类实例的每个对象都可以附加功能。 如果您有需要处理的数据,那么您需要一个执行处理的函数。 使用数组,您必须在该数组上调用该函数,从而将逻辑本身与数据相关联。 对于一个对象,这种关联已经完成,你不必再关心它了。

另外你应该考虑信息隐藏的OO原则。并非所有从数据库返回或进入数据库的内容都应该可以直接访问。

答案 6 :(得分:4)

  1. 代码看起来很凉爽
  2. 对象通过引用传递
  3. 对象的类型比数组更强,因此可以使用错误(或者在尝试使用不存在的成员时给出有意义的错误消息)
  4. 今天所有的IDE都有自动完成功能,因此在使用已定义的对象时,IDE会为您做很多事情并加快速度。
  5. Easilly将逻辑数据封装在同一个框中,在数组中,您将数据存储在数组中,然后使用一组不同的函数来处理它。
  6. 继承,如果你有一个几乎但没有类似功能的类似数组,那么你必须复制更多的代码,如果你要用对象做的话
  7. 可能还有一些我想到的原因

答案 7 :(得分:3)

返回对象有几个原因:

  1. 撰写$myObject->property所需的“开销”字符少于$myArray['element']

  2. 对象可以返回数据和功能;数组只能包含数据。

  3. 启用链接:$myobject->getData()->parseData()->toXML();

  4. 编码更简单:IDE自动完成可以为对象提供方法和属性提示。

  5. 在性能方面,数组通常比对象快。除性能外,使用数组有几个原因:

    1. array _ *()函数系列提供的功能可以减少某些情况下所需的编码量。

    2. 可以对数组执行count()和foreach()等操作。对象不提供此功能(除非他们实现IteratorCountable)。

答案 8 :(得分:2)

通常不会出于性能原因。通常,对象的成本高于数组。

对于许多API,它可能与提供除存储机制之外的其他功能的对象有关。否则,这是一个偏好问题,返回一个对象和一个数组确实没有任何好处。

答案 9 :(得分:2)

数组只是值的索引。而对象包含可以为您生成结果的方法。当然,有时您可以直接访问对象值,但“正确的方法”是访问对象方法(对该对象的值进行操作的函数)。

$obj = new MyObject;
$obj->getName();   // this calls a method (function), so it can decide what to return based on conditions or other criteria

$array['name'];   // this is just the string "name". there is no logic to it. 

有时你直接访问一个对象变量,这通常是不受欢迎的,但它经常发生。

$obj->name;   // accessing the string "name" ... not really different from an array in this case.

但是,请考虑MyObject类没有名为“name”的变量,而是具有first_name和last_name变量。

$obj->getName();  // this would return first_name and last_name joined.
$obj->name;  // would fail...
$obj->first_name; 
$obj->last_name; // would be accessing the variables of that object directly.

这是一个非常简单的例子,但你可以看到它的发展方向。类提供了一组变量和可以在自包含逻辑实体中对这些变量进行操作的函数。该实体的一个实例称为对象,它引入了逻辑和动态结果,而数组根本没有。

答案 10 :(得分:1)

大多数时候对象和数组一样快,如果不比数组快,在PHP中没有明显的区别。主要原因是对象比数组更强大。面向对象编程允许您创建对象并不仅存储数据,而且存储其中的功能,例如在PHP中,MySQLi类允许您拥有一个数据库对象,您可以使用大量内置函数来操作它,而不是使用过程方法。

所以主要原因是OOP是一个很好的范例。我写了一篇文章,说明为什么使用OOP是一个好主意,并解释这个概念,你可以看看这里:http://tomsbigbox.com/an-introduction-to-oop/

作为次要加号,您还可以输入较少的数据来获取对象的数据 - $ test->数据优于$ test ['data']。

答案 11 :(得分:1)

我不熟悉word press。这里有很多答案表明,对象的强度是否有能力包含功能代码。从函数/ API调用返回对象时,它不应包含实用程序函数。只是属性。

返回对象的优势在于,API背后的任何内容都可以在不破坏代码的情况下进行更改。

示例:您获得一个包含键/值对的数据数组,键代表DB列。如果重命名DB列,则代码将中断。

答案 12 :(得分:1)

我在php 5.3.10(windows)中运行下一个测试:

for ($i = 0; $i < 1000000; $i++) {
    $x = array();
    $x['a'] = 'a';
    $x['b'] = 'b';
}

for ($i = 0; $i < 1000000; $i++) {
    $x = new stdClass;
    $x->a = 'a';
    $x->b = 'b';
}

http://atomized.org/2009/02/really-damn-slow-a-look-at-php-objects/comment-page-1/#comment-186961

复制

为10个并发用户调用该函数10次(为获得平均值)然后

  • 阵列:100%
  • 对象:214% - 216%(慢2倍)。

AKA,对象它仍然很痛苦。 OOP保持整洁,但应小心使用。

Wordpress正在应用什么?嗯,两种解决方案都是使用对象,数组和对象&amp;数组,类 wpdb 使用后者(它是Wordpress的核心)。

答案 13 :(得分:0)

它遵循OOP的装箱和拆箱原则。虽然Java和C#等语言本身支持这种语言,但PHP却不支持。然而,在某种程度上,它可以在PHP中完成,因为语言本身没有支持它的构造,所以不能雄辩。在PHP中使用框类型可以帮助进行链接,保持所有面向对象并允许在方法签名中进行类型提示。缺点是开销以及您现在需要使用“实例”构造进行额外检查的事实。当使用具有智能感知或像PDT之类的代码辅助的开发工具时,拥有类型系统也是一个优势。它不是google / bing / yahoo的方法,而是存在于对象上,您可以使用该工具提供下拉。

答案 14 :(得分:0)

尽管关于对象不仅仅是数据的要点是有效的,因为它们通常是数据和行为,但Martin Fowler's "Patterns of Enterprise Application Architecture"中提到的至少一种模式适用于您传输数据的此类Cenario来自一个系统(API背后的应用程序)和另一个系统(您的应用程序)。

它是Data Transfer Object - 一个在进程之间传递数据的对象,以减少方法调用的数量。

因此,如果问题是API是否应该返回DTO或数组,我会说如果性能成本可以忽略不计,那么你应该选择更易于维护的选项,我认为这是DTO选项......但是当然,您还必须考虑开发系统的团队的技能和文化以及每个选项的语言或IDE支持。