Collections

486 views
Skip to first unread message

Matthieu Napoli

unread,
Apr 26, 2013, 6:01:26 AM4/26/13
to php...@googlegroups.com
Hi everyone,

Following a discussion on Github, I am bringing the subject to the ML: proposing a standard for Collections.

Please note I am not a PHP-FIG member.

Why?

There is no Collection object or interface in PHP. Today, some libraries or frameworks make use of such a concept instead of a PHP array, for several reasons.

The main example I have worked with is Doctrine, which introduces a Collection interface and several implementations. Quoting from the docs:

plain PHP arrays can not be transparently extended / instrumented in PHP code, which is necessary for a lot of advanced ORM features.

The Doctrine collection provides useful features in a OO way (like map, filter, forAll with closures), so that is useful for the user. But mainly, Doctrine proposes 2 implementations of the collection: a "simple" ArrayCollection, and a "PersistentCollection" that allows lazy loading, Criteria filtering directly using DB queries, etc. Thinks that would be difficult to implement with PHP arrays.

I have not worked with Propel, but it seems there is a similar object: PropelCollection. I am sure I am missing other frameworks/libraries with a Collection interface, so feel free to complete the list of usages.

So the idea would be to enable users or frameworks to make use of such objects without tying themselves to a particular implementation (by implementation I mean "implementation of a Collection interface", yeah bad choice of words).

How?

Before jumping into code, that would be interesting to properly understand all possible uses of such objects (so please speak if you use/propose collections in your libraries).

There is also the question of "what is a collection?"

I find interesting looking at what Java offers (only top interfaces):
  • Collection: A group of objects. No assumptions are made about the order of the collection (if any) or whether it can contain duplicate elements.
    • List: Extends Collection. Ordered collection
    • Set: Extends Collection. No duplicate elements permitted. May or may not be ordered.
    • Queue: Extends Collection.
  • Map: A mapping from keys to values. Each key can map to one value.
As we can see, there is not "just" a Collection interface, because Map doesn't extend it. And that's understandable when you see how methods differ.

In PHP, arrays can behave as Collection or as Map. That's mostly thanks to the array notation that makes that practical:
  • $array[] = 'value';
  • $array['key'] = 'value';
But is that possible to do it properly with objects?

So the question is: should a PHP Collection behave as a Collection and as a Map, or should behaviors be separated?

Put in other words: should the PSR provide a Collection interface, or a Collection and a Map interface?


There are a lot of things to be discussed, but in order to not come empty handed, I have put together a gist inspired by Doctrine collections and Java Collection/Map: https://gist.github.com/mnapoli/5466043
This gist can be discussed, forked, edited or also thrown away if useless.

Alexandre Gaigalas

unread,
Apr 26, 2013, 6:52:55 AM4/26/13
to php...@googlegroups.com
I've always understood the rationale behind custom collections but never found out any good way of making them feel really native. OOP-wise everything seems fine but really useful functions like array_map or array_merge_recursive don't work. That's the main difference between arrays and ArrayObject-like structures and it's huge, 'cause we can always getArrayCopy() to go native but then performance gets a major hit.

Another difference is that ArrayObjects have their object hashes and standard arrays don't, making ArrayObjects easier to work with algorithms that need object references instead of copying between scopes.

Since Java was mentioned as an example, perhaps libraries like underscore.js could be considered as well for this. The purpouse is the same (make easy to play with sets and data structures), but in another paradigm (functional programming, which PHP also supports).

Regarding the difference between Collection and Map and its practicabilityfor PHP, I'm really not sure. We know for example that SplFixedArray is faster than an usual array 'cause the engine ensures that, but a custom SplFixedArray written in PHP rather than C would probably be slower than a normal one. Mostly these different data structures are built for performance, not by their inherent interface limitations (for example, the recently added TypedArrays in JavaScript).

Also, speaking of SplFixedArray, how do we relate these custom collections with the SPL data structures?

--
Gaigalas


--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
To post to this group, send email to php...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/php-fig/-/BYSzYkxLwvQJ.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Matthieu Napoli

unread,
Apr 26, 2013, 7:00:56 AM4/26/13
to php...@googlegroups.com
I'm only answering the first part of your message: the subject is not about using Collections instead of arrays. There is a fact that some frameworks need to work with Collections instead of arrays. So let's bring interoperability to it.

Sebastian Krebs

unread,
Apr 26, 2013, 7:11:22 AM4/26/13
to php...@googlegroups.com



2013/4/26 Alexandre Gaigalas <alex...@gaigalas.net>

I've always understood the rationale behind custom collections but never found out any good way of making them feel really native. OOP-wise everything seems fine but really useful functions like array_map or array_merge_recursive don't work.

