ArrayKit is a modern PHP 8.4+ library for elegant, high-performance array manipulation , dot notation
utilities , dynamic configuration , hookable collections , and more.
From shallow single arrays to deeply nested data structures — ArrayKit provides a fluent, reliable toolkit for
real-world PHP projects.
Single-Dimensional Helpers
Multi-Dimensional Helpers
Dot Notation Get/Set/Flatten
Dynamic Config with Hooks
Collection & Hooked Collection
Unified Facade (ArrayKit)
Traits for DTO & Hooking
Pipeline for Collection Ops
LazyCollection for Generator-Based Flows
ArrayShape Validation Helper
Laravel Compatibility Layer (LaravelCompat\\Arr, LaravelCompat\\Collection)
Namespaced Helpers + Optional Globals
Helper
Description
ArraySingle
Helpers for single-dimensional arrays (set ops, mapWithKeys, countBy, min/max, paginate, duplicates, averages).
ArrayMulti
Helpers for multi-dimensional arrays (flatten, collapse, depth, keyBy/indexBy, firstWhere, recursive sort/filter).
DotNotation
Get/set/remove values using dot keys; wildcard support; escaped literal-dot paths; flatten & expand.
ArrayShape
Lightweight array-shape assertions for row validation (require).
BaseArrayHelper
Internal shared base for consistent API across helpers.
ArraySharedOps
Internal shared operations used by ArraySingle and ArrayMulti (each/every/partition/skip*).
Class
Description
Config
Dot-access configuration loader with explicit hook-aware variants (getWithHooks, setWithHooks, fillWithHooks).
LazyFileConfig
First-segment lazy loader (db.host loads db.php on demand) for lower memory usage on large config trees.
BaseConfigTrait
Shared config logic.
Class
Description
Collection
OOP array wrapper implementing ArrayAccess, IteratorAggregate, Countable, JsonSerializable.
HookedCollection
Extends Collection with on-get/on-set hooks for real-time transformation of values.
Pipeline
Functional-style pipeline for chaining operations on collections.
LazyCollection
Generator-backed lazy operations (mapLazy, filterLazy, chunkLazy, take, takeUntil).
BaseCollectionTrait
Shared collection behavior.
Trait
Description
HookTrait
Generic hook system for on-get/on-set callbacks. Used by Config, LazyFileConfig, and HookedCollection.
DTOTrait
Utility trait for DTO-like behavior: populate, extract, cast arrays/objects easily.
Helper Surface
Description
Infocyph\ArrayKit\*
Namespaced helper functions (compare, array_get, array_set, collect, chain) autoloaded by default.
functions.php
Optional global helper variants (manual include when needed).
Class
Description
ArrayKit
Single entry point for arrays, dot tools, config, and collections (single(), multi(), etc.).
composer require infocyph/arraykit
<?php
// Namespaced helpers are autoloaded by default.
use function Infocyph \ArrayKit \array_get ;
use function Infocyph \ArrayKit \array_set ;
use function Infocyph \ArrayKit \collect ;
use function Infocyph \ArrayKit \chain ;
// Optional: enable global helpers in projects that explicitly want them.
require_once __DIR__ . '/vendor/infocyph/arraykit/src/functions.php ' ;
use Infocyph \ArrayKit \ArrayKit ;
$ isList = ArrayKit::single ()->isList ([1 , 2 , 3 ]); // true
$ flat = ArrayKit::multi ()->flatten ([[1 ], [2 , [3 ]]]); // [1, 2, 3]
$ name = ArrayKit::dot ()->get (['user ' => ['n ' => 'A ' ]], 'user.n ' ); // A
$ config = ArrayKit::config (['app ' => ['env ' => 'local ' ]]);
$ env = $ config ->get ('app.env ' ); // local
Single-Dimensional Helpers
use Infocyph \ArrayKit \Array \ArraySingle ;
$ list = [1 , 2 , 3 , 2 ];
// Is it a list?
$ isList = ArraySingle::isList ($ list ); // true
// Duplicates
$ dupes = ArraySingle::duplicates ($ list ); // [2]
// Contains checks
$ hasAll = ArraySingle::containsAll ($ list , [1 , 2 ]); // true
$ hasAny = ArraySingle::containsAny ($ list , [99 , 2 ]); // true
// Pagination
$ page = ArraySingle::paginate ($ list , page:1 , perPage:2 ); // [1, 2]
Multi-Dimensional Helpers
use Infocyph \ArrayKit \Array \ArrayMulti ;
$ data = [ [1 , 2 ], [3 , [4 , 5 ]] ];
// Flatten to one level
$ flat = ArrayMulti::flatten ($ data ); // [1, 2, 3, 4, 5]
$ flatZero = ArrayMulti::flatten ($ data , 0 ); // [[1, 2], [3, [4, 5]]]
$ flatOne = ArrayMulti::flatten ($ data , 1 ); // [1, 2, 3, [4, 5]]
// Multi-column and query helpers
$ sortedMany = ArrayMulti::sortByMany ($ rows , [
['status ' , 'asc ' ],
['created_at ' , 'desc ' ],
]);
$ active = ArrayMulti::whereStartsWith ($ rows , 'status ' , 'act ' , false );
$ match = ArrayMulti::whereLike ($ rows , 'email ' , '%@example.com ' );
$ first = ArrayMulti::firstWhereIn ($ rows , 'role ' , ['admin ' , 'editor ' ]);
$ uniqueUsers = ArrayMulti::uniqueBy ($ rows , 'email ' );
$ dupeUsers = ArrayMulti::duplicatesBy ($ rows , fn ($ row ) => strtolower ((string ) ($ row ['email ' ] ?? '' )));
// Collapse one level
$ collapsed = ArrayMulti::collapse ($ data ); // [1, 2, 3, [4, 5]]
// Nesting depth
$ depth = ArrayMulti::depth ($ data ); // 3
// Recursive sort
$ sorted = ArrayMulti::sortRecursive ($ data );
use Infocyph \ArrayKit \Array \DotNotation ;
$ user = [
'profile ' => ['name ' => 'Alice ' ]
];
// Get value
$ name = DotNotation::get ($ user , 'profile.name ' ); // Alice
$ literal = DotNotation::get (['profile.name ' => 'flat ' ], 'profile \\.name ' ); // flat
// Set value
DotNotation::set ($ user , 'profile.email ' , 'alice@example.com ' );
// Flatten
$ flat = DotNotation::flatten ($ user );
// wildcard set
DotNotation::set ($ user , 'users.*.active ' , true );
// [ 'profile.name' => 'Alice', 'profile.email' => 'alice@example.com' ]
use Infocyph \ArrayKit \Config \Config ;
$ config = new Config ();
// Load from file
$ config ->loadFile (__DIR__ .'/config.php ' );
// Hook: auto-hash password when set
$ config ->onSet ('auth.password ' , fn ($ v ) => password_hash ($ v , PASSWORD_BCRYPT ));
// Hook: decrypt when getting 'secure.key'
$ config ->onGet ('secure.key ' , fn ($ v ) => decrypt ($ v ));
// Use it
$ config ->setWithHooks ('auth.password ' , 'secret123 ' );
$ hashed = $ config ->getWithHooks ('auth.password ' );
// Typed getters + state helpers
$ port = $ config ->getInt ('db.port ' , 3306 );
$ config ->snapshot ('before-runtime ' );
$ config ->merge (['app ' => ['env ' => 'production ' ]]);
$ changed = $ config ->changed ('before-runtime ' );
$ config ->restore ('before-runtime ' );
use Infocyph \ArrayKit \Collection \HookedCollection ;
$ collection = new HookedCollection (['name ' => 'alice ' ]);
// Hook on-get: uppercase
$ collection ->onGet ('name ' , fn ($ v ) => strtoupper ($ v ));
// Hook on-set: prefix
$ collection ->onSet ('role ' , fn ($ v ) => "Role: $ v " );
echo $ collection ['name ' ]; // ALICE
$ collection ['role ' ] = 'admin ' ;
echo $ collection ['role ' ]; // Role: admin
use Infocyph \ArrayKit \traits \DTOTrait ;
class UserDTO {
use DTOTrait;
public string $ name ;
public string $ email ;
}
$ user = new UserDTO ();
$ user ->fromArray (['name ' => 'Alice ' , 'email ' => 'alice@example.com ' ]);
$ array = $ user ->toArray ();
// Advanced hydration / export
$ user ->hydrate (['name ' => 'Alice ' ], mapping: ['name ' => 'full_name ' ]);
$ deep = $ user ->toArrayDeep ();
use Infocyph \ArrayKit \Array \ArrayShape ;
use Infocyph \ArrayKit \ArrayKit ;
use Infocyph \ArrayKit \LaravelCompat \Arr ;
$ lazy = ArrayKit::lazyCollection (range (1 , 10 ))
->filterLazy (fn ($ v ) => $ v % 2 === 0 )
->take (3 )
->all (); // [2, 4, 6]
$ row = ArrayShape::require (
['id ' => 1 , 'email ' => 'a@example.com ' , 'roles ' => ['admin ' ]],
['id ' => 'int ' , 'email ' => 'string ' , 'roles ' => 'list<string> ' ],
);
$ data = ['user ' => ['name ' => 'Alice ' ]];
Arr::set ($ data , 'user.role ' , 'admin ' );
ArrayMulti::flatten($array, 0) keeps top-level values unchanged; 1 flattens one level; INF fully flattens.
ArraySingle::avg(), sum(), isPositive(), and isNegative() only consider numeric values (non-numeric values are ignored).
ArraySingle::paginate() requires page >= 1 and perPage >= 1 (throws InvalidArgumentException otherwise).
Callback-based row helpers (ArrayMulti::sortBy(), sum(), maxBy(), minBy()) support ($row, $key).
DotNotation treats existing null keys/properties as present (does not fall back to defaults).
DotNotation::hasWildcard(), paths(), matches(), rename(), and move() are available for wildcard/path operations.
For untrusted/deep payloads, use bounded traversal variants: DotNotation::getSafe(), ArrayMulti::depthGuarded(), flattenGuarded(), and sortRecursiveGuarded().
Protected by PHPForge — an automated quality and security gate for PHP projects.