【问题标题】:Can I instantiate a PHP class inside another class?我可以在另一个类中实例化一个 PHP 类吗?
【发布时间】:2010-12-07 16:13:42
【问题描述】:

我想知道是否允许在另一个类中创建一个类的实例。

或者,我是否必须在外部创建它,然后通过构造函数将其传入?但是我会在不知道是否需要它的情况下创建它。

示例(数据库类):

class some{

if(.....){
include SITE_ROOT . 'applicatie/' . 'db.class.php';
$db=new db

【问题讨论】:

    标签: php class oop object


    【解决方案1】:

    我现在才看到这个,我想添加我的评论。它可能对任何人都有好处。有人听说过 php 特性吗?尽管traits不会导入另一个类,而只是将一个特征导入另一个类。因此,您可以拥有一个主类而不是尝试导入多个类,而子类将充当特征,使您可以在主/父类中使用它们

    【讨论】:

    • 特征基本上是方法的复制/粘贴。但问题是关于创建实例,而不是继承。 PHP 长期以来一直支持abstract 类和父/子继承。在大多数情况下,特征在这里并不是一个好的解决方案
    【解决方案2】:

    (编辑)好的,您尝试完成的问题和示例令人困惑。 从您的示例看来,您正试图在另一个类中定义一个类。

    它的正确名称是 NESTED CLASS 并且在 PHP 中是不可能的。 因此,对于您的示例,答案是“否”。反正不在 PHP 中。其他语言将允许“嵌套类”。 Java 就是一个例子。

    例如,这在 PHP 中不起作用

    class outer_class{
        class inner_class{
            ...
        }
        ...
    }
    

    现在的问题是在另一个类中创建一个类的实例。

    对此,答案是“是”,您可以在“类”中实例化一个“对象”。我们一直这样做。

    class simple_class{
    
        protected $instanceOfOtherClass;
    
        public function instanciateObject_KeepingAReferenceToIt(){
            // create an instance of OtherClass and associate it to $this->instanceOfOtherClass
            $this->instanceOfOtherClass = new OtherClass();
        }
    
        public function instanciateObject_Without_KeepingAReferenceToIt(){
            // create an instance of OtherClass and return it
            return new OtherClass();
        }
    }
    

    一个类甚至可以实例化自己。这就是著名的单身人士和许多其他Creational patterns 所做的事情。可悲的是,有些人认为知道dependency injection 意味着他们再也不会在方法中调用 NEW。错了。

    它有助于理解类和对象之间的区别。 class 是用于创建对象的可扩展程序代码模板。 object 指的是类的特定实例。

    【讨论】:

      【解决方案3】:

      你不能在另一个类中定义一个类。您应该在类之外包含具有其他类的文件。在您的情况下,这将为您提供两个顶级课程dbsome。现在在some 的构造函数中,您可以决定创建db 的实例。例如:

      include SITE_ROOT . 'applicatie/' . 'db.class.php';
      
      class some {
      
          public function __construct() {
              if (...) {
                  $this->db = new db;
              }
          }
      
      }
      

      【讨论】:

      • 我建议使用require 而不是include
      • 这看起来也是利用依赖注入设计模式的好情况。
      • @rink.attendant.6 require_once 更好:D
      【解决方案4】:

      这在 PHP 7 中可以使用Anonymous classes

      参见the docs的示例:

      class Outer
      {
          private $prop = 1;
          protected $prop2 = 2;
      
          protected function func1()
          {
              return 3;
          }
      
          public function func2()
          {
              return new class($this->prop) extends Outer {
                  private $prop3;
      
                  public function __construct($prop)
                  {
                      $this->prop3 = $prop;
                  }
      
                  public function func3()
                  {
                      return $this->prop2 + $this->prop3 + $this->func1();
                  }
              };
          }
      }
      
      echo (new Outer)->func2()->func3();
      // Output: 6
      

      这是一个简单的例子,展示了匿名类的用法,但不是来自一个类:

      // Pre PHP 7 code
      class Logger
      {
          public function log($msg)
          {
              echo $msg;
          }
      }
      
      $util->setLogger(new Logger());
      
      // PHP 7+ code
      $util->setLogger(new class {
          public function log($msg)
          {
              echo $msg;
          }
      });
      

      【讨论】:

      • func3 在“外部”类实例中是否全局不可用?
      • @ChrisO 不。 print_r(get_class_methods('Outer')); 打印 Array( [0] => func2 )
      • 那太糟糕了,但是,无论如何,它是一些东西。多一点语法,谢谢。 :)
      【解决方案5】:

      人们说可以“在一个类中创建一个类”似乎意味着可以在一个类中创建一个对象/实例。我没有在另一个类定义中看到实际类定义的示例,如下所示:

      class myClass{
      
          class myNestedClass{
      
          }
      
      }
      
      /* THIS IS NOT ALLOWED AND SO IT WON'T WORK */
      

      既然问题是'是否有可能创建一个类内部另一个类',我现在只能假设这是不可能的。

      【讨论】:

      • 虽然有其他编程语言的示例,但嵌套类会派上用场:docs.oracle.com/javase/tutorial/java/javaOO/nested.html
      • 那不是 OP 的问题。问题询问是否可以“在另一个类中创建一个类的实例”。因此,所有解决在 PHP 中的类中创建类的“答案”似乎都是错误的,并且与问题无关。
      • @McAuley:事实上这是 OP 的问题。给出此答案后,OP 已编辑问题。
      【解决方案6】:

      不,这是不可能的。嵌套类和聚合对象是不同的机制。实际上,嵌套类意味着嵌套类名。嵌套在 B 类中的 A 类将被命名为“B\A”(?)。从 v5.3 开始,您可以在命名空间中嵌套类名(和其他一些名称)。

      【讨论】:

        【解决方案7】:

        我只是想指出,可以在另一个类定义中动态加载一个类定义。

        Lukas 是对的,我们不能在另一个类中定义一个类,但是我们可以动态地 include() 或 require() 它们,因为包含文件中定义的每个函数和类都将具有全局范围。如果您需要动态加载类或函数,只需将文件包含在类的函数之一中即可。你可以这样做:

        function some()
        {
            require('db.php');
            $db = new Db();
            ...
        }
        

        http://php.net/manual/en/function.include.php

        【讨论】:

        • 对于动态类加载,我建议使用require_onceinclude_once - 这样您将确保您没有多次包含/需要它:)
        • 在这种情况下,您应该使用“include_once”,因为当该文件(定义函数的位置)包含到系统中时,“require”将调用。但您可以在子例程中使用 include 或 include_once。当它的指针进入那个子程序时它会执行
        【解决方案8】:

        在 PHP 的另一个类中创建一个类是不可能的。 在另一个对象中创建一个对象(一个类的实例)是另一回事。

        【讨论】:

        • 你会如何做类似的事情?
        猜你喜欢
        • 2012-07-07
        • 1970-01-01
        • 2011-03-07
        • 2015-08-26
        • 1970-01-01
        • 2020-11-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多