da2e / generic-collection
PHP-based implementation for generic collection
Installs: 6 778
Dependents: 0
Suggesters: 0
Security: 0
Stars: 4
Watchers: 2
Forks: 0
Open Issues: 0
Requires
- php: >=7.1
Requires (Dev)
- ext-curl: *
- phpunit/phpunit: ^7.5
This package is not auto-updated.
Last update: 2024-11-09 12:12:29 UTC
README
This small library provides PHP-based implementation for generic collection.
PHP lacks generics (in opposite to Java, C++, etc). The problem is that you can't control and be sure which types do elements implement in an array/collection/hash/...
An example:
$a = [1, 2, new \stdClass(), function () { return 'foo'; }]; $r = 0; foreach ($a as $v) { $r += $v; // here for stdClass and a closure you will get an error: Object of class ... could not be converted to int. }
In Java for example you can eliminate that by using the generics:
List<String> v = new ArrayList<String>();
This library provides an OOP solution to have homogeneous types in a collection/array.
Built-in types
- DA2E\GenericCollection\Type\ArrayType (corresponds to PHP built-in is_array() function).
- DA2E\GenericCollection\Type\BoolType (corresponds to PHP built-in is_bool() function).
- DA2E\GenericCollection\Type\CallableType (corresponds to PHP built-in is_callable() function).
- DA2E\GenericCollection\Type\FloatType (corresponds to PHP built-in is_float() function).
- DA2E\GenericCollection\Type\IntType (corresponds to PHP built-in is_int() function).
- DA2E\GenericCollection\Type\IterableType (corresponds to PHP built-in is_iterable() function).
- DA2E\GenericCollection\Type\MixedType (passes any value through).
- DA2E\GenericCollection\Type\NullType (corresponds to PHP built-in is_null() function).
- DA2E\GenericCollection\Type\NumericType (corresponds to PHP built-in is_numeric() function).
- DA2E\GenericCollection\Type\ObjectType (corresponds to PHP built-in is_object() function).
- DA2E\GenericCollection\Type\ResourceType (corresponds to PHP built-in is_resource() function).
- DA2E\GenericCollection\Type\ScalarType (corresponds to PHP built-in is_scalar() function).
- DA2E\GenericCollection\Type\StringType (corresponds to PHP built-in is_string() function).
Special types:
- DA2E\GenericCollection\Type\CustomType: accepts a callback function with one argument to build a custom validator. E.g.:
use DA2E\GenericCollection\GCollection; use DA2E\GenericCollection\Type\CustomType; $collection = new GCollection(new CustomType(function ($value) { return $value === 'foobar'; })); $collection[] = 'foobar'; // valid $collection[] = 'bar'; // invalid
- DA2E\GenericCollection\Type\GCollectionType: a type for embedded GCollections. E.g.:
use DA2E\GenericCollection\Type\GCollectionType; use DA2E\GenericCollection\Type\StringType; use DA2E\GenericCollection\GCollection; $collection = new GCollection(new GCollectionType()); $collection[] = new GCollection(new StringType()); // valid $collection[] = new StringType(); // invalid
ObjectType
ObjectType optionally accepts a fully-qualified class name to validate that value implements the given class. e.g.:
$value = new Some\Class\Here(); $type = new DA2E\GenericCollection\Type\ObjectType('Some\Class\Here'); $type->validate($value);
How to use
- Create a Generic Collection.
- Pass a Type for that collection in a constructor.
- Generic Collection implements \ArrayAccess interface, so just set/push elements to array.
- While adding elements to the collection it is immediately validated for the given type.
- If the type is invalid, a DA2E\GenericCollection\Exception\InvalidTypeException will be thrown.
An example:
use DA2E\GenericCollection\GCollection; use DA2E\GenericCollection\Type\StringType; use DA2E\GenericCollection\Exception\InvalidTypeException; try { $collection = new GCollection(new StringType()); // You can pass an array as 2nd argument as well. $collection[] = 'string'; // this one is fine $collection[] = 1; // this one will throw an exception } catch (InvalidTypeException $e) { // handle exception }
- If you pass the collection to a method/function as an argument, you could demand that all elements should implement an exact type:
function foobar(GCollection $collection) { try { $collection->elementsShouldBeTypeOf(StringType::class); // If something is wrong InvalidTypeException is thrown } catch (InvalidTypeException $e) { // handle exception } // ... }
If the collection contains object you could additionally assure that elements are instances of a specific class.
function foobar(GCollection $collection) { try { $collection->elementsShouldBeTypeOf(ObjectType::class); // This is fine and valid but does not give a lot of information which exactly object is there. $collection->elementsShouldBeTypeOf(YourAnyClass::class); // This is more verbose and clear. We know that we expect a concrete YourAnyClass objects. } catch (InvalidTypeException $e) { // handle exception } // ... }
Additional functions of GCollectionInterface
There many additional functions in GCollectionInterface (e.g. map, filter, slice, shuffle, etc.). Please refer to the interface to see all of the functions.
map
use DA2E\GenericCollection\GCollection; use DA2E\GenericCollection\Type\StringType; $collection = new GCollection(new StringType(), ['a' ,'b']); $collection->map(function ($item) { return $item . '2'; }); // Returns [ 'a2', 'b2', 'c2' ]
filter
use DA2E\GenericCollection\GCollection; use DA2E\GenericCollection\Type\StringType; $collection = new GCollection(new StringType(), ['a' ,'b']); $collection->filter(function ($item) { return $item === 'b'; }); // Returns [ 'b' ]
sort
use DA2E\GenericCollection\GCollection; use DA2E\GenericCollection\Type\StringType; $collection = new GCollection(new StringType(), ['a' ,'b']); $collection->sort(function (array $items) { rsort($items); // Here you can call any sort function you wish. return $items; }); // Returns [ 'b', 'a' ]