I don't want this task to be done for each visitor : how to keep
results in an always instanciated php class
I focused on that part of the question, which makes me think that you rather missconcept the Singleton pattern, objects and requests.
Let me change your sample as another demonstration which maybe you will understand better
<?php
class Singleton {
public $x = 1;
private static $_inst = null;
private function __construct() { }
/**
* @return Singleton
*/
public static function getInstace() {
if (self::$_inst == null) {
self::$_inst = new self();
}
return self::$_inst;
}
}
if (isset($_POST['y'])) {
Singleton::getInstace()->x++;
echo Singleton::getInstace()->x;
}
?>
<form action="" method="post">
<input type="submit" name="y"/>
</form>
We have a Singleton
class which contains public property $x
accessible via its instance. Since constructor is private, you can access instance only from getInstance()
method. Singleton::getInstace()->x
will access the property $x
.
In this code, if the button is clicked, we expect the $x
property to increment by one.
When we first launch the script, the property has value of 1
. After we press the button, it has value of 1 + 1 = 2. And now, you expect, the value of 2
somehow to be written in the memory, so if the button is clicked for third time, it should show 3
. But, it unfortunately is not true, and no matter how many times you do click the button, you will always recieve a value of 2
, since after requesting the page for N-th time, it reinstantiates the class and it loses all of its changes.
There is no way to keep that persistence between all your clients only in the memory, because it's flushed right after it is used.
My suggestion is to keep changes into a database.
You can also do an object serialization, so you can save your changes into the database;
E.g.:
serialize(Singleton::getInstance());
outputs:
O:9:"Singleton":1:{s:1:"x";i:1;}
You can store this somewhere i.e. in db col serialized
afterwards extract it and assign it to variable:
$singleton = unserialize($row['serialized']);
Perform a change:
$singleton->x++;
See the serialized changes again:
O:9:"Singleton":1:{s:1:"x";i:2;}
Save them back.
Assign again
$singleton = unserialize($row['serialized']);
$singleton->x++;
echo $singleton->x;
Outputs: 3
This might not be the most efficient way, but you cannot rely on PHP objects to save in memory like database. That's why databases are present, and all the information for users, etc. is not stored into objects kept in the memory.
If there are a lot of credentials to save, the best design decision is to save each field into the DB instead of a serialized object, so you can set to the new instance the value from the database. That's what, in practice, the ORM's are for. Bind resultset to object.
Think twice which approach can fit your needs, if reinstantiating an object / pulling from the database for each user is costly, you should think about a caching approach, if no changes - no db pull, take from the cache.