php-standard-library/vec
php-standard-library/vec provides small, focused helpers for working with sequential 0-indexed arrays (lists). Create, map, filter, transform, and compose list operations with predictable behavior and clean APIs—part of the PHP Standard Library collection.
Collection excels in query-like operations (e.g., where, pluck), Vec fills gaps for strictly indexed, functional-style transformations (e.g., immutable pipelines, DSLs). Ideal for domains requiring ordered sequences (e.g., event sourcing, batch processing) where Laravel’s Collection lacks immutability guarantees.tap, when) but avoids Laravel’s OOP overhead. Useful for service-layer abstractions where raw arrays are verbose and Collection is overkill.array_* or SplFixedArray.Vec::fromArray($collection->toArray())), risking confusion with Laravel’s Collection methods (e.g., map vs. Vec::map).VecServiceProvider to register Vec as a global helper (e.g., vec()), mirroring Laravel’s collection().Vec<int, User>). Consider custom PHPDoc blocks for IDE support:
/** @var Vec<int, User> */
$users = Vec::fromArray($rawUsers);
InvalidArgumentException on access).Vec::map/filter may conflict with Laravel’s Collection methods, leading to:
Collection::map with Vec::map mid-project.Vec rejects non-sequential keys (e.g., ['a' => 1, 'b' => 2]). Requires explicit validation:
if (!Vec::isSequential($array)) { throw new InvalidArgumentException(); }
Vec::get(999) throws; native arrays return null. Behavior mismatch may cause bugs.Vec’s immutability model.Vec outperform Laravel’s Collection or native arrays? (e.g., immutability, strict typing, or DSL syntax).Vec for our event log processor because it enforces ordered, immutable transformations."Array.prototype)?Vec vs. arrays/collections).Collection for target operations (e.g., reduce, chunk)?Vec::reduce is 8% slower than array_reduce but 30% more readable for our use case."Vec-specific logic if the package evolves? (e.g., new methods, breaking changes).Vec instances be tested? (e.g., custom assertions, property-based testing with pestphp).VecTestCase trait with helpers like assertVecEquals()."Collection’s mutability is undesirable (e.g., caching intermediate results).Vec::fromArray($input)->validate()->map(...)).array_* calls with expressive Vec methods.Collection or Eloquent).array or stdClass).array_* or SplFixedArray).Vec for one operation chain (e.g., map + filter).// Before
$filtered = array_filter($users, fn($u) => $u['active']);
$mapped = array_map(fn($u) => $u['name'], $filtered);
// After
$result = Vec::fromArray($users)
->filter(fn($u) => $u['active'])
->map(fn($u) => $u['name']);
VecHelper to standardize usage and handle edge cases:
class VecHelper {
public static function fromInput(array $input, string $key): Vec {
return Vec::fromArray($input[$key] ?? []);
}
public static function ensureSequential(array $array): Vec {
if (!Vec::isSequential($array)) {
throw new InvalidArgumentException("Array must be sequential.");
}
return Vec::fromArray($array);
}
}
$this->app->singleton('vec', fn() => new VecHelper());
array_map/array_filter with Vec::map()/Vec::filter() in new code.Vec for return types in domain objects (e.g., public function getItems(): Vec).$vec = Vec::fromArray($collection->toArray());
$collection = Collection::make($vec->toArray());
VecCollection facade for seamless switching:
class VecCollection extends Collection {
public function toVec(): Vec { return Vec::fromArray($this->items); }
}
array_* via Vec::toArray(), but loses type safety.array_merge($vec->toArray(), [newItem]).function assertVecEquals(Vec $expected, Vec $actual) {
PHPUnit::assertEquals($expected->toArray(), $actual->toArray());
}
php-standard-library/vec to composer.json.map, filter, reduce).Collection for target operations.Vec usage guidelines (e.g., "Use Vec for ordered data pipelines").VecException for invalid inputs).^1.0 in composer.json until adoption stabilizes.How can I help you explore Laravel packages today?