This functions aren't very OOP-like anyway ;) I think of Doctrine\Common\Collections: They implement (for example) "map()" as method.
 
That's the main difference between arrays and ArrayObject-like structures and it's huge, 'cause we can always getArrayCopy() to go native but then performance gets a major hit.

Another difference is that ArrayObjects have their object hashes and standard arrays don't, making ArrayObjects easier to work with algorithms that need object references instead of copying between scopes.

Since Java was mentioned as an example, perhaps libraries like underscore.js could be considered as well for this. The purpouse is the same (make easy to play with sets and data structures), but in another paradigm (functional programming, which PHP also supports).

Regarding the difference between Collection and Map and its practicabilityfor PHP, I'm really not sure. We know for example that SplFixedArray is faster than an usual array 'cause the engine ensures that, but a custom SplFixedArray written in PHP rather than C would probably be slower than a normal one. Mostly these different data structures are built for performance, not by their inherent interface limitations (for example, the recently added TypedArrays in JavaScript).

Also, speaking of SplFixedArray, how do we relate these custom collections with the SPL data structures?

Is this required?

Alexandre Gaigalas

unread,
Apr 26, 2013, 7:30:27 AM4/26/13
to php...@googlegroups.com
I was too prolix on that email =)

You're proposing a distinction between two strucures. On Java, they're distinct mostly for performance requirements. Doctrine implemented so it can have strong object references to an extensibe generic object. These are use cases for these structures, what is the use case for the interop distinction between a Map and a Collection?

Sebastian Krebs

unread,
Apr 26, 2013, 7:40:11 AM4/26/13
to php...@googlegroups.com



2013/4/26 Alexandre Gaigalas <alex...@gaigalas.net>
I was too prolix on that email =)

You're proposing a distinction between two strucures. On Java, they're distinct mostly for performance requirements. Doctrine implemented so it can have strong object references to an extensibe generic object. These are use cases for these structures, what is the use case for the interop distinction between a Map and a Collection?

Don't know, if you get me wrong (or I get you wrong ^^ or you mistook me for someone else ;)), but I was only talking about "array_map() vs $collection->map()/$map->map()". I don't propose anything :D But the OOP-approach (independent from any (doctrine-)implementation) allows to chain the calls more easily without creating a mess

array_filter(array_map($mapFct, $array), $filterFct);
// vs
$collection->map(mapFct)->filter($filterFct);

Alexandre Gaigalas

unread,
Apr 26, 2013, 8:14:45 AM4/26/13
to php...@googlegroups.com
I love chaining, but that's only syntax. Chains are good on top of architectures, not in their center. Just like the Mongo API:

//underlying architecture
$conn = new Mongo();
$db = new MongoDb($conn, 'foo');
$coll = new MongoCollection($db, 'bar');

//equivalent fluid-chained-builder-sugar
$conn = new Mongo();
$coll = $conn->foo->bar;

And just like underscore.js:

//I´m not proposing anything like this for fig, it´s only a sample!!!
_.chain(myArr).map(bysomething).filter(byfn).value();

We can't make a PHP interface enforce a fluent chain. There is no return type declaration for this so it's impossible by the interpreter. It's possible to enforce by convention though.

But that doesn't seem to be the reason to propose a distinction between Map and Collection, since the chain is equally useful in both these structures. Operations like 'map' are suitable for arrays, dictionaries, maps, collections, lists, etc... their interfaces are highly polymorphic and I still don't see how separating Map and Collection would improve interoperability instead of making it harder.

Sebastian Krebs

unread,
Apr 26, 2013, 8:54:22 AM4/26/13
to php...@googlegroups.com



2013/4/26 Alexandre Gaigalas <alex...@gaigalas.net>
I love chaining, but that's only syntax.

Definitely and I hope it doesn't sound like I think _thats_ the killer feature. It's just: It feels more natural to apply a mapping function _on_ a collection ($a = $c->map($f)), than passing both separately to a function ($a = array_map($c, $f)). Thats all :)

Matthieu Napoli

unread,
Apr 26, 2013, 9:28:37 AM4/26/13
to php...@googlegroups.com
I still don't see how separating Map and Collection would improve interoperability instead of making it harder.

 I think one reason to separate Collection and Map is their methods.

As I said, with PHP arrays the difference between a Collection and a Map is very small:
  • Collection: $array[] = 'value'; $value = $array[];
  • Map: $array['key'] = 'value'; $value = $array['key'];
But with OOP, that's another problem. Look and those differences:
  • Collection
    • add($value)
    • contains($value)
    • remove($value)
  • Map
    • set($key, $value)
    • get($key)
    • contains($key)
    • remove($key)
