Skip to content

Collection


Overview

Phalcon\Support\Collection is an object-oriented array. It offers speed, as well as implementations of various PHP interfaces. These are:

In addition to the interfaces, Collection exposes a rich method set for inspecting, transforming, and filtering the data it holds. The component is meant to be used wherever the application needs an object-flavored array that supports both property/array access and higher-order operations like filter(), map(), reduce(), and sort().

<?php

use Phalcon\Support\Collection;

$data = [
    'colors' => [
        'red',
        'green',
        'blue',
    ],
    'year'   => 1987,
];

$collection = new Collection($data);

Constructor

public function __construct(
    array $data = [],
    bool $insensitive = true,
    bool $strictNull = false,
    string | null $type = null
)

Collection accepts four optional constructor parameters. Each is described in its own section below, but here is the full surface at a glance:

Parameter Type Default Purpose
$data array [] Initial payload. The collection is populated by calling init($data).
$insensitive bool true When true, key lookups are case-insensitive.
$strictNull bool false When true, a stored null value is returned verbatim by get().
$type string\|null null Optional runtime type guard enforced on every set() / init() call.

The simplest construction passes only the initial payload:

<?php

use Phalcon\Support\Collection;

$data = [
    'colors' => [
        'red',
        'green',
        'blue',
    ],
    'year'   => 1987,
];

$collection = new Collection($data);

Case Sensitivity

The second constructor parameter, $insensitive, controls how key lookups behave. With the default true, all keys are normalized to lowercase on read and write, so get('year'), get('Year'), and get('YEAR') all return the same value. Setting it to false makes every key comparison exact.

<?php

use Phalcon\Support\Collection;

$data = [
    'colors' => [
        'red',
        'green',
        'blue',
    ],
    'year'   => 1987,
];

$collection = new Collection($data, false);

echo $collection->has('year');   // true
echo $collection->has('COLORS'); // false (would be true with $insensitive = true)

Strict Null Handling

The third constructor parameter, $strictNull, changes how get() reports stored null values:

  • false (default): a stored null is treated as "missing" and the supplied default (or null if no default is given) is returned. This matches the long-standing 3.x behavior.
  • true: a stored null is returned as-is. Use this when you need to distinguish "I stored null on purpose" from "the key was never set".
<?php

use Phalcon\Support\Collection;

$loose  = new Collection(['flag' => null], true, false);
$strict = new Collection(['flag' => null], true, true);

echo $loose->get('flag', 'fallback');  // 'fallback' — null treated as missing
echo $strict->get('flag', 'fallback'); // null      — null returned verbatim

has() is unaffected by $strictNull — it reports membership, not value. A key whose stored value is null always satisfies has().

Type Guard

The fourth constructor parameter, $type, turns the collection into a typed container. When set, every set() and every value assigned through init() (or via __set, offsetSet, or the property syntax) is validated against $type. A mismatched value triggers an InvalidArgumentException and is not stored.

The accepted tokens are split into two groups:

Scalar tokens map to the corresponding is_* checks:

Token Check
'int' is_int()
'string' is_string()
'bool' is_bool()
'float' is_float()
'array' is_array()
'object' is_object()

Anything else is treated as a fully-qualified class or interface name and tested with instanceof.

<?php

use Phalcon\Support\Collection;
use Phalcon\Mvc\Url;

// Scalar guard — only integers allowed
$years = new Collection([], true, false, 'int');

$years->set('genesis', 1987); // OK
$years->set('genesis', '1987'); // InvalidArgumentException — '1987' is a string

// Class guard — only Url instances allowed
$urls = new Collection([], true, false, Url::class);

$urls->set('home', new Url());    // OK
$urls->set('home', '/home');      // InvalidArgumentException

The guard runs on the initial payload as well, so passing data that does not match the declared type will throw at construction time:

$years = new Collection(['ok' => 1, 'bad' => 'two'], true, false, 'int');
// InvalidArgumentException is thrown while iterating the initial array

You can read the configured guard back at any time with getType() (see below). When $type is null (the default), the guard is a no-op and any value is accepted.

Reusing

You can also reuse the component by repopulating it. Phalcon\Support\Collection exposes three methods to manage the internal data wholesale:

  • clear() — empties the collection.
  • init(array $data = []) — adds each entry of $data to the collection without clearing first. Existing keys are overwritten; other keys are left untouched.
  • replace(array $data) — clear-then-init in one call. Useful when you want a clean swap.
<?php

use Phalcon\Support\Collection;

$data = [
    'colors' => [
        'red',
        'green',
        'blue',
    ],
    'year'   => 1987,
];

$collection = new Collection($data);

echo $collection->count(); // 2

// Wholesale swap
$collection->replace(['year' => 1987]);

echo $collection->count(); // 1

// Or the two-step variant
$collection->clear();
$collection->init(['year' => 1987]);

echo $collection->count(); // 1

Get

Phalcon\Support\Collection implements several interfaces to make the component as flexible as possible. Retrieving data stored in an element can be done by using:

  • Property access
  • __get()
  • Array-based get ($collection[$element])
  • offsetGet()
  • get()

The fastest way is by using the property syntax:

<?php

use Phalcon\Support\Collection;

$data = [
    'colors' => [
        'red',
        'green',
        'blue',
    ],
    'year'   => 1987,
];

$collection = new Collection($data);

echo $collection->year; // 1987

You can use __get($element) but it is not advisable as it is much slower than the property syntax. The same applies to offsetGet:

echo $collection->__get('year');           // 1987
echo $collection['year'];                  // 1987
echo $collection->offsetGet('year');       // 1987
echo $collection->get('year', 1987);       // 1987
public function get(
    string $element,
    mixed $defaultValue = null,
    string | null $cast = null
): mixed

get() offers three parameters:

  • $element — the key of the element we want to retrieve.
  • $defaultValue — returned when $element is not set, or when $element is set to null and $strictNull is false (the default). See Strict Null Handling for the strict variant.
  • $cast — accepts a string that defines what the returned value will be cast to before it is returned. The available values are:
    • array
    • bool
    • boolean
    • double
    • float
    • int
    • integer
    • null
    • object
    • string
$collection = new Collection(['port' => '8080']);

echo $collection->get('port', null, 'int'); // (int) 8080

Has

To check whether an element exists or not in the collection, you can use the following:

  • isset() on the property
  • __isset()
  • Array-based isset (isset($collection[$element]))
  • offsetExists()
  • has()

The fastest way is by using the property syntax:

<?php

use Phalcon\Support\Collection;

$data = [
    'colors' => [
        'red',
        'green',
        'blue',
    ],
    'year'   => 1987,
];

$collection = new Collection($data);

echo isset($collection->year); // true

You can use __isset($element) but it is not advisable as it is much slower than the property syntax. The same applies to offsetExists:

echo $collection->__isset('year');      // true
echo isset($collection['year']);        // true
echo $collection->offsetExists('year'); // true
echo $collection->has('year');          // true
public function has(string $element): bool

Set

To set an element in the collection, you can use the following:

  • Assign the value to the property
  • __set()
  • Array-based assignment
  • offsetSet()
  • set()

The fastest way is by using the property syntax:

<?php

use Phalcon\Support\Collection;

$data = [
    'colors' => [
        'red',
        'green',
        'blue',
    ],
];

$collection = new Collection($data);

$collection->year = 1987;

You can use __set($element, $value) but it is not advisable as it is much slower than the property syntax. The same applies to offsetSet:

$collection->__set('year', 1987);
$collection['year'] = 1987;
$collection->offsetSet('year', 1987);
$collection->set('year', 1987);

Every code path above ultimately routes through the same internal setData() helper, which means the Type Guard (when configured) applies uniformly regardless of which form you use.

Remove

To remove an element in the collection, you can use the following:

  • unset the property
  • __unset()
  • Array-based unset
  • offsetUnset()
  • remove()

The fastest way is by using the property syntax:

<?php

use Phalcon\Support\Collection;

$data = [
    'colors' => [
        'red',
        'green',
        'blue',
    ],
];

$collection = new Collection($data);

unset($collection->year);

You can use __unset($element) but it is not advisable as it is much slower than the property syntax. The same applies to offsetUnset:

$collection->__unset('year');
unset($collection['year']);
$collection->offsetUnset('year');
$collection->remove('year');
public function remove(string $element): void

