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

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

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

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

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

  • 对象不仅包含数据,还包含function。
  • 对象具有(在大多数情况下)预定义的结构。 这对于APIdevise非常有用。 此外,您可以将属性设置为公共,受保护或私有。
  • 对象更适合面向对象的开发。
  • 在大多数IDE中,自动完成只适用于对象。

这里有一些东西可以阅读:

  • 对象VS. PHP中的数组
  • PHP stdClass:将数据存储在对象而不是数组中
  • 什么时候应该使用stdClass,什么时候应该在php5 oo代码中使用数组
  • PHP对象与数组
  • Mysql导致PHP – 数组或对象?
  • PHP对象与数组的性能神话
  • PHP中的一组对象:数组与SplObjectStorage
  • 更好的面向对象的数组

这可能不是你要深入了解,直到你从事一个大型软件项目多年。 许多新的计算机科学专业的学生会给你一个答案,包括封装,数据function和可维护性,但很less有人真正理解为什么这些东西是好的。

我们来看几个例子。

  • 如果返回数组,则所有的值都需要先计算出来,否则需要返回大量的小数值,从中可以构build更复杂的值。

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

如果要返回数组中的所有post,则必须限制自己返回一个postID数组:

[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调用,以获取有关该post的一些信息。

第二种情况会让你获得更多的信息,而不是你需要90%的时间,并且做更多的工作(特别是如果这些领域中的任何一个非常复杂的话)。

另一方面,一个对象可以让你访问你所需要的所有信息,但是实际上并没有获取这些信息。 确定字段的值可以在使用对象时懒惰地完成(也就是说,当需要而不是预先设置时)。

  • 数组暴露了比预期更多的数据和function

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

  • function

一个对象可以保存内部的信息,使其能够为您提供有用的function。 例如,一个post对象可以足够聪明地返回前一个或下一个post。 一个arrays永远无法为你做。

  • 灵活性

上面提到的所有对象的好处有助于创build一个更灵活的系统。

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

可能有两个原因:

  • WordPress是相当古老的
  • 在大多数情况下,数组速度更快,占用内存更less
  • 更容易序列化

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

不,但有很多其他原因,例如:

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

OOP != AOP 🙂

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

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

一个对象(即使只是一个stdClass的实例)是一件事的表示。 在WordPress可能是一个职位,评论或用户。 另一方面,数组是事物的集合。 (例如,post列表)

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

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

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

关联数组的语法糖Zeev Suraski 关于 PHP 3以来的标准对象

  • stdClass对象并不比数组好。 他们几乎是一样的。 这是由于语言的一些历史原因,以及stdClass对象是非常有限的,实际上只是一种非常基本的价值对象 。
  • stdClass对象存储其成员的值,如每个条目的数组。 就是这样。
  • 只有PHP的怪胎能够创build具有私人成员的stdClass对象。 没有太多的好处 – 如果有的话 – 这样做。
  • stdClass对象没有任何方法/函数。 所以没有在WordPress的使用。
  • array相比,处理列表或半结构化数据的function要less得多。

但是,如果您习惯于数组,只需施放:

 $array = (array) $object; 

你可以访问以前作为一个对象的数据,作为一个数组。 或者你反过来喜欢它:

 $object = (object) $array; 

哪些只会删除无效的成员名称,如数字。 所以要小心一点。 但是我认为你可以看到大概的情况:只要是关于stdClass数组和对象,没有太大的区别。

有关:

  • 转换为对象PHP手册
  • 保留的类PHP手册
  • 什么是PHP中的stdClass?
  1. 代码看起来比较酷
  2. 对象通过引用传递
  3. 对象更强types然后数组,因此可以看错误(或当您尝试使用不存在的成员给你一个有意义的错误消息)
  4. 今天所有的IDE都具有自动完成function,因此在使用定义的对象时,IDE会为你做很多事情,并加快速度
  5. 轻松地将逻辑数据封装在同一个盒子里,其中包含数组,将数据存储在数组中,然后使用一组不同的函数来处理它。
  6. inheritance,如果你将有一个类似的数组,几乎不相似的function,你将不得不复制更多的代码,然后如果你要做的对象

也许有更多的原因,我想过

对象比数组强大得多。 每个对象作为一个类的实例可以有附加的function。 如果你有需要处理的数据,那么你需要一个处理的函数。 对于数组,您将不得不在数组上调用该函数,因此将自己的逻辑关联到数据。 有一个对象,这个关联已经完成了,你不必再关心它了。

你也应该考虑信息隐藏的OO原则。 并非所有从数据库返回的数据都可以直接访问。

返回对象有几个原因:

  1. 编写$myObject->property需要比$myArray['element']更less的“开销”字符

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

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

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

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

  1. array _ *()函数族提供的function可以减less某些情况下所需的编码量。

  2. 诸如count()和foreach()之类的操作可以在数组上执行。 对象不提供这个(除非他们实现迭代器或可数 )。

这通常不会是因为性能的原因。 通常,对象比数组花费更多。

对于很多API来说,除了作为存储机制之外,它可能与提供其他function的对象有关。 否则,这是一个偏好问题,返回一个对象与数组真的没有任何好处。

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

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

有时你直接访问一个对象variables,这通常是皱眉,但它经常发生。

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

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

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

这是一个非常简单的例子,但是你可以看到这是怎么回事。 一个类提供了一个variables的集合,以及可以在一个独立的逻辑实体中操作这些variables的函数。 该实体的一个实例被称为对象,它引入了一个数组根本不具有的逻辑和dynamic结果。

大多数情况下,对象的速度与数组速度一样快,但在PHP中并没有明显的差别。 主要原因是对象比数组更强大。 面向对象的编程允许你创build对象,不仅存储数据,而且存储数据,例如在PHP中,MySQLi类可以让你拥有一个数据库对象,你可以使用大量的内置函数来处理数据库对象,而不是使用程序方法。

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

作为一个小的加号,你也可以inputless来获取对象的数据 – $ test-> data比$ test ['data']要好。

我不熟悉文字新闻。 这里有很多答案表明,对象的强度是有能力包含function代码。 当从一个函数/ API调用返回一个对象时,它不应该包含实用函数。 只是属性。

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

示例:您将获得一组具有键/值对的数据,该键表示DB列。 如果数据库列被重命名,您的代码将会中断。

即时通讯运行下一个testing在PHP 5.3.10(窗口):

 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个并发用户的function和10次(为了获得一个平均值)

  • 数组:100%
  • 对象:214% – 216%(慢2倍)。

AKA,Object还是很痛苦的慢。 OOP保持整洁,但应小心使用。

什么WordPress的应用? 那么,这两个解决scheme,是使用对象,数组和对象和数组,类wpdb使用后来(这是Wordpress的核心)。

它遵循OOP的装箱和拆箱原则。 虽然像Java和C#这样的语言本身就支持这个,但是PHP不支持。 但是,在某种程度上,PHP可以完成,因为这种语言本身并不具有支持它的构造。 在PHP中使用boxtypes可以帮助链接,保持所有的面向对象,并允许在方法签名中键入提示。 缺点是开销太大,而且现在您还有额外的检查来使用“实例”构造。 当使用具有智能感知或代码辅助(如PDT)的开发工具时,使用types系统也是一个优点。 这个方法不是必须google / bing / yahoo,而是存在于这个对象上,你可以使用这个工具来提供一个下拉菜单。

虽然关于对象不仅仅是数据的观点是有效的,因为它们通常是数据和行为,但Martin Fowler的“企业应用程序体系结构模式”中提到的至less有一种模式适用于您正在传输的这种types的数据库来自一个系统(API背后的应用程序)和另一个系统(您的应用程序)的数据。

它的数据传输对象 – 在进程之间传输数据的对象,以减less方法调用的数量。

所以如果问题是API是否应该返回一个DTO或一个数组,我会说,如果性能成本是微不足道的,那么你应该select更可维护的选项,我认为是DTO选项…但当然,你也必须考虑正在开发系统的团队的技能和文化以及每种选项的语言或IDE支持。