These are the main features of a Collection and a Map, and they are really different (and not only in naming).

Alexandre Gaigalas

unread,
Apr 26, 2013, 9:46:51 AM4/26/13
to php...@googlegroups.com
They're different, but the underlying code will eventually deal with raw arrays or ArrayObjects. We can put every ->set, ->get, ->contains, ->remove, ->map, ->reduceLeft, etc and it will always point to an underlying object that supports that action. It could be even a $keys->combine($values); that fuses two numeric arrays into an associative one, making it really flexible (although this is just a brainstorm, I´m not proposing any of this, just trying to understand what is your specific need).

In Java, Python and languages that have multiple native set data structures it makes sense to not create a flexible object, because you can leverage the performance improvements of each data structure. It's designed for efficiency, the limitations on the interface aren't pleasant, they're just side effects. Off course you can rely on the limitations of a data structure to define semantics, and that is something nice, but I couldn't think of a sample usage (a single one would make a strong point for separate Map and Collection).

In PHP we have a couple of alternative native data structures like SplObjectStorage, SplDoublyLinkedList, SplFixedArray and so on that are interpreter-based and faster. It would make a lot of sense to make a interoperable/chainable/improved pattern on top of those, but making yet another one on top of the same ArrayObject doesn´t appeal me, unless I'm not seeing some issue with having an uniform performant flexible single object.


--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
To post to this group, send email to php...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/php-fig/-/TVwU6Y1W1hYJ.

Sebastian Krebs

unread,
Apr 26, 2013, 10:13:46 AM4/26/13
to php...@googlegroups.com



2013/4/26 Matthieu Napoli <matt...@mnapoli.fr>

I still don't see how separating Map and Collection would improve interoperability instead of making it harder.

 I think one reason to separate Collection and Map is their methods.

As I said, with PHP arrays the difference between a Collection and a Map is very small:
  • Collection: $array[] = 'value'; $value = $array[];
Well, in fact it is "$array[]" only for appending, but (see "lists") usually it is more like $array[1]

 
  • Map: $array['key'] = 'value'; $value = $array['key'];
But with OOP, that's another problem. Look and those differences:
  • Collection
    • add($value)
    • contains($value)
Works with Maps too (see below)
 
    • remove($value)

Works with maps too too ;)
 
  • Map
    • set($key, $value)

List::set($index, $value); 
 
    • get($key)
List::get($index);
 
    • contains($key)

contains() should test the value anyway and then its identical to Collection::contains($value). In this case it would be more a "hasKey($key)".
 
    • remove($key)

List::remove($index);


That I used "List" here was intentionally, because this doesn't work really well for Sets.

 
These are the main features of a Collection and a Map, and they are really different (and not only in naming). 

Well, not as different as it looks like: A map is a collection with the ability to reference theire content with a special item (the key). At the end thats all:
- Because this "reference" is required the add() method must fail
- There are additional methods for key handling.
- A map is unordered (but for example a Set is unordered too)

This makes me think, that "Map extends Collection" makes sense. The other Collection-implementations must take care about the validity of the keys themself anyway.

 


 

--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
To post to this group, send email to php...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/php-fig/-/TVwU6Y1W1hYJ.

For more options, visit https://groups.google.com/groups/opt_out.
 
 

Alexandre Gaigalas

unread,
Apr 26, 2013, 10:57:49 AM4/26/13
to php...@googlegroups.com
A Map can always be used as a Collection, you just need to ignore the keys. Actually, the keys are always there in PHP, there are always keys, even in SplObjectStorage.

Architecturally, "Map extends Collection" doesn't make sense, 'cause Collection is already a restriction on top of PHP's own behavior and Map is a rollback of these restrictions. The only way to have an unordered ArrayAccess-like thing in PHP is to ignore its order somehow, which is hard.

If PHP had only a numeric-based structure then it would make sense that the next "layer" on top of it would implement associative features, but since the key/value is pretty much tied to everything in PHP from iterators to generators and everything traversable it will be pretty hard to "hide" these keys, and even if possible it would be something of questionable use.

Keys are also always acessible by interface. You can't override key() to be private while implementing ArrayAccess or any of it's derivates.

Matthieu Napoli

unread,
Apr 26, 2013, 11:34:48 AM4/26/13
to php...@googlegroups.com
I see what you both mean. I'd love to hear more use cases to see if a "do-it-all" map-collection could cover everything.

I've updated https://gist.github.com/mnapoli/5466043 to show example interfaces for both possible solutions.

For "add()", should it be removed (since a map needs a key) or should the PHP behavior be reproduced: i.e. append after the last numeric index.

Levi Morrison

