Instantiate a new class with the value of a string - php

This might be a very stupid question :P But I found this really interessting:
class SomeClass{
var $var = "this is some text";
function echoVar($name){
echo $this->{$name};
}
}
$class = new SomeClass()
$class->echoVar("var") // will echo "this is some text"
Can I do somethign similar, can I take the value of a string and instantiate a new class with that name? If not, any "almost" solutions?
Thanks

Yes. You can dynamically instantiate classes in PHP. Like this:
$className = 'SomeClass';
$myInstance = new $className();

If your string 'dave' is in $name, you can use it with $$name
$name = 'dave';
$$name = new SomeClass();
$dave->echoVar('var');

Related

How to use variable name to call a class?

I want to use a variable (string value) to call a Class. Can I do it ? I search for PHP ReflectionClass but I do not know how to use a method from Reflection Result. Like this:
foreach($menuTypes as $key => $type){
if($key != 'Link'){
$class = new \ReflectionClass('\App\Models\\' . $key);
//Now $class is a ReflectionClass Object
//Example: $key now is "Product"
//I'm fail here and cannot call the method get() of
//the class Product
$data[strtolower($key) . '._items'] = $class->get();
}
}
Without ReflectionClass:
$instance = new $className();
With ReflectionClass: use the ReflectionClass::newInstance() method:
$instance = (new \ReflectionClass($className))->newInstance();
I found one like this
$str = "ClassName";
$class = $str;
$object = new $class();
You can use directly like below
$class = new $key();
$data[strtolower($key) . '._items'] = $class->get();
The risk is that the class doesn't exist. So it's better to check before instantiating.
With php's class_exists method
Php has a built-in method to check if the class exists.
$className = 'Foo';
if (!class_exists($className)) {
throw new Exception('Class does not exist');
}
$foo = new $className;
With try/catch with rethrow
A nice approach is trying and catching if it goes wrong.
$className = 'Foo';
try {
$foo = new $className;
}
catch (Exception $e) {
throw new MyClassNotFoundException($e);
}
$foo->bar();

Use string as object name in PHP