Keys and Values

Collection exposes two methods to read the internal data shape directly:

  • keys(bool $insensitive = true): array — returns the keys stored internally. With the default true, keys are returned in their case-insensitive (lowercase) form, mirroring how they were indexed. Pass false to receive the keys in their original casing.
  • values(): array — returns the values, indexed numerically from 0.
<?php

use Phalcon\Support\Collection;

$data = [
    'Year'   => 1987,
    'colors' => ['red', 'green', 'blue'],
];

$collection = new Collection($data);

print_r($collection->keys());      // ['year', 'colors']
print_r($collection->keys(false)); // ['Year', 'colors']
print_r($collection->values());    // [1987, ['red', 'green', 'blue']]

NOTE

The original method names getKeys() and getValues() are retained as deprecated thin wrappers over keys() / values(). New code should call keys() and values() directly. The deprecated forms will be removed in a future major release.

Inspecting

The following methods give you quick visibility into the collection without iterating it yourself:

  • count(): int — number of stored elements (also satisfies Countable).
  • isEmpty(): booltrue when the collection holds no elements.
  • first(): mixed — first stored value, or null when empty.
  • last(): mixed — last stored value, or null when empty.
  • getType(): string | null — the type guard configured at construction (see Type Guard), or null when none.
  • column(string $propertyOrMethod): array — projects a single property (or method-result) off every stored item, keyed by the original collection key.
<?php

use Phalcon\Support\Collection;

$collection = new Collection([
    'one'   => 1,
    'two'   => 2,
    'three' => 3,
]);

echo $collection->count();   // 3
echo $collection->isEmpty(); // false
echo $collection->first();   // 1
echo $collection->last();    // 3
echo $collection->getType(); // null

column() accepts the name of either a public property or a public method. For each stored item it returns the property's value, or the result of invoking the method with no arguments. Items that are not objects/arrays are returned as null.

<?php

use Phalcon\Support\Collection;

class User
{
    public function __construct(
        public string $name,
        public int $age,
    ) {}

    public function displayName(): string
    {
        return strtoupper($this->name);
    }
}

$users = new Collection([
    'alice' => new User('Alice', 30),
    'bob'   => new User('Bob', 25),
]);

print_r($users->column('age'));
// ['alice' => 30, 'bob' => 25]

print_r($users->column('displayName'));
// ['alice' => 'ALICE', 'bob' => 'BOB']

column() also works on plain arrays:

$rows = new Collection([
    ['id' => 1, 'name' => 'Alice'],
    ['id' => 2, 'name' => 'Bob'],
]);

print_r($rows->column('name')); // [0 => 'Alice', 1 => 'Bob']

Filtering and Transforming

Collection exposes a small set of higher-order operations modeled after the standard array primitives. Each of these returns a new Collection of the same concrete subclass (so Registry::filter(...) returns a Registry, not a base Collection) and carries over the insensitive, strictNull, and type configuration; the source collection is never mutated.

each(callable $callback)

Runs $callback($value, $key) for every entry and returns the collection itself, so calls can be chained. Use this for side effects (logging, dispatching events) where you do not need a new collection back.

<?php

use Phalcon\Support\Collection;

$collection = new Collection(['one' => 1, 'two' => 2, 'three' => 3]);

$collection
    ->each(function ($value, $key) {
        echo "$key => $value" . PHP_EOL;
    })
    ->each(function ($value) {
        // do something else
    });

filter(callable $callback)

Returns a new collection containing only the entries for which $callback($value, $key) returns a truthy value. Original keys are preserved.

<?php

use Phalcon\Support\Collection;

$collection = new Collection([
    'one'   => 1,
    'two'   => 2,
    'three' => 3,
    'four'  => 4,
]);

$even = $collection->filter(
    fn ($value) => $value % 2 === 0
);

print_r($even->toArray()); // ['two' => 2, 'four' => 4]

map(callable $callback)

Returns a new collection with every entry replaced by $callback($value, $key). Keys are preserved.

<?php

use Phalcon\Support\Collection;

$collection = new Collection(['one' => 1, 'two' => 2, 'three' => 3]);

$squared = $collection->map(
    fn ($value) => $value * $value
);

