102

Is it possible in PHP to instantiate an object from the name of a class, if the class name is stored in a string?

karim79
  • 339,989
  • 67
  • 413
  • 406
user135295
  • 1,023
  • 2
  • 7
  • 5

5 Answers5

171

Yep, definitely.

$className = 'MyClass';
$object = new $className; 
brianreavis
  • 11,562
  • 3
  • 43
  • 50
  • 3
    In fact it is not so evident. I know that in Java it is a thing called reflection, but this is very simple compared to that. – Bartis Áron May 03 '14 at 20:34
  • 6
    If clsss is in namespace, use this $class = 'PrintData\\' . $class; return new $class(); – Dariux Jan 23 '15 at 09:20
  • 3
    Also, as the PHP doc states, if the class you want to instantiate is within a namespace then you must specify the FQN (Fully Qualified Name). For example, I myself was within a namespace of "App\Http\Controllers" and I had a string $string = 'App\Models\Task'; I thought that if I tried to instantiate the string it would break but actually, you don't need to append a \ at the beginning. – Matt Kieran Mar 23 '18 at 12:41
  • I'm currently using this for PHPUnit Tests, it is usefull to test a whole bunch of (similar) objects all at once by letting each one implement an interface, and in my function test_setup(string $classname) i can just return a new instance as long as each one has implemented the interface. – clockw0rk Aug 20 '20 at 13:56
  • @MattKieran it was kinda difficult to spot your comment and I went allover the internet trying to find the solution only to comeback here and spot your comment, I think it should be an answer in itself or at least included in the answer for better visibility. thank you for the hint tho – Majd Apr 08 '22 at 12:19
13

if your class need arguments you should do this:

class Foo 
{
   public function __construct($bar)
   {
      echo $bar; 
   }
}

$name = 'Foo';
$args = 'bar';
$ref = new ReflectionClass($name);
$obj = $ref->newInstanceArgs(array($args));
josef
  • 872
  • 9
  • 8
9

Yes it is:

<?php

$type = 'cc';
$obj = new $type; // outputs "hi!"

class cc {
    function __construct() {
        echo 'hi!';
    }
}

?>
Mr. Smith
  • 5,489
  • 11
  • 44
  • 60
5

Static too:

$class = 'foo';
return $class::getId();
Andrew Atkinson
  • 4,103
  • 5
  • 44
  • 48
  • This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. - [From Review](/review/low-quality-posts/16691553) – Blackbam Jul 12 '17 at 20:13
  • 1
    @Blackbam relevant related supplementary answer. Please only comment if it is useful. – Andrew Atkinson Jul 13 '17 at 23:21
  • True it works basically anyway a little bit of explanation of your answer would be nice. The question was "can PHP instantiate an object" but access to a static member function is not an object access. – Blackbam Jul 14 '17 at 00:51
0

You can do some dynamic invocation by storing your classname(s) / methods in a storage such as a database. Assuming that the class is resilient for errors.

sample table my_table
    classNameCol |  methodNameCol | dynamic_sql
    class1 | method1 |  'select * tablex where .... '
    class1 | method2  |  'select * complex_query where .... '
    class2 | method1  |  empty use default implementation

etc.. Then in your code using the strings returned by the database for classes and methods names. you can even store sql queries for your classes, the level of automation if up to your imagination.

$myRecordSet  = $wpdb->get_results('select * from my my_table')

if ($myRecordSet) {
 foreach ($myRecordSet   as $currentRecord) {
   $obj =  new $currentRecord->classNameCol;
   $obj->sql_txt = $currentRecord->dynamic_sql;
   $obj->{currentRecord->methodNameCol}();
}
}

I use this method to create REST web services.

Hugo R
  • 2,613
  • 1
  • 14
  • 6
  • 1
    And if I manage to inject your database with any number of classes and methods I've owned your entire rest API .... Kudos! Please do NOT use this code, it's very dangerous! – James Kipling Aug 18 '20 at 09:05