|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2005-03-15 19:54 UTC] rickd at commando-pernod dot net
Description:
------------
We use a user singleton instance for our cms user authed ids that should not be able to killed from third party addons or worse coders so easily, but accessable from all.
But when someone get the instance with reference it can be killed easy with setting the reference var to null, unset dont work.
If you put the static $instance holder inside the getinstance() function it seems to be work correct and cant be deleted from setting reference to NULL
Reproduce code:
---------------
class test {
static private $instance = null;
static function getinstance() {
if ( self::$instance == null ) {
return new test();
}
return self::$instance;
}
}
$user = &test::getinstance();
$user = null; // destroy singleton instance
$user = &test::getinstance();
unset( $user ); // dont destroy instance
Expected result:
----------------
singleton not destroying with setting a getted instance with
reference to null
Actual result:
--------------
singleton destroyed
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sun Oct 26 06:00:02 2025 UTC |
<?php class test { private static $instance = null; private $myname = ''; private function __construct( $value = '' ) { echo "New class $value created \n"; $this -> myname = $value; } private function __clone() {} static public function getInstance() { if ( self::$instance == null ) { self::$instance = new test('Singleton1'); } else { echo "Using old class " . self::$instance -> myname . "\n"; } return self::$instance; } static public function getInstance2() { static $instance2 = null; if ( $instance2 == null ) { $instance2 = new test('Singleton2'); } else { echo "Using old class " . $instance2 -> myname . "\n"; } return $instance2; } public function __destruct() { if ( defined('SCRIPT_END') ) { echo "Class " . $this -> myname . " destroyed at script end \n"; } else { echo "Class " . $this -> myname . " destroyed beforce script end \n"; } } } echo "Try static instance inside class :\n"; $getCopyofSingleton = test::getInstance(); $getCopyofSingleton = null; $getCopyofSingleton = &test::getInstance(); $getCopyofSingleton = null; $getCopyofSingleton = test::getInstance(); echo "Try static instance inside function :\n"; $getCopyofSingleton2 = test::getInstance2(); $getCopyofSingleton2 = null; $getCopyofSingleton2 = &test::getInstance2(); $getCopyofSingleton2 = null; $getCopyofSingleton2 = test::getInstance2(); define('SCRIPT_END',1); ?> Current result : Try static instance inside class : New class Singleton1 created Using old class Singleton1 Class Singleton1 destroyed beforce script end New class Singleton1 created Try static instance inside function : New class Singleton2 created Using old class Singleton2 Using old class Singleton2 Class Singleton1 destroyed at script end Class Singleton2 destroyed at script end Expected result : Try static instance inside class : New class Singleton1 created Using old class Singleton1 Using old class Singleton1 Try static instance inside function : New class Singleton2 created Using old class Singleton2 Using old class Singleton2 Class Singleton1 destroyed at script end Class Singleton2 destroyed at script end php setting : allow_call_time_pass_reference Off Off zend.ze1_compatibility_mode Off Off What i mean whats going wrong : to return a variable by reference, you need to define the caller?s code and function code with a & prefix, but it seems when you use the self:: and parent:: as return values this is broken, only caller need a & prefix, that is what i mean