I'm no fan of (too much) global helper functions, but I feel like is_initalized()
is a must! It really should be PHP native, but that's not happening.
This is_initialized()
helper is modeled after method_exists()
, and others like it, in the sense that it asks for an $object
and a $property
separately. Reason for this is that we cannot infer the context of a parameter when it is passed like is_initialized($object->parameter)
. The function would just receive the value.
if (!function_exists('is_initialized')) {
/**
* Returns whether a property is initialized with a value.
* @param string|object $object The class (name), that contains the property.
* @param string $property The name of the property.
* @return bool Whether the property is initialized with a value.
*/
function is_initialized($object, string $property): bool {
try {
return (new ReflectionProperty($object, $property))->isInitialized(is_object($object) ? $object : null);
} catch (ReflectionException $e) {
return false;
}
}
}
Why is this better than isset()
?
It's not "better" per se, but it makes memoization easier as a value can now also be null
. isset()
would return false
in that case. It kind of depends on your use case.
An example
In this example we use the $service
parameter for memoization. The parameter can by either null
or a Service
instance. In this case, only the first call to getService()
would call the container, whereas isset()
would call the container multiple times if the value where to be null
.
class Controller
{
private ?Service $service;
public function getService(): ?Service
{
if (!is_initialized($this, 'service')) {
$this->service = Container::get(Service::class); // either the service, or `null`
}
return $this->service;
}
}
Think you can make this better?
Please let me know if you have an idea on how this function could be even more helpful.
Couldn't you just do something like return $this->service ?? Container::get(....):
This->service would be null if it's not "initialised" . ?? Is perfect for that