I want to make a function, modify for instance, for clients where user can modify passed object BUT not override it with another one.
I mean... if any user wants to override the passed object for instance:
$originObject = new \StdClass();
after the function execution
I'll be able to restore the SAME object passed to the function.
function modify(object &$obj): void {
$obj = new \StdClass();
}
function back(object &$obj, int $previousObjectId, string $serializedOriginObject): void {
if (\spl_object_id($obj) !== $previousObjectId) {
$obj = \unserialize($serializedOriginObject);
}
}
$originObject = new \StdClass; // ORIGIN OBJECT
$serializedOriginObject = \serialize($originObject);
$objectIdBeforeModify = \spl_object_id($originObject);
\var_dump($objectIdBeforeModify); // in my case object id: "1"
modify($originObject); // PASSES BY REFERENCE AND OVERRIDES IT
$objectIdAfterModify = \spl_object_id($originObject);
\var_dump($objectIdAfterModify); // in my case object id: "2"
back($originObject, $objectIdBeforeModify, $serializedOriginObject);
$returnedObjectId = \spl_object_id($originObject);
\var_dump($returnedObjectId); // in my case object id: "1"
My question is: are there any ways to make it without serialization? To restore an object that was overriden, cuz it was passed by reference in the function.
Just assign the object to another variable, using a normal "by value" assignment (no &
). The fact that $obj
was passed by reference won't be relevant, the current value will be used.
For instance, using a class just to have somewhere to store the value:
class Whatever {
private $backup;
public function replace(object &$obj) {
$this->backup = $obj;
$obj = new stdClass;
}
public function restore(object &$obj) {
$obj = $this->backup;
}
}
Note that because $obj
is an object, it is also mutable even when assigned by value. That is, code elsewhere could do something like $obj->foo = 42;
and that would change $backup
, because it is the same object being referenced.
If you don't want that, you could store a clone instead.