Skip to content

Instantly share code, notes, and snippets.

@nicolas-grekas
Last active November 4, 2016 15:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nicolas-grekas/b23b27d9fd12796f89d15191f3cc9829 to your computer and use it in GitHub Desktop.
Save nicolas-grekas/b23b27d9fd12796f89d15191f3cc9829 to your computer and use it in GitHub Desktop.
<?php
// A proposal for a future PHP version: builtin lazy variables
class foo
{
function __construct(PDO $db) {
$this->db = $db;
}
function doJob()
{
$sql = '...';
$this->db->query($sql);
}
}
$host = 'localhost';
// Here is the new construct: a variable whose value
// can be computed later thanks to a closure,
// with a type that is known at compile time (PDO):
$db = var(PDO) use ($host) {
return new PDO($host);
};
$foo = new foo($db); // works, no db connection is made until really needed
/*
* - when only type information is needed, the provided var type should be used to resolve the need;
* - when the value is needed, the value should be computed and memoized so that the closure is never
evaluated again and can be freed;
* - any Exception or Error thrown by the closure should be propagated as usual;
* - returned values must match defined return type in `var (PDO)` or throw a TypeError
* - by nature, this construct is not reflectable and must be totally undifferentiable from its return value;
* - when a circular dependency is found while resolving the lazy-chain cascade (if any), an Error should be raised (exact type to be defined).
*
* To play nice with existing PHP extensions, this eval-n-replace should happen by default when any internal
* function/method is called (same hook as __toString?) Some internal functions that use only type information
* should be able to opt into not-triggering the lazy-evaluation (e.g. gettype, get_class).
*/
gettype($db) === 'object'; // true, does NOT trigger lazy-eval
get_class($db) === 'PDO'; // true, does NOT trigger lazy-eval
$db instanceof PDO; // true, does NOT trigger lazy-eval
var_dump($db); // exact same output as var_dump(new PDO(...)), DOES trigger lazy-eval
$db === $bar; // DOES trigger lazy-eval
$r = new ReflectionClass($db); // DOES trigger lazy-eval
$r->name === 'PDO'; // true
$foo->doJob(); // DOES trigger lazy-eval
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment