Створення екземпляра класу PHP за допомогою рядка


223

У мене два класи, class ClassOne { }і class ClassTwo {}. Я отримую рядок, який може бути "One"або "Two".

Замість використання довгого switchтвердження, наприклад:

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

Чи є спосіб створити екземпляр за допомогою рядка, тобто new Class("Class" . $str);?

Відповіді:


484

Так, ти можеш!

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

Використовуючи простори імен, введіть повністю кваліфіковане ім’я :

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

Інші цікаві речі, які ви можете зробити в php, це:
Змінні змінні :

$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. 

1
Дякую за приклади!
Джоель

28
FYI, ви не можете частково використовувати змінну. напр. $my_obj = Package\$class_name();. Натомість ви повинні$class_name = "Package\\" . $class_name; $my_obj = new $class_name();
Бірла

14
Зверніть увагу на те, що при використанні просторів імен ви повинні надати повний шлях:$className = '\Foo\Bar\MyClass'; $instance = new $className();
Giel Berkers

5
Ложки немає ... тільки php.
Гіпертекст капітана

4
але одне питання. Описаний вище метод може бути використаний для створення нового екземпляра класу. Що робити, якщо я хочу статично викликати метод існуючого класу? Я спробував так: $model = $user_model::find()->All(); де $user_modelзнаходиться змінна, що містить рядок, який називається
Ramesh Pareek

22

Ви можете просто використовувати наступний синтаксис для створення нового класу (це зручно, якщо ви створюєте фабрику ):

$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.');
}

1
Ви не пропустите крапку між назвою класу та розширенням? require_once($className.'php'); ->require_once($className.'.php');
J Quest


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 Reflection;

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

Створіть новий екземпляр:

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

Виклик методу:

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

Використовуйте змінну як метод:

$method = "echoArgOne";
$instance->$method();

//prints "Banana"

Використання Reflection замість простого використання необробленого рядка для створення об'єкта дає вам кращий контроль над вашим об'єктом і легше перевірити (PHPUnit сильно покладається на Reflection)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.