Reputation: 6107
I have two classes, class ClassOne { }
and class ClassTwo {}
. I am getting a string which can be either "One"
or "Two"
.
Instead of using a long switch
statement such as:
switch ($str) {
case "One":
return new ClassOne();
case "Two":
return new ClassTwo();
}
Is there a way I can create an instance using a string, i.e. new Class("Class" . $str);
?
Upvotes: 288
Views: 275536
Reputation: 1111
In case you have a namespace at the top of the file.
import the desired class at the top of the current file:
use \Foo\Bar\MyClass;
// Assign the class namespace to a variable.
$class = MyClass::class;
// Create a new instance
$instance = new $class();
The ::class
will return the entire namespace of the desired class
Upvotes: 1
Reputation: 29897
Yes, you can!
$str = 'One';
$class = 'Class'.$str;
$object = new $class();
When using namespaces, supply the fully qualified name:
$class = '\Foo\Bar\MyClass';
$instance = new $class();
You can also call variable functions & methods dynamically.
$func = 'my_function';
$parameters = ['param2', 'param2'];
$func(...$parameters); // calls my_function() with 2 parameters;
$method = 'doStuff';
$object = new MyClass();
$object->$method(); // calls the MyClass->doStuff() method.
// or in one call
(new MyClass())->$method();
Also PHP can create variables with a string as well, but it's a really bad practice that should be avoided whenever possible. Consider to use arrays instead.
Upvotes: 600
Reputation: 1696
// Way #1
$className = "App\MyClass";
$instance = new $className();
// Way #2
$className = "App\MyClass";
$class = new \ReflectionClass($className);
// Create a new Instance without arguments:
$instance = $class->newInstance();
// Create a new Instance with arguments (need a contructor):
$instance = $class->newInstanceArgs(["Banana", "Apple"]);
Upvotes: 2
Reputation: 54415
You can simply use the following syntax to create a new class (this is handy if you're creating a factory):
$className = $whatever;
$object = new $className;
As an (exceptionally crude) example factory method:
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.');
}
Upvotes: 29
Reputation: 427
Lets say ClassOne
is defined as:
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;
}
}
Using PHP Reflection;
$str = "One";
$className = "Class".$str;
$class = new \ReflectionClass($className);
Create a new Instance:
$instance = $class->newInstanceArgs(["Banana", "Apple")]);
Call a method:
$instance->echoArgOne();
//prints "Banana"
Use a variable as a method:
$method = "echoArgOne";
$instance->$method();
//prints "Banana"
Using Reflection instead of just using the raw string to create an object gives you better control over your object and easier testability (PHPUnit relies heavily on Reflection)
Upvotes: 11
Reputation: 1707
have a look at example 3 from http://www.php.net/manual/en/language.oop5.basic.php
$className = 'Foo';
$instance = new $className(); // Foo()
Upvotes: 15