According to this article which shows how to create strictly typed arrays and collections in Php7, php-generic generator was born.
There is some discusion about generic in Php but who knows when it comes to us.
It is not exacly what you know from Java or C++ where generic looks like
Vector<int>()
, Array<bool>()
or Vector<\Namespace\Entity\User>()
.
Here generics looks like VectorInt
, ArrayBool
and VectorUser
so I hope when they come to nativ Php all what you need to do will be:
- Replace all
VectorType
,ArrayType
toVector<Type>
,array<Type>
, - Delete directory where you store all generated array/vector,
- Enjoy a nice day.
They are not collections like Doctrine or Laravel Collections. They are like normal php array
which can store values one type. array<int>
can store only numeric values which will converted to int
so you can not push 'some string value'
to it.
$ composer require d0niek/php-generic
There is a bin command that you should find in vendor/bin or somewhere else according to your composer.json settings.
To generate a generic array run:
$ bin/generic generate:array [-s|--save [SAVE]] [--] <type> <namespace>
where:
- -s|--saveCollection - do you want to save generated array for future regenerate (default true),
- type - is a type of generic array. It can be simple type (bool, int, float, string, array) or complex type (\YourApp\Module\Repository\User),
- namespace - is a namespace where new generic array will be save. Remember that namespace's directory have to exists. To separate namespace parts use \\ or / to speed up typing if your namespace is 1:1 with your directory structure
For example you have project in /path/to/project and your composer.json contains this kind of entry:
"autoload": {
"psr-4": {
"VendorName\\AppName\\": "src/"
}
}
Now, when you call command like this:
$ bin/generic generate:array int VendorName\\AppName\\Collections
new generic array ArrayInt
will be save to /path/to/project/src/Collections/ directory.
If this directory does not exists, exceptions will be throw.
Tip! Store all php-generics in one diretory and add it to .gitignore. When php will start support generics, replace
ArrayInt
toarray<int>
and remove php-generic directory.
You can alse generate generic \Ds\Vector (it is new data structure since Php7, here you can and you should read about it!). To do this just run:
$ bin/generic generate:vector [-s|--save [SAVE]] [--] <type> <namespace>
parameters means exacly the same whats means when you run generate:array
.
By defaule generated array/vector are save in generated-colletions.json file in your root app path.
Keep this file in repository and ignore all generated php-generics. When you clone repository,
after composer install
run:
$ bin/generic collections:regenerate
and all your collections will be regenerate.
Now you can create in easy way specific generic when you are selecting data from DB
class UserRepository implements UserRepositoryInterface
{
...
/**
* @inheritDoc
*/
public function findAll(): VectorUser
{
$users = new VectorUser();
$mysqli = new \mysqli('localhost:3306', 'user', 'password', 'db');
$mysqliResult = $mysqli->query('SELECT id, name FROM users LIMIT 10');
if ($mysqliResult !== false) {
while (($user = $mysqliResult->fetch_object(User::class)) !== null) {
$users->push($user);
}
}
$mysqli->close();
return $users;
}
...
}
Before you run tests remember to regenerate collections. Run:
$ bin/generic collections:regenerate
and now you can run
$ phpunit