unread,
Apr 26, 2013, 12:20:56 PM4/26/13
to php...@googlegroups.com
Hello, everyone. This is my first post to this group and have never participated in FIG before. My interest is piqued because I have been trying to write a good data-structures library for PHP for several years now. The project is here (https://github.com/morrisonlevi/Ardent) if you are interested in seeing what I have.

My real purpose in replying isn't to promote my own library; rather it is to tell you that you are thinking too narrowly. You don't need to have universal add and remove methods for every kind of collection. In fact, I would even venture to say that going down that road would be harmful and counterproductive.

My main point: the real usefulness of a collection is that you work with items as a group. This means that you are interested in having methods like filter, map, reduce and join -- not the details of how to add or remove a specific item to a collection.

Alexandre Gaigalas

unread,
Apr 26, 2013, 2:18:55 PM4/26/13
to php...@googlegroups.com
Hi Levi!

I've also wrote a prototype library to work with groups of data: https://github.com/Respect/Conversion, there are many ways to approach this issue, I've chosen objects as operations to delay state and not fixed structures to define state, but the goal is the same.

Indeed aggregate/group methods are useful. Anyway, "filter", "map", "reduce" and similar ones also work on many set data structures the same way as simpler methos like "hasKey". We have array_walk, array_map, array_walk_recursive, array_combine, array_filter and so on. They work on any array (which is flexible enough to cover use cases for Map, Collection, Tuple, Array, Dictionary and so on) and making these functions type-specific in PHP is actually harder than making them generic (well, PHP is a juggling type language).

Anyway, I believe we should focus on the interoperability advantages of separating the interface definition of the data structures. Actually, not the separation (because in PHP there is no such separation) but the limitation of PHP structures.

TL;DR how does limiting something generic by nature in PHP makes it more interoperable?




--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
To post to this group, send email to php...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/php-fig/-/SrZnsUKBFnAJ.

Larry Garfield

unread,
Apr 26, 2013, 2:40:17 PM4/26/13
to php...@googlegroups.com
Welcome aboard!

I have an even deeper question for this thread: Given PHP supports native collections (just mislabeled as arrays), and for cases where you want object passing semantics we have ArrayAccess, iterators, and over a half dozen C-level object structures in SPL already, what is the use case for adding a user space collection interface as well? I'm unclear on what genetic interface here would be useful for interoperability but not simply be duplicating existing baked in PHP functionality. Please enlighten.

--Larry Garfield

Bernhard Schussek

unread,
Apr 26, 2013, 9:32:02 PM4/26/13
to php...@googlegroups.com
Hi Larry,

I think a Collection interface that just extends \ArrayAccess, \Traversable and \Countable would already make sense. Currently, if I want to type-hint against these features (="array-like object"), I need to build my own interface.

Methods like filter() and map() on top of that are obviously a plus.

Bernhard

--


2013/4/26 Larry Garfield <la...@garfieldtech.com>

Larry Garfield

unread,
Apr 27, 2013, 1:07:35 AM4/27/13
to php...@googlegroups.com
How would that help interoperability? And why not just hint on the one of those you care about?

There is a piece missing here that is not connecting.

Bernhard Schussek

unread,
Apr 27, 2013, 5:38:32 AM4/27/13
to php...@googlegroups.com
You can't hint on multiple interfaces. Especially traversal and array access are frequently needed at the same time.

Bernhard

--
Bernhard Schussek
Blog: http://webmozarts.com
Twitter: http://twitter.com/webmozart


2013/4/27 Larry Garfield <la...@garfieldtech.com>

Alexandre Gaigalas

unread,
Apr 27, 2013, 6:32:49 AM4/27/13
to php...@googlegroups.com
You don't need to hint on that specific granularity (specially in a language that has type juggling). When you want a "month" you would probably hint for the superset, a DateTime. Why not hint for "array" or "ArrayObject"?

Unfortunately, PHP has some gotchas. A primitive array is not instance of Traversable and there is no common single interface for most array-like objects. There is no way to avoid this, it's mostly in the core of the language (since primitives and classes are two different typing systems in PHP) and there is no way for fig to "fix this".

Why would someone need an object that absolutely cannot be Traversable while still must have ArrayAccess? (that's not rethorical!).You can just ignore the Travesibleness or ArrayAccessness of the object and use the interface you want, just like sometimes I only use the month of a DateTime object and still want the goodies from having it encapsulated.

Sebastian Krebs

unread,
Apr 27, 2013, 9:36:26 AM4/27/13
to php...@googlegroups.com



2013/4/27 Alexandre Gaigalas <alex...@gaigalas.net>

You don't need to hint on that specific granularity (specially in a language that has type juggling). When you want a "month" you would probably hint for the superset, a DateTime. Why not hint for "array" or "ArrayObject"?

Well, a month is (at the very minimum) an integer between 1 and 12 (or 0 and 11 ;)). This makes this example quite useless, doesn't?

On the other hand an interface is a crontract for the implementing classes and a type hint is a contract about the given parameter. It definitely makes sense to limit the allowed types of an parameter to the most restrictive interface instead of "an array-ish thing with something arbitrary inside". This "arbitrary stuff inside" includes, that you always have to take care, that it _really_ contains values (and maybe keys) of the correct type.
 

Unfortunately, PHP has some gotchas. A primitive array is not instance of Traversable and there is no common single interface for most array-like objects. There is no way to avoid this, it's mostly in the core of the language (since primitives and classes are two different typing systems in PHP) and there is no way for fig to "fix this".

Why would someone need an object that absolutely cannot be Traversable while still must have ArrayAccess? (that's not rethorical!).

The question is wrong. It should be: Why _should_ everything collection-like class be traversable? As long as the type doesn't need it, it shouldn't implement it ("less code" and such).

Strictly spoken (and a little bit academic): Maps and sets are by definition _not_ traversable because they are unordered and you need an order to iterate over something. When you iterate over a set, or an map you iterate over (a list of) the values, but not over the map/set itself :) 

Comment: The behaviour for "iterating over arrays" (The "real" ones, not the PHP-style array-ish maps) includes, that it iterates over every "unset" value too. Again something you can avoid with a list-type class, so your application doesn't need to check against it later (ok, this argument is not really valid for PHP :D)
 
You can just ignore the Travesibleness or ArrayAccessness of the object and use the interface you want, just like sometimes I only use the month of a DateTime object and still want the goodies from having it encapsulated.

As mentioned above: If you want to have a month, why don't you use integer? :) Encapsulation doesn't necessarily makes sense, especially because you must take into account, that DateTime has a timezone associated with it, which may or may not result in an unexpected value.
(Just saying. Maybe I would use DateTime too :) It depends)

