PHP Getting a reference through a constructor?

前端 未结 2 670
遥遥无期
遥遥无期 2021-01-23 10:51

I am wondering if it is possible while using the keyword \'new\' to return a reference to an existing object instead of a new object. And if not, what would be the best way to a

相关标签:
2条回答
  • 2021-01-23 11:08

    First a few facts:

    • The constructor can never return a value.
    • $this cannot be reassigned (it could in PHP 4 but wasn't intended, and was undocumented)

    Conclusion:

    • Use factory methods or delegation.*

    * There is a slight difference between the two, and that is that using delegation $a!=$b, but using factory methods $a === $b (see below)

    Delegation example:

    // Declare the delegate that will be wrapped by DelegationClass
    // * Only public methods/properties will be accessible
    class MyClass {
        public $a;
        public function a($a) {
            echo "This is a(\$a=$a)\n";
        }
    }
    
    class MyDelegationClass {
        static protected $_delegation = 'MyClass'; // define the delegate
        static protected $_i = array(); // instances
        protected $_l = null; // delegation link
        public function __construct($n) {
           if (!array_key_exists($n,self::$_i)) {
               // ensures that the instance is always created
               self::$_i[$n] = new self::$_delegation; 
            }
            $this->_l = self::$_i[$n]; // link to delegate
        }
        public function __get($v) {
            return $this->_l->$v; // get property from delegate link
        }
        public function __set($k,$v) {
            return $this->_l->$k = $v; // set property on delegate link
        }
        public function __call($f,$p) {
            // call method on delegate link
            return call_user_func_array(array($this->_l,$f),$p); 
        }
    }
    // $a != $b, but $a->a === $b->a
    $a = new MyDelegationClass(1);
    $b = new MyDelegationClass(1);
    

    Factory class example:

    class MyFactoryClass {
        static protected $_i = array(); // instances
        public static function newMyClass($n) {
           if (!array_key_exists($n,self::$_i)) {
               // ensures that the instance is always created
               self::$_i[$n] = new MyClass; 
            }
            return self::$_i[$n]; // return instance
        }
    }
    // $a === $b
    $a = MyFactoryClass::newMyClass(1);
    $b = MyFactoryClass::newMyClass(1);
    
    0 讨论(0)
  • 2021-01-23 11:30

    Wouldn't it just be easier to directly store the object references in your instances var?

    if (!isset(self::$instances[$myparam])) {
        self::$instances[$myParam] = ... new object here ...;
    } else
        return &self::$instances[$myParam];
    }
    

    Just guessing, but it seems that storing your simple integer parameter as an array key to the instances cache would be "cheaper" than storing an sha1 signature of a serialized structure that could potentially NOT be the same even if the object has the same initial parameter.

    0 讨论(0)
提交回复
热议问题