note 75043 deleted from language.oop5.patterns by danbrown
| From: | danbrown@php.net | Date: | Sun, 23 Jan 2011 16:42:27 +0000 |
| Subject: | note 75043 deleted from language.oop5.patterns by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-176112@lists.php.net to get a copy of this message | ||
Note Submitter: baldurien at bbnwn dot eu
----
uvillaseca at yahoo dot es :
Yes. In PHP singleton are dependent to a start page - unless if php is runt from a console - thus :
<?php
final class Foo {
private __construct() {
// read some static file like configuration file
}
public static function getInstance() {
static $instance = null;
if (null === $instance) $instance = new Foo();
return $instance;
}
}
?>
The file is read each time someone hit the startpage (say "index.php" which would include
"Foo.php", and which would call Foo::getInstance()).
Use of cache like APC may allow you to achieve a singleton which would work on the whole server
instead of each incoming connexion (an incoming connexion that read a php page, like index.php, will
run the script, use the singleton, read the static file, each time while if the singleton was stored
like a global instance among each incoming transaction, then the file would be read only once).
However, it is hard to do some as you are not in Java and J2EE, where such is valid and thread safe
:
<?php // note : this is java!
public final class Foo {
private Foo() {/*read our file*/}
private static final Foo instance = new Foo();
public static final Foo getInstance() {
return instance;
}
}
?>
Because when Java load the class, a lock is acquired so that we only have one call to the
constructor, this is equivalent :
<?php // note : this is java!
public final class Foo {
private static final Object synchrotron = new Object();
private Foo() {/*read our file*/}
private static Foo instance;
public static final Foo getInstance() {
synchronized (synchrotron) {
// force the thread to wait here
// eg: only one thread is in that block
if (instance == null) {
instance = new Foo();
}
return instance;
}
}
}
?>
The comparison with Java is useful, because it means that you have some work to do to achieve a
singleton that would work on the whole server instead of only each incoming connexion :
If you use APC, like this :
<?php
final class Foo {
private __construct() {
// append "blah" to a file
}
public static function getInstance() {
if (false === ($o = apc_fetch(__FUNCTION__)) {
$o = new Foo();
apc_store(__FUNCTION__, $o);
}
return $o;
}
}
?>
This would work. But, when two incoming connexion arise at the same exact moment, then you will
append "blah" twice.
As for the one that said that singleton are a class with static method, no it is not. A singleton is
polymorphic, where static method are simply the equivalent with a class namespace of function.
If you have a method or function that expect an object implementing interface A, then you will be
able to use singleton implementing interface A.