print_r($squared->toArray()); // ['one' => 1, 'two' => 4, 'three' => 9]

reduce(callable $callback, mixed $initial = null)

Collapses the collection to a single value by repeatedly applying $callback($accumulator, $value, $key). The first call receives $initial as the accumulator; each subsequent call receives the previous return value.

<?php

use Phalcon\Support\Collection;

$collection = new Collection(['one' => 1, 'two' => 2, 'three' => 3]);

$sum = $collection->reduce(
    fn ($acc, $value) => $acc + $value,
    0
);

echo $sum; // 6

sort(?callable $callback = null, int $order = SORT_ASC)

Returns a new collection sorted by value, preserving keys. When $callback is supplied it is passed to PHP's uasort. Without a callback, the comparison direction is controlled by $order (SORT_ASC uses asort(), SORT_DESC uses arsort()).

<?php

use Phalcon\Support\Collection;

$collection = new Collection([
    'c' => 30,
    'a' => 10,
    'b' => 20,
]);

print_r($collection->sort()->toArray());
// ['a' => 10, 'b' => 20, 'c' => 30]

print_r($collection->sort(null, SORT_DESC)->toArray());
// ['c' => 30, 'b' => 20, 'a' => 10]

$byLength = $collection
    ->map(fn ($v) => str_repeat('x', $v / 10))
    ->sort(fn ($left, $right) => strlen($left) <=> strlen($right));

where(string $propertyOrMethod, mixed $value)

Returns a new collection containing only the items whose $propertyOrMethod (resolved through the same logic as column()) is strictly equal (===) to $value.

<?php

use Phalcon\Support\Collection;

$users = new Collection([
    ['id' => 1, 'role' => 'admin'],
    ['id' => 2, 'role' => 'user'],
    ['id' => 3, 'role' => 'admin'],
]);

$admins = $users->where('role', 'admin');

print_r($admins->toArray());
// [
//   0 => ['id' => 1, 'role' => 'admin'],
//   2 => ['id' => 3, 'role' => 'admin'],
// ]

Iteration

Since the collection object implements \IteratorAggregate, you can iterate through the object with ease. getIterator() returns an ArrayIterator instance.

<?php

use Phalcon\Support\Collection;

$data = [
   'red',
   'green',
   'blue',
];

$collection = new Collection($data);

foreach ($collection as $key => $value) {
    echo $key . ' - ' . $value . PHP_EOL;
}

Count

The implementation of the \Countable interface exposes the count() method, which stores the number of elements in the collection.

<?php

use Phalcon\Support\Collection;

$data = [
    'colors' => [
        'red',
        'green',
        'blue',
    ],
    'year'   => 1987,
];

$collection = new Collection($data);

echo $collection->count(); // 2
echo count($collection);   // 2 (same value, via Countable)

Serialization

The \Serializable and \JsonSerializable interfaces expose methods that allow you to serialize and unserialize the object. serialize() and unserialize() use PHP's serialize / unserialize functions; jsonSerialize() returns an array which can be used with json_encode to serialize the object.

__serialize() returns a structured array that captures the full collection configuration — data, insensitive, strictNull, and type — so that round-tripping through serialize()/unserialize() faithfully restores the case-sensitivity setting, the strict-null mode, and the type guard, not just the data.

<?php

use Phalcon\Support\Collection;

$data = [
    'colors' => [
        'red',
        'green',
        'blue',
    ],
    'year'   => 1987,
];

$collection = new Collection($data, false, true, 'int');

$blob = $collection->serialize();
// O:31:"Phalcon\Support\Collection":4:{...}
// Contains data + insensitive=false + strictNull=true + type=int

$restored = new Collection();
$restored->unserialize($blob);

echo $restored->getType(); // 'int' — guard preserved

Backwards compatibility

__unserialize() accepts both the new structured format and the legacy flat-array format produced by earlier releases, so existing serialized blobs stored in caches, sessions, or databases keep deserializing without intervention. When a legacy blob is loaded, the missing fields default to insensitive = true, strictNull = false, type = null.

Transformations

Phalcon\Support\Collection also exposes two transformation methods: toArray() and toJson(int $options). toArray() returns the object transformed as an array. This method returns the same array as jsonSerialize().

