Download the PHP package xi/collections without Composer

On this page you can find all versions of the php package xi/collections. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package collections

Xi Collections

Functional, immutable and extensible enumerations and collections for PHP 5.3.

Design Philosophy

PHP has always lacked solid collections support, with the vast majority of programmers making do with arrays and the related built-in functions. With the introduction of SPL in PHP 5.0 and the consequent extensions in 5.3, there are currently more choices than ever if all you want for is speed and answers to specific use cases. Array processing, however, is not significantly better than ten years ago, with the API about as comfortable and handy for everyday tasks as picking at your dinner with a shovel.

Xi Collections aims to rectify the situation and inject your workflow with a hearty dose of functional and declarative aspects. This is intended to result in more clarity in expressing and understanding processing collections of objects or data, allowing you to work faster and deliver more self-documenting code.

Design Principles

Examples

From imperative to functional

Let's assume a simple loop that filters and transforms a set of data:

public function getMatchingInterestingParts() {
    $result = array();
    foreach ($this->getFoos() as $key => $value) {
        if ($this->match($value)) {
            $result[$key] = $value->getInterestingParts();
        }
    }
    return $result;
}

Here's the same expressed with Collections:

public function getMatchingInterestingParts() {
    return $this->getFoos()
        ->filter(function(Foo $foo) {
            return $this->matches($foo);
        })->map(function(Foo $foo) {
            return $foo->getInterestingParts();
        });
}

The latter bit of code is not much shorter, and for someone unfamiliar with functional constructs it may be more difficult to process. It does, however, have a few interesting qualities. The code communicates its intent better - filter values, then map the result, and nothing else. This is especially beneficial when considering code with a significantly more complex set of transformations. There's less room for error; index associations are automatically maintained. This also means you can focus on the interesting bits instead of boilerplate, which helps both when reading and when writing the code. A third benefit is that you can take full advantage of type hints and the safety they can bring, something which will be lacking with a simple foreach loop.

Simplifying common access patterns

One of the most common use cases for looping over an array is collecting the results of a member access or method invocation from every item. Collections makes that easy.

public function getBarsByFoos() {
    $bars = array();
    foreach ($this->getFoos() as $key => $foo) {
        $bars[$key] = $foo->getBar();
    }
    return $bars;
}
// becomes
public function getBarsByFoos() {
    return $this->getFoos()->invoke('getBar');
}

public function getFooTrivialities() {
    $trivialities = array();
    foreach ($this->getFoos() as $key => $foo) {
        $trivialities[$key] = $foo->triviality;
    }
    return $trivialities;
}
// becomes
public function getFooTrivialities() {
    return $this->getFoos()->pick('triviality');
}

Picking even works for arrays (or objects implementing ArrayAccess) as well, and you don't need to care about which type the input is.

Inspecting intermediate steps of complex operations

Suppose you have a pipeline where data is transformed according to complex rules.

public function getAliveQuxen() {
    return $this->getFoos()
        ->map($this->fromFooToBar)
        ->filter(function($bar) { return $bar->isAlive(); })
        ->map($this->fromBarToQux);
}

Suppose further that you want to inspect the data as it passes from one step to another. This is where you'd introduce temporary variables, were the code imperatively structured. With Collections, all you need is tap. It accepts a function that takes the contents of the collection as its parameter - and does nothing but call the function.

public function getAliveQuxen() {
    return $this->getFoos()
        ->map($this->fromFooToBar)
        ->filter(function($bar) { return $bar->isAlive(); })
        ->tap(function($bars) { $this->log($bars); })
        ->map($this->fromBarToQux);
}

A reader of your code will be able to immediately recognize that the part in tap is only being executed for its side effects and that it has nothing to do with the transformation itself. We could've used each in a similar fashion if we were instead interested in the individual units of computation.

public function getAliveQuxen() {
    return $this->getFoos()
        ->map($this->fromFooToBar)
        ->filter(function($bar) { return $bar->isAlive(); })
        ->each(function($bar) { $this->logBar($bar); })
        ->map($this->fromBarToQux);
}

Delaying computation using views

In some cases you may wish to expose a certain Collection to a consumer, but are not certain whether the Collection is going to be used, and generating one is potentially costly. In such a case you can apply a CollectionView, which is a set of transformation operations that haven't yet been applied to an underlying base Collection. Upon access, the operations will be applied and the resulting values provided to the consumer.

A Collection is transformed into a view backed by itself by invoking view. Best effort is made to apply all Collection method calls lazily. Forcing the view into actual values happens when accessing any Enumerator methods.

public function getEnormouslyExpensiveCollection() {
    return $this->getStuff()->view()->map(function(Stuff $s) {
        return enormouslyExpensiveComputation($s);
    });
}

There's a caveat, however. It is not guaranteed that the transformation from lazy to strict should happen exactly once per CollectionView object. If you need that, you should force the view object to get a strict one.

Using an extended API on the fly

In any given PHP environment there tends to be an amount of existing functionality around for processing data in a Traversable format. PHP itself has a plethora of built-in array functions that aren't feasible to support in the Collection API if it is supposed to be kept minimal. This can potentially change with the introduction of traits in PHP 5.4, but for now you'll have to figure out ways to use these functions manually. At the core of this facility is apply. It accepts a function that applies a transformation of some kind to the collection, the result of which is taken in as a new collection.

Let's assume you want to sort your values. Here's a way to do it using apply.

public function getSortedFoos() {
    return $this->getFoos()
        ->apply(function($collection) {
            $foos = $collection->toArray();
            ksort($foos);
            return $foos;
        });
}

The argument is a collection, which will have to be converted to an array first to be accepted by ksort. The function also operates on references, not values, so a temporary variable is necessary. There's an amount of cruft with this use case, but you're likely to be using raw PHP functions rarely. If you're using apply with functions that have a more reasonable API, eg. accept Traversable objects instead of necessitating arrays, the footprint becomes much more palatable. In such a fictional scenario for ksort, for instance:

public function getSortedFoos() {
    return $this->getFoos()
        ->apply('ksort');
}

API basics

Collections has two core interfaces. Enumerable implements a set of collection operations relying only on traversability. Collection extends the Enumerable operations to a superset that includes operations that yield other collections in return. This means collections can be transformed into other collections.

Every concrete class has a static create method that can be used for fluently constructing and accessing a collection. For instance:

ArrayCollection::create($values)->invoke('getBar')->each(function(Bar $bar) { $bar->engage(); });

Below is a short description of the APIs provided by Enumerable and Collection. For more thorough information, you'll need to consult the source.

Enumerable

Element retrieval

Element conditions

Size information

Reduces

Invocations

Collection

Maps

Subcollections

Subdivisions

Additions

Size information

Sorts

Views

Specific reduces

CollectionView

Collection implementations

Running the unit tests

phpunit -c tests

TODO


All versions of collections with dependencies

PHP Build Version
Package Version
Requires php Version >=5.3.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package xi/collections contains the following files

Loading the files please wait ....