I want to use a string as an object name in PHP.
For example:
$name = 'utils';
$obj = new $name();
$utils->test();
So I want to be able to call the object by the name of a string (since I don't know the class names beforehand).
How would I be able to do this?
Try the following:
$name = 'utils';
$$name = new $name();
See Namespaces and dynamic language features ΒΆ for more information
Class Foo {
function bar(){
return 'text';
}
}
$name = 'Foo';
$obj = new $name();
echo $obj->bar();

Use variable's string into class names or other

I want to use variables inside class names.
For example, let's set a variable named $var to "index2".
Now I want to print index2 inside a class name like this:
controller_index2, but instead of doing it manually, I can just print the var name there like this:
controller_$var;
but I assume that's a syntax error.
How can I do this?
function __construct()
{
$this->_section = self::path();
new Controller_{$this->_section};
}
It's a hideous hack, but:
php > class foo { function x_1() { echo 'success'; } };
php > $x = new foo;
php > $one = 1;
php > $x->{"x_$one"}();
^^^^^^^^^^^^
success
Instead of trying to build a method name on-the-fly as a string, an array of methods may be more suitable. Then you just use your variables as the array's key.
Echo it as a string in double quotes.
echo "controller_{$var}";
Try this (based on your code in the OP):
function __construct()
{
$this->_section = self::path();
$controller_name = "Controller_{$this->_section}";
$controller = new $controller_name;
}
You can do this.... follow this syntax
function __construct()
{
$this->_section = self::path();
$classname = "Controller_".$this->_section;
$instance = new $classname();
}
Another way to create an object from a string definition is to use ReflectionClass
$classname = "Controller_".$this->_section;
$reflector = new ReflectionClass($classname);
and if your class name has no constructor arguments
$obj = $reflector->newInstance();
of if you need to pass arguments to the constructor you can use either
$obj = $reflector->newInstance($arg1, $arg2);
or if you have your arguments in an array
$obj = $reflector->newInstanceArgs($argArray);
try this:
$name = "controller_$var";
echo $this->$name;
just to add on the previous answers, if you're trying to declare new classes with variable names but all the construction parameters are the same and you are treating the instanced object all alike maybe you don't need different classes but just different instances of the same.

PHP analog to C++ member pointers?

Does PHP have something similar to C++ member pointers? I want to use a member of a PHP object, whose name (the member's, not the object's) I only know at runtime. For example:
$object = new stdClass();
$object->NewMember = "value";
$member = 'NewMember';
// I don't know whether this is valid PHP,
// but you get what I'm trying to do.
echo $object->$member;
<?php
class Test
{
public $foo = 'bar';
}
$var = 'foo';
$test = new Test();
echo $test->$var;
Edit: after your update, yes, that will work.
You can use variables in member calls.
$methodName = 'some_method';
$myObj->$methodName($param);
Not sure if this will work for what you want.
In the following code I'm setting the $memberToGet at runtime:
class Person
{
public $foo = 'default-foo';
public $bar = 'default-bar';
}
$p = new Person();
$memberToGet = 'foo';
print "The Person's $memberToGet is [" . $p->$memberToGet . "]\n";
$memberToGet = 'bar';
print "The Person's $memberToGet is [" . $p->$memberToGet . "]\n";
No, PHP doesn't support (member) pointers. However you could use Reflection API.
class MyClass {
public function doSth($arg1, $arg2) { ... }
public static function doSthElse($arg1) { ... }
}
$ref = new ReflectionMethod('MyClass', 'doSth');
$ref->invokeArgs(new MyClass(), array('arg1', 'arg2'));
$ref = new ReflectionMethod('MyClass', 'doSthElse');
$ref->invokeArgs(null, array('arg1'));
As you can see in other answers you could also write:
class MyClass { ... }
$method = 'doSth';
$obj = new MyClass();
$obj->$method('arg1', 'arg2');
But I really don't recommend that way. It's tricky, obscure and much harder to debug and maintain.
By passing $this as a variable by reference, you can access members of that class.

How to "invoke" a class instance in PHP?

is there any possibility to "invoke" a class instance by a string representation?
In this case i would expect code to look like this:
class MyClass {
public $attribute;
}
$obj = getInstanceOf( "MyClass"); //$obj is now an instance of MyClass
$obj->attribute = "Hello World";
I think this must be possible, as PHP's SoapClient accepts a list of classMappings which is used to map a WSDL element to a PHP Class. But how is the SoapClient "invoking" the class instances?
$class = 'MyClass';
$instance = new $class;
However, if your class' constructor accepts a variable number of arguments, and you hold those arguments in an array (sort of call_user_func_array), you have to use reflection:
$class = new ReflectionClass('MyClass');
$args = array('foo', 'bar');
$instance = $class->newInstanceArgs($args);
There is also ReflectionClass::newInstance, but it does the same thing as the first option above.
Reference:
Object instantiation
ReflectionClass::newInstanceArgs()
ReflectionClass::newInstance()
The other answers will work in PHP <= 5.5, but this task gets a lot easier in PHP 5.6 where you don't even have to use reflection. Just do:
<?php
class MyClass
{
public function __construct($var1, $var2)
{}
}
$class = "MyClass";
$args = ['someValue', 'someOtherValue'];
// Here's the magic
$instance = new $class(...$args);
If the number of arguments needed by the constructor is known and constant, you can (as others have suggested) do this:
$className = 'MyClass';
$obj = new $className($arg1, $arg2, etc.);
$obj->attribute = "Hello World";
As an alternative you could use Reflection. This also means you can provide an array of constructor arguments if you don't know how many you will need.
<?php
$rf = new ReflectionClass('MyClass');
$obj = $rf->newInstanceArgs($arrayOfArguments);
$obj->attribute = "Hello World";

Categories