<?php

use Phalcon\Support\Collection;

$data = [
    'colors' => [
        'red',
        'green',
        'blue',
    ],
    'year'   => 1987,
];

$collection = new Collection($data);

print_r($collection->toArray()); // $data

toJson(int $options) returns a JSON representation of the object. It uses json_encode internally and accepts a parameter, which represents the flags that json_encode accepts. By default, the options bundle together a sensible escape set:

  • JSON_HEX_TAG
  • JSON_HEX_APOS
  • JSON_HEX_AMP
  • JSON_HEX_QUOT
  • JSON_UNESCAPED_SLASHES
  • JSON_THROW_ON_ERROR

JSON_THROW_ON_ERROR is included so that encode failures (e.g., passing a value that cannot be JSON-encoded like a resource) raise an InvalidArgumentException rather than silently returning an empty string.

You can pass any valid flags to the method according to your needs.

<?php

use Phalcon\Support\Collection;

$data = [
    'colors' => [
        'red',
        'green',
        'blue',
    ],
    'year'   => 1987,
];

$collection = new Collection($data);

echo $collection->toJson();
// {"colors":["red","green","blue"],"year":1987}

echo $collection->toJson(JSON_PRETTY_PRINT);
/**
{
    "colors": [
        "red",
        "green",
        "blue"
    ],
    "year": 1987
}
*/

Read Only Collection

Phalcon also offers a component that can be used in a read-only fashion. Phalcon\Support\Collection\ReadOnlyCollection can serve as a collection in your application that can only be populated with initial data but does not allow its contents to be changed throughout the application.

NOTE

This class has been renamed from ReadOnly in order to avoid collisions with PHP 8.x reserved words.

<?php

use Phalcon\Support\Collection\ReadOnlyCollection;

$data = [
    'colors' => [
        'red',
        'green',
        'blue',
    ],
    'year'   => 1987,
];

$collection = new ReadOnlyCollection($data);

echo $collection->toJson();
// {"colors":["red","green","blue"],"year":1987}

$collection->set('colors', ['red']); // Exception

Methods that would otherwise mutate state (clear, init, remove, replace, set) all throw Phalcon\Support\Collection\Exception. Read-only operations — get, has, keys, values, count, first, last, isEmpty, column, filter, map, reduce, sort, where, each, toArray, toJson — behave exactly as on a regular Collection.

Custom Objects

Phalcon allows developers to define their own collection objects. These objects must implement the canonical contract Phalcon\Contracts\Support\Collection. The expanded interface mirrors every public method exposed by Phalcon\Support\Collection:

<?php

namespace MyApp;

use Phalcon\Contracts\Support\Collection as CollectionContract;

class MyCollection implements CollectionContract
{
    public function __get(string $element): mixed;

    public function __isset(string $element): bool;

    public function __set(string $element, mixed $value): void;

    public function __unset(string $element): void;

    public function clear(): void;

    public function column(string $propertyOrMethod): array;

    public function each(callable $callback): static;

    public function filter(callable $callback): static;

    public function first(): mixed;

    public function get(
        string $element,
        mixed $defaultValue = null,
        ?string $cast = null
    ): mixed;

    public function getKeys(bool $insensitive = true): array;

    public function getType(): ?string;

    public function getValues(): array;

    public function has(string $element): bool;

    public function init(array $data = []): void;

    public function isEmpty(): bool;

    public function keys(bool $insensitive = true): array;

    public function last(): mixed;

    public function map(callable $callback): static;

    public function reduce(callable $callback, mixed $initial = null): mixed;

    public function remove(string $element): void;

    public function replace(array $data): void;

    public function set(string $element, mixed $value): void;

    public function sort(?callable $callback = null, int $order = SORT_ASC): static;

    public function toArray(): array;

    public function toJson(int $options = 4194383): string;

    public function values(): array;

    public function where(string $propertyOrMethod, mixed $value): static;
}

Interface location

The interface previously lived at Phalcon\Support\Collection\CollectionInterface. That symbol is retained as a deprecated alias that extends Phalcon\Contracts\Support\Collection, so existing implementations keep working without modification. New code should reference Phalcon\Contracts\Support\Collection directly.