Benjamin Eberlei

unread,
Apr 27, 2013, 12:26:25 PM4/27/13
to php...@googlegroups.com
This doesn't make sense to standardize datastructures imho, they should be optimized for their use case, not follow some arbitrary API.

For Doctrine we are not sure if we want to heavily break BC in the next eversion of collectoins, when we might introduce Lists, Sets and/or maybe even think about immutabliity of collections.

Matthieu Napoli

unread,
Apr 29, 2013, 2:47:37 AM4/29/13
to php...@googlegroups.com
Like it has been said, maybe starting with an interface extending \ArrayAccess, \Traversable and \Countable could be a good thing. Being able to type-hint against all that means you already have a good way to use the Collection.


This doesn't make sense to standardize datastructures imho, they should be optimized for their use case
 
The implementation should be optimized for the use case. That's how it works in Java for example: you use a generic interface, and then you choose which implementation to use (i.e. which data structure) based on your use case.

not follow some arbitrary API.

Instead follow the arbitrary API of a library?
 

For Doctrine we are not sure if we want to heavily break BC in the next eversion of collectoins, when we might introduce Lists, Sets and/or maybe even think about immutabliity of collections.

If we can have List and Set extends from the Collection interface, then that's good. It will be at least usable by any framework that choose to be PSR-X compliant. And when me, the user, doesn't care about the added value of a more specialized interface/implementation, I'll use Collection so that I keep my code decoupled from Doctrine.

Sebastian Krebs

unread,
Apr 29, 2013, 6:43:18 AM4/29/13
to php...@googlegroups.com



2013/4/27 Benjamin Eberlei <kon...@beberlei.de>

This doesn't make sense to standardize datastructures imho, they should be optimized for their use case, not follow some arbitrary API.

Something like "Queue", or "Stack" is already the use-case isn't it?
 

For Doctrine we are not sure if we want to heavily break BC in the next eversion of collectoins, when we might introduce Lists, Sets and/or maybe even think about immutabliity of collections.

Yes, I fear the impact on existing libraries would be a bigger one...

Phil Sturgeon

unread,
May 2, 2013, 11:06:40 AM5/2/13
to php...@googlegroups.com

How would that help interoperability? And why not just hint on the one of those you care about?

There is a piece missing here that is not connecting.
 
I can absolutely see what these guys are talking about. Take a look at the Laravel 4 Collection class:


This is required by many of its packages, such as Translator, and Eloquent (which extends it to add its own ORM specific features, like Doctrine could probably do too). By expecting a collection I KNOW I can use $foo->sort() (which will uasort it without having to convert it to an array and then back to a collection), filter, map, etc.

