【问题标题】:Java-like Collections in PHPPHP 中的类 Java 集合
【发布时间】:2010-12-07 12:05:45
【问题描述】:

我正在学习 PHP5(上次我检查 PHP 是在 PHP4 天),我很高兴看到 PHP5 OO 比 PHP4 更类似于 Java,但仍然有一个问题让我感到很不舒服,因为我的 Java 背景:数组。

我正在阅读“Proffesional PHP6”(Wrox),它展示了它自己的 Collection 实现。 我发现了其他类,例如基于 SPL 的 http://aheimlich.dreamhosters.com/generic-collections/Collection.phps 中的类。 我还发现 SPL (ArrayObject) 中有某种 Collection

但是,我很惊讶,因为我并没有真正看到人们在 PHP 中使用集合,他们似乎更喜欢数组。

那么,在 PHP 中使用集合不是一个好主意,就像人们在 Java 中使用 ArrayList 而不是基本数组一样?毕竟,php 数组并不像 java 数组。

【问题讨论】:

  • 您能指出 Java 集合相对于 PHP 数组的优势吗?除了看起来很有企业精神?
  • 实际上,如果在 PHP 中有一个集合实现会很好,但类似于 Python 的集合。
  • 我在下面的回答中提供了一个非常简单的实现。

标签: java php collections language-comparisons


【解决方案1】:

Java 中的集合很有意义,因为它是一种强类型语言。有一个集合说“汽车”和另一个“摩托车”是有意义的。

然而,在 PHP 中,由于动态类型的特性,牺牲集合的形式是很常见的。数组足以用作各种对象类型(汽车、摩托车等)的通用容器。此外,额外的好处来自于数组可以很容易地改变这一事实(如果没有适当的错误检查,这有时可能是一个很大的缺点)。

我来自 Java 背景,我发现在 PHP 中使用集合设计模式并没有带来太多好处(没有多线程、没有优化内存分配、没有迭代器等) .

如果您正在寻找这些优势中的任何一个,最好围绕数组构建一个包装类,实现每个功能(迭代器等)点菜。

【讨论】:

  • 构建我自己的包装类的缺点是使用非标准类来完成这样一个基本的事情。 SPL 的 ArrayObject 是包装器吗?
  • 同意,任何自定义包装器都有非标准的缺点,但这可能不是那么糟糕,因为确实没有标准的 Collections 包装器。我还没有真正使用过 SPL 的 ArrayObject,但查看文档 (php.net/~helly/php/ext/spl/classArrayObject.html),它似乎是一个添加克隆函数和迭代器的包装类。如果这就是您所需要的,我建议您使用它。但如果您需要同步、linkedlist 与 arraylist 等,您可能需要编写自己的包装器或扩展 ArrayObject。
  • 完全同意,但有时您只想基本保证数组只包含一种类型的对象。我有一个我使用的简单实现 - 请参阅下面的答案
【解决方案2】:

PHP 数组是关联数组...它们比 Java 的数组强大得多,并且包含 List 和 Map 的大部分功能。

“好主意”是什么意思?它们是不同的工具,以您使用另一种语言的方式使用一种语言通常会导致挫败感。

【讨论】:

  • PHP 中使用了很多 OO 设计模式,而且 PHP5 OO 与 Java 非常相似,所以使用某种 Collection 对我来说似乎是个好主意。
  • PHP 借鉴了 Java 的一些东西未必是好事。
  • 我想我很困惑。你确实有“收藏”。它们只是没有命名为“列表”或“地图”。 PHP 数组将动态增长。您可以关联键/值对。套装是一个有点不同的野兽,但是,嘿,不能在那里堆得太多。 :) 来自 Java 肯定是一个奇怪的世界,但要接受这些差异和随之而来的权衡!
【解决方案3】:

我也有点沮丧地发现 PHP 中没有 Collection 类型的类。根据我的经验,数组有几个真正的缺点。

首先,可用于操作它们的函数数量有限。例如,我需要能够在给定索引位置向集合中任意插入和删除项目。使用 PHP 中数组的内置语言函数来做到这一点充其量是痛苦的。

其次,作为第一点的一种分支,编写干净、可读的代码来处理任何复杂程度的数组,而不是简单的推送/弹出和迭代器的东西,充其量是困难的。我经常发现我必须使用一个数组来索引和跟踪我创建的数据密集型应用程序中的另一个数组。

我更喜欢在框架中工作(我个人的选择是NOLOH)。在那里,我有一个名为 ArrayList 的真正 Collection 类,它具有 Add、Insert、RemoveAt、RemoveRange 和 Toggle 等功能。我想其他 PHP 框架也可以解决这个问题。

【讨论】:

    【解决方案4】:

    我是 PHP 中非常专业的集合对象,它们可用于添加类型安全性,实现易于使用的搜索、排序和操作功能,并代表正确的 OO 方法,而不是使用数组和大量有用但程序化的函数在整个源中以不同的模式对它们进行操作。

    我们有各种集合用于各种目的,所有这些集合都被巧妙地继承,以促进类型安全、一致的编码标准和高水平的代码重用。

    但归根结底,它们都是数组内部的!

    我想这真的归结为选择,但在我面向对象的世界中,我喜欢在基类中保留易于重复的代码段,例如排序和搜索算法,而且我发现对象表示法更能自我记录。

    【讨论】:

      【解决方案5】:

      Varien Lib 提供了一个很好的 php 集合实现,该库是具有 OSL 许可证的 Magento 代码的一部分。 (有关 Magento 许可证和代码重用的更多信息here

      找不到该库的任何源代码,因此最好的方法是下载 magento,然后查看 /lib/Varien/

      【讨论】:

        【解决方案6】:

        Yii 实现了完整的 java 类集合堆栈

        http://www.yiiframework.com/doc/api/1.1/CList

        【讨论】:

          【解决方案7】:

          我有时会使用这个非常简单的实现来给我一个粗略的现成集合。

          通常,集合的主要要求是强制一组一种类型的对象,您只需要设置一个带有构造函数的基本类来实现它。

          class SomeObjectCollection {
          
             /**
              * @var SomeObject[]
              */
             private $collection = array();
          
             /** 
              * @param SomeObject $object1
              * @param SomeObject $_ [optional]
              */
             function __construct(SomeObject $object1 = null, SomeObject $_ = null) 
             {
                 foreach (func_get_args() as $index => $arg) {
                     if(! $arg instanceof SomeObject) throw new \RuntimeException('All arguments must be of type SomeObject');
                     $this->collection[] = $arg;
                 }
             }
          
             /**
              * @return SomeObject[]
              */
             public function getAll()
             {
                 return $this->collection;
             }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-07-26
            • 1970-01-01
            • 1970-01-01
            • 2010-10-08
            • 1970-01-01
            • 1970-01-01
            • 2010-10-22
            相关资源
            最近更新 更多