代码之家  ›  专栏  ›  技术社区  ›  Val Délia

用参数初始化php对象,而其构造函数不接受任何参数(单例模式)

  •  1
  • Val Délia  · 技术社区  · 8 年前

    我只有基本的PHP知识,正在阅读“PHP 5 E-commerce Development.pdf”一书,该书的源代码可以在这里找到: https://github.com/rogeriorps/books_demo .

    public function storeObject( $object, $key )
    {
    
        if( strpos( $object, 'database' ) !== false ) {
             $object = str_replace( '.database', 'database', $object);
             require_once('databaseobjects/' . $object
             . '.database.class.php');
       } else {
         require_once('objects/' . $object . '.class.php');
       }
       self::$objects[ $key ] = new $object( self::$instance );
    
    }
    

    例如,对于身份验证类,构造函数是空的:public

    function __construct() { }
    

    因此它需要身份验证。班然后创建一个新的身份验证(self:$instance)。。。在构造函数上没有参数!

    这怎么可能?困扰我的是这个词的用法 ,它通常调用空构造函数,并突然为其提供参数。

    欢迎您进一步解释这一切的工作原理,谢谢:-)

    2 回复  |  直到 8 年前
        1
  •  0
  •   e_i_pi    8 年前

    PHP是一种非常宽容的语言,因为某些语言构造和实践没有像其他编程语言那样严格应用。

    如果您提供 更多 参数,无论该方法是构造函数还是正则方法。如下所示,输出“你好,世界!”很好:

    error_reporting(E_ALL);
    ini_set('display_errors', TRUE);
    ini_set('display_startup_errors', TRUE);
    
    class Foo
    {
        public function __construct() {}
        public function hello($input) { return 'Hello ' . $input . '!'; }
    }
    
    $foo = new Foo(123);
    echo $foo->hello('World', 'Universe');
    
        2
  •  0
  •   marc_s MisterSmith    8 年前

    我还在努力理解你的问题是什么。

    虽然源代码的链接很好,但您能否更具体地说明您在谈论哪些文件。

    这也是你指的那一行吗

      //I will call this class 'Singleton',as I have no idea what it's name is.
     class Singleton
     {
    
      protected static $instance;
    
      protected static $objects = [];
      ...
      public function storeObject( $object, $key )
      {
           ...
           self::$objects[ $key ] = new $object( self::$instance ); //<--- this line
           ...
      }
    }
    

    然后你说你有一个这样的类(有一个空构造函数)

    class authenticate{  
        public function __construct() {} //empty
    }
    

    如果我正确地理解了这一点,那么在这种情况下,额外的参数将被忽略。但是,请考虑使用另一个可以存储在中的类 Singleton

    class user{  
        //instance of singleton
        protected $singleton;
    
        public function __construct( $Singleton ) {
            $this->singleton = $Singleton;
        } 
    }
    

    所以在这种情况下,同一个类 Singlton 调用另一个接受 辛尔顿 .

    多态性是为不同类型的实体提供单一接口。

    就我个人而言,我更希望他们有一个这样的界面。我会尽力解释。一个接口可以被看作是一个契约,它保证实现它的任何类都将以特定的顺序公开一些带有给定参数的公共方法。

    例如

      interface StorableObjectInterface{
    
          //interfaces do not contain a method body, only the definition
          //here I am using type hinting to tell it to only accept instance of Singleton
          public function __construct( Singleton $Singleton );
    
      }
    

    因此,这需要实现该接口的每个类都需要一个singleton实例作为其构造函数的第一个参数。他们仍然可以忽视这一点,但这应该是一项合同义务 独生子女 (国际海事组织)。

    那么你的课看起来像这样

    class authenticate implements StorableObjectInterface{  
        public function __construct(Singleton $Singleton) {} // still empty
    }
    
    class user implements StorableObjectInterface{  
        //instance of singlton
        protected $singlton;
    
        public function __construct(Singleton $Singleton ) {
            $this->singlton = $Singleton;
        } 
    }
    

    $Object

      public function storeObject( $object, $key )
      {
           ...
           if( is_a( $object, StorableObjectInterface::class ){
               self::$objects[ $key ] = new $object( self::$instance );
           }else{
                //throw exception
               throw new Exception("Class {$object} must implement interface ".StorableObjectInterface::class); 
            }
           ...
      }
    

    这就是我要做的。。。不清楚你是在使用别人的系统,还是在创建自己的系统。

    所以你可能想知道为什么要经历这些麻烦,我给你举个例子。

    稍后,您可能需要类似于中配置文件的路径 authenticate

    所以你在课堂上看到这个(我们会忘记我们知道什么)

    class authenticate{  
        public function __construct() {} // still empty
    }
    

    因此,您可以将其固定在构造函数中(假设您在Singlton之外的某个地方使用这个类)。所以你改变它。

    class authenticate{ 
        protected $config; 
        public function __construct($configFile = null) {
            if( $configFile )
                $this->config = include $configFile;
        }
    }
    
    //then you call it for you new code
    
    $z = new authenticate('passwordsAndStuf.php');
    

    这一切都很好,直到 独生子女 使用其自身的实例调用该构造函数。现在一切都爆炸了。主要问题是 证明…是真实的 没有办法断定这会发生。因此,通过添加一个接口,我们与之签订了合同 Singleton any class implementing this interface will always accept an instance of

    希望这有意义。

    推荐文章