It's pretty much doing all the things you'd really like PHP arrays to do if you were coming from a Python/JS/Ruby background. While we aren't here to replicate potential language features, I feel like a Collection is a specific-enough goal that enough packages and projects use to warrant investigation for a PSR.

I'd suggest the L4 collection is a great example, and would like to see folks post other examples of similar Collection code so we can work out a shared structure.

Dries Vints

unread,
Apr 21, 2015, 8:19:59 AM4/21/15
to php...@googlegroups.com
I'd like to bump this thread because I believe (a) common interface(s) would greatly benefit developers. It's often that frameworks/libraries have their own implementation for collections and using them together in your code base can be quite awkward from time to time. Having a common interface to typehint against would solve a lot of problems and will lead to much cleaner code I believe.

Basically the fact that you could use a single interface in your codebase and easily swap out different framework/library implementations should be enough reason to start a PSR for this.

Any thoughts?

Christopher Pitt

unread,
Apr 21, 2015, 3:22:19 PM4/21/15
to php...@googlegroups.com
I think this would be awesome. Any way I can help...

Kayla Daniels

unread,
Apr 22, 2015, 10:12:54 AM4/22/15
to php...@googlegroups.com
I'm a huge fan of this. Collections are super useful and having a PSR that allows them to be exchangeable would be fabulous. 

Dries Vints

unread,
Apr 22, 2015, 10:17:45 AM4/22/15
to php...@googlegroups.com
Kayla, Chris: I think we should continue from Levi's project: https://github.com/morrisonlevi/Ardent
Looks like most of the hard work has already been done here and it'll be a good base to start from.

Unfortunately I don't have time myself to work on this so it'd be great if someone could step up to take charge of this proposal.

Joe Ferguson

unread,
Apr 22, 2015, 10:19:01 AM4/22/15
to php...@googlegroups.com
Hello All,

Long time lurker, first time poster. I think this would be awesome. Would make jumping between frameworks easier.

-- 
- Joe Ferguson
MemphisTechnology.org
MemphisPHP.org
HACKMemphis.com


On Tue, Apr 21, 2015 at 2:22 PM, Christopher Pitt <cgp...@gmail.com> wrote:

I think this would be awesome. Any way I can help...

--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
To post to this group, send email to php...@googlegroups.com.

Marco Pivetta

unread,
Apr 22, 2015, 6:18:46 PM4/22/15
to php...@googlegroups.com
I've been pushing for Levi's library for a while: would love to get rid of doctrine/collections in favor of his awesome research work :-)

Levi Morrison

unread,
Apr 23, 2015, 10:24:42 PM4/23/15
to php...@googlegroups.com
Author of Ardent here. I'd love to collaborate on this. What would be really helpful to me is if two or three major framework contributors would do a few things:
  • Post a link to their Collections type
  • Talk about what parts of it they like
  • Talk about which parts are painful
  • Which parts they feel like they could drop (functionally that is there that they can do without, either by removing it altogether or moving it somewhere else)
This would be really helpful information and a good start to gathering requirements.

Alexander Makarov

unread,
Apr 24, 2015, 4:30:00 AM4/24/15
to php...@googlegroups.com
We had collections in Yii 1.1 (https://github.com/yiisoft/yii/tree/master/framework/collections) but removed them in favor of SPL and arrays in 2.0.

Painful part with 1.1 collections was the fact that these were significantly slower and memory hungry than SPL and arrays. It was hard to live w/o them when PHP was 5.1 but with 5.3—5.4 SPL was a better choice.

Taylor Otwell

unread,
Apr 24, 2015, 9:01:03 AM4/24/15
to php...@googlegroups.com
Not a huge fan of this.

Collections / arrays are *already* inter-changable without any libraries having to change their code at all. One library can simply pass the raw array underlying their collection to another library, which can then change the array back to a Collection object of its own choosing. Typically, the cost of moving from array to Collection and back again is negligible.

On Friday, April 26, 2013 at 5:01:26 AM UTC-5, Matthieu Napoli wrote:
Hi everyone,

Following a discussion on Github, I am bringing the subject to the ML: proposing a standard for Collections.

Please note I am not a PHP-FIG member.

Why?

There is no Collection object or interface in PHP. Today, some libraries or frameworks make use of such a concept instead of a PHP array, for several reasons.

The main example I have worked with is Doctrine, which introduces a Collection interface and several implementations. Quoting from the docs:

plain PHP arrays can not be transparently extended / instrumented in PHP code, which is necessary for a lot of advanced ORM features.

The Doctrine collection provides useful features in a OO way (like map, filter, forAll with closures), so that is useful for the user. But mainly, Doctrine proposes 2 implementations of the collection: a "simple" ArrayCollection, and a "PersistentCollection" that allows lazy loading, Criteria filtering directly using DB queries, etc. Thinks that would be difficult to implement with PHP arrays.

I have not worked with Propel, but it seems there is a similar object: PropelCollection. I am sure I am missing other frameworks/libraries with a Collection interface, so feel free to complete the list of usages.

So the idea would be to enable users or frameworks to make use of such objects without tying themselves to a particular implementation (by implementation I mean "implementation of a Collection interface", yeah bad choice of words).

How?

Before jumping into code, that would be interesting to properly understand all possible uses of such objects (so please speak if you use/propose collections in your libraries).

There is also the question of "what is a collection?"

I find interesting looking at what Java offers (only top interfaces):
  • Collection: A group of objects. No assumptions are made about the order of the collection (if any) or whether it can contain duplicate elements.
    • List: Extends Collection. Ordered collection
    • Set: Extends Collection. No duplicate elements permitted. May or may not be ordered.
    • Queue: Extends Collection.
  • Map: A mapping from keys to values. Each key can map to one value.
As we can see, there is not "just" a Collection interface, because Map doesn't extend it. And that's understandable when you see how methods differ.

In PHP, arrays can behave as Collection or as Map. That's mostly thanks to the array notation that makes that practical:
  • $array[] = 'value';
  • $array['key'] = 'value';
But is that possible to do it properly with objects?

So the question is: should a PHP Collection behave as a Collection and as a Map, or should behaviors be separated?

Put in other words: should the PSR provide a Collection interface, or a Collection and a Map interface?


There are a lot of things to be discussed, but in order to not come empty handed, I have put together a gist inspired by Doctrine collections and Java Collection/Map: https://gist.github.com/mnapoli/5466043
This gist can be discussed, forked, edited or also thrown away if useless.

Josh Lockhart

unread,
Apr 24, 2015, 9:10:05 AM4/24/15
to php...@googlegroups.com
I agree with Taylor. If you depend on a collection, you can depend on an array. Accept an array and convert it to your own collection internally. I see a collection more as a helpful implementation detail.

Woody Gilk

unread,
Apr 24, 2015, 9:21:52 AM4/24/15
to php...@googlegroups.com
I think we need a strong definition of what a Collection library does before we talk about it extensively. Ardent doesn't look like a Collections tool to me, it looks like a validation package.

Larry Garfield

unread,
Apr 24, 2015, 11:09:44 AM4/24/15
to php...@googlegroups.com
I agree here. I'm not entirely sure what we're discussing.

"Collection" in my mind means something that works like ArrayObject, or
other iterable. SPL has a pretty good set of those already. The big gap
in PHP now isn't the collection per se, it's the incompatibility between
arrays and iterators. :-) That's not something FIG is in a position to
address. However, there are libraries already out there that offer
traversable-or-array behavior.

I don't know what an abstracted interface for such libraries would look
like that wouldn't be dictating implementation... (I had the same
concern about PDO-extensions a while back.)

--Larry Garfield

On 4/24/15 8:21 AM, Woody Gilk wrote:
> I think we need a strong definition of what a Collection library does
> before we talk about it extensively. Ardent doesn't look like a
> Collections tool to me, it looks like a validation package.
>
> On Wednesday, April 22, 2015 at 5:18:46 PM UTC-5, Marco Pivetta wrote:
>
> I've been pushing for Levi's library for a while: would love to get
> rid of doctrine/collections in favor of his awesome research work :-)
>
> Marco Pivetta
>
> http://twitter.com/Ocramius
>
> http://ocramius.github.com/
>
> On 22 April 2015 at 15:18, Joe Ferguson <j...@joeferguson.me
> <javascript:>> wrote:
>
> Hello All,
>
> Long time lurker, first time poster. I think this would be
> awesome. Would make jumping between frameworks easier.
>
> --
> - Joe Ferguson
> MemphisTechnology.org
> MemphisPHP.org
> HACKMemphis.com
>
>
> On Tue, Apr 21, 2015 at 2:22 PM, Christopher Pitt
> <cgp...@gmail.com <javascript:>> wrote:
>
> I think this would be awesome. Any way I can help...
>
> --
> You received this message because you are subscribed to the
> Google Groups "PHP Framework Interoperability Group" group.
> To unsubscribe from this group and stop receiving emails
> from it, send an email to php-fig+u...@googlegroups.com
> <javascript:>.
> To post to this group, send email to php...@googlegroups.com
> <javascript:>.
> <https://groups.google.com/d/msgid/php-fig/c0a59769-b004-4939-a438-93025cf15fff%40googlegroups.com?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout
> <https://groups.google.com/d/optout>.
>
>
> --
> You received this message because you are subscribed to the
> Google Groups "PHP Framework Interoperability Group" group.
> To unsubscribe from this group and stop receiving emails from
> it, send an email to php-fig+u...@googlegroups.com <javascript:>.
> To post to this group, send email to php...@googlegroups.com
> <javascript:>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/php-fig/1429712337049.6b6c397a%40Nodemailer
> <https://groups.google.com/d/msgid/php-fig/1429712337049.6b6c397a%40Nodemailer?utm_medium=email&utm_source=footer>.
>
> For more options, visit https://groups.google.com/d/optout
> <https://groups.google.com/d/optout>.
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "PHP Framework Interoperability Group" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to php-fig+u...@googlegroups.com
> <mailto:php-fig+u...@googlegroups.com>.
> To post to this group, send email to php...@googlegroups.com
> <mailto:php...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/php-fig/4dce2e75-dc2b-4068-bcbc-90d035411a62%40googlegroups.com
> <https://groups.google.com/d/msgid/php-fig/4dce2e75-dc2b-4068-bcbc-90d035411a62%40googlegroups.com?utm_medium=email&utm_source=footer>.

