【问题标题】:Creating PHP class instance with a string使用字符串创建 PHP 类实例
【发布时间】:2011-06-02 11:25:16
【问题描述】:

我有两个班级,class ClassOne { }class ClassTwo {}。我得到一个字符串,它可以是 "One""Two"

而不是使用很长的switch 语句,例如:

switch ($str) {
    case "One":
        return new ClassOne();
    case "Two":
        return new ClassTwo();
}

有没有办法可以使用字符串创建实例,即new Class("Class" . $str);

【问题讨论】:

    标签: php


    【解决方案1】:

    是的,你可以!

    $str = 'One';
    $class = 'Class'.$str;
    $object = new $class();
    

    使用命名空间时,提供fully qualified name:

    $class = '\Foo\Bar\MyClass'; 
    $instance = new $class();
    

    您可以在 php 中做的其他很酷的事情是:
    Variable variables:

    $personCount = 123;
    $varname = 'personCount';
    echo $$varname; // echo's 123
    

    还有可变的函数和方法。

    $func = 'my_function';
    $func('param1'); // calls my_function('param1');
    
    $method = 'doStuff';
    $object = new MyClass();
    $object->$method(); // calls the MyClass->doStuff() method. 
    

    【讨论】:

    • 仅供参考,您不能部分使用变量。例如。 $my_obj = Package\$class_name();。相反,您必须$class_name = "Package\\" . $class_name; $my_obj = new $class_name();
    • 请注意,使用命名空间时,必须提供完整路径:$className = '\Foo\Bar\MyClass';$instance = new $className();
    • 没有勺子...只有 php。
    • 但有一个问题。上述方法可用于创建新的类实例。如果我想静态调用现有类的方法怎么办?我尝试如下:$model = $user_model::find()->All(); 其中$user_model 是包含被调用类的字符串的变量
    • 因为我们正在处理字符串,所以转义反斜杠会更安全:$className = '\\Foo\\Bar\\MyClass'; ... 对吗?
    【解决方案2】:

    您可以简单地使用以下语法来创建一个新类(如果您正在创建 factory,这很方便):

    $className = $whatever;
    $object = new $className;
    

    作为一个(异常粗糙的)示例工厂方法:

    public function &factory($className) {
    
        require_once($className . '.php');
        if(class_exists($className)) return new $className;
    
        die('Cannot create new "' . $className . '" class - includes not found or class unavailable.');
    }
    

    【讨论】:

    • 你不会错过类名和扩展名之间的一个点吗?require_once($className.'php'); -> require_once($className.'.php');
    【解决方案3】:

    看看http://www.php.net/manual/en/language.oop5.basic.php的例子3

    $className = 'Foo';
    $instance = new $className(); // Foo()
    

    【讨论】:

      【解决方案4】:

      假设ClassOne 定义为:

      public class ClassOne
      {
          protected $arg1;
          protected $arg2;
      
          //Contructor
          public function __construct($arg1, $arg2)
          {
              $this->arg1 = $arg1;
              $this->arg2 = $arg2;
          }
      
          public function echoArgOne
          {
              echo $this->arg1;
          }
      
      }
      

      使用 PHP 反射;

      $str = "One";
      $className = "Class".$str;
      $class = new \ReflectionClass($className);
      

      创建一个新实例:

      $instance = $class->newInstanceArgs(["Banana", "Apple")]);
      

      调用方法:

      $instance->echoArgOne();
      //prints "Banana"
      

      使用变量作为方法:

      $method = "echoArgOne";
      $instance->$method();
      
      //prints "Banana"
      

      使用反射而不是仅仅使用原始字符串来创建对象可以让您更好地控制对象并更容易测试(PHPUnit 严重依赖反射)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-07-30
        • 1970-01-01
        • 1970-01-01
        • 2015-07-22
        • 1970-01-01
        相关资源
        最近更新 更多