PHP code example of lisachenko / userland-php-generics
1. Go to this page and download the library: Download lisachenko/userland-php-generics library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
lisachenko / userland-php-generics example snippets
use Lisachenko\Generics\Attribute\TemplateParameter;
use Lisachenko\Generics\{GenericObject, GenericTemplate};
/**
* @template T
*/
#[TemplateParameter('T')]
final class Box implements GenericObject
{
use GenericTemplate;
private ?T $value = null;
public function set(T $value): void
{
$this->value = $value;
}
public function get(): ?T
{
return $this->value;
}
}
$intBox = new (Box::of('int'))();
$intBox->set(42); // fine
$intBox->set('nope'); // TypeError: Box<int>::set(): Argument #1 ($value) must be of type int
get_class($intBox); // "Box<int>" — a real, registered, instantiable class
$factory = new GenericFactory(mangler: new IdentifierSafeNameMangler());
use Lisachenko\Generics\Runtime\GenericAutoloader;
GenericAutoloader::register($factory); // never installed for you
class_exists('App\Generic\Box_int'); // true - minted on the spot
spl_autoload_register(fn ($name) => print $name);
class_exists('App\Box<int>'); // prints nothing whatsoever
use Lisachenko\Generics\Generic;
Generic::bootstrap(); // optional: boots Z-Engine now instead of on first specialization
private ?T $value = null;
public function set(T $value): void {}
#[Of('T')]
private mixed $value = null;
#[TemplateParameter('T', of: Countable::class)]
interface BoxInterface extends GenericObject {}
/** @template T @implements BoxInterface<T> */
#[TemplateParameter('T')]
final class Box implements BoxInterface { use GenericTemplate; }
function consume(BoxInterface $box): void {} // works for every Box<X>
$box = new (Box::of('int'))(); // inferred as Box<int>
Box::of('int'); // class-string<Box<int>>
Box::of($runtime); // class-string<Box> - not narrowed, and not wrong
use Lisachenko\Generics\Native\NativeVector;
$samples = new (NativeVector::of('int'))($blobFromTheWire);
echo $samples[0]; // a zend_long read straight out of the block
$samples[1] = -20; // written straight back into it
$samples->append(50); // the block grows by eight bytes
$samples->append(1.5); // TypeError, from the engine
$bytes = $samples->toBinary(); // back to a PHP string, byte for byte