Levi Morrison

unread,
Apr 27, 2015, 3:14:04 PM4/27/15
to php...@googlegroups.com


On Friday, April 24, 2015 at 7:21:52 AM UTC-6, Woody Gilk wrote:
I think we need a strong definition of what a Collection library does before we talk about it extensively. Ardent doesn't look like a Collections tool to me, it looks like a validation package.

Ardent provides Map, Set, Stack, LinkedList, etc which are collections. You must be talking about Laravel's Ardent which picked this name despite me already having a repository with over 100 stars on it. Perhaps others have had this confusion as well, which is why I am bringing it up here. The previously linked and mentioned library is the former, not the latter.

I do agree that we should talk more about what a Collections library is and does; this is why I asked for links to existing collections in frameworks to see how they using this idea of a Collection currently.

Woody Gilk

unread,
Apr 27, 2015, 3:16:10 PM4/27/15
to php...@googlegroups.com
On Mon, Apr 27, 2015 at 2:14 PM, Levi Morrison <morris...@gmail.com> wrote:
> You must be talking about Laravel's Ardent which picked this name

I was indeed confused by that. Thanks for clarifying.

--
Woody Gilk
http://about.me/shadowhand

Levi Morrison

unread,
Apr 27, 2015, 3:24:52 PM4/27/15
to php...@googlegroups.com
On Friday, April 24, 2015 at 7:01:03 AM UTC-6, Taylor Otwell wrote:
Not a huge fan of this.

Collections / arrays are *already* inter-changable without any libraries having to change their code at all. One library can simply pass the raw array underlying their collection to another library, which can then change the array back to a Collection object of its own choosing. Typically, the cost of moving from array to Collection and back again is negligible.

This assumes that the underlying collection is stored as an array to begin with; some structures such as balanced trees are inherently not an array. What is being proposed here is not necessarily that broad. It seems people here are more interested in an interface that is an ArrayAccess, Countable, Traversable at its core, in which case converting to an array and back is possibly good enough, as Taylor mentions.

To respond to something Larry said:

The big gap in PHP now isn't the collection per se, it's the incompatibility between arrays and iterators.
 
This depends somewhat on the operation. There is no reason that filter, map and reduce can't work on a general Iterator, but sort and diff needs more information to be efficient. Even still that's not something FIG can really change, though.

Dries Vints

unread,
Apr 27, 2015, 3:33:50 PM4/27/15
to php...@googlegroups.com
Doctrine: https://github.com/doctrine/collections/
Another Collection package I found by Johannes Schmitt: https://github.com/schmittjoh/php-collection

I cannot speak for any of the authors but at least you have some links now.

Paul M. Jones

unread,
Apr 27, 2015, 3:41:10 PM4/27/15
to php...@googlegroups.com

> On Apr 27, 2015, at 14:15, Woody Gilk <woody...@gmail.com> wrote:
>
> On Mon, Apr 27, 2015 at 2:14 PM, Levi Morrison <morris...@gmail.com> wrote:
>> You must be talking about Laravel's Ardent which picked this name
>
> I was indeed confused by that. Thanks for clarifying.

As was I.


--
Paul M. Jones
pmjo...@gmail.com
http://paul-m-jones.com

Modernizing Legacy Applications in PHP
https://leanpub.com/mlaphp

Solving the N+1 Problem in PHP
https://leanpub.com/sn1php


Reply all
Reply to author
Forward
0 new messages