Well, I know that you probably weren't looking for this, but it is late and I am bored.
Disclaimer: this is a bad idea.
class MyString
{
private $format, $pet;
public function __construct($format, &$pet)
{
$this->format = $format;
$this->pet = &$pet;
}
public function __toString()
{
return sprintf($this->format, $this->pet);
}
}
$myString = new MyString('This is my little %s, cool huh?', $pet);
$pet = 'cat';
echo $myString."\n";
$pet = 'dog';
echo $myString."\n";
$pet = 'goldfish';
echo $myString."\n";
Output:
This is my little cat, cool huh?
This is my little dog, cool huh?
This is my little goldfish, cool huh?
Demo: https://3v4l.org/XmUEZ
Basically this class stores a reference to the $pet variable in it's fields. As such, when the $pet variable is updated, the reference in the class is updated as well.
Another one for good measure:
function mysprintf($format, &$variable)
{
return function() use ($format, &$variable) {
return sprintf($format, $variable);
};
}
$print = mysprintf('This is my little %s, cool huh?', $pet);
$pet = 'cat';
echo $print()."\n";
$pet = 'dog';
echo $print()."\n";
$pet = 'goldfish';
echo $print()."\n";
https://3v4l.org/KJTKj
(Ab)uses closures to save the reference. Probably even worse.
Why is this a bad idea, you ask?
Consider solely this statement:
$pet = 'goldfish';
This is a simple assignment. Most programmers assume that this statement has no side-effects. That means that this statement changes nothing in the execution flow besides creating a new variable.
Our MyString or mysprintf violate this assumption. What should be a simple assignment, now has side-effects. It violates a programmer's expectation in the worst way possible.