Use variable's string into class names or other - php

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.

Related

PHP: Specify a variable name for a function call

I need to specify a variable name for a function call (imageapi) and then execute the line.
//For example this is my working code:
require($Path.'/lib/imageapi.php');
new imageapi($ACCESS_TOKEN);
//I want to replace the above lines with:
require($Path.'/lib/imageapi.php');
$provider = 'imageapi';
new $provider($ACCESS_TOKEN);
Is anything like this doable?
Any help is appreciated.
So, your code does work. Just not quite how you think it does (or maybe want/expect it to).
Using variables as class/function names
You can do this, pretty much as you have done. For example:
$getTotal = "array_sum";
$array = [1,2,3,4,5,6,7];
echo $getTotal($array); // 28
You can do the same for a class
class test
{
public static $count = 0;
public $variable1 = "some var";
public function __construct()
{
test::$count++;
}
}
$className = 'test';
new $className;
echo test::$count; // 1
The problem with the above code is that you haven't assigned the class object to a variable and so it is lost to the abyss.
So you need to assign it to a variable:
$myClassInstance = new $className;
echo test::$count; // 2 :: because it's the second time we've called the class
// and whether or not we keep the class in memory the
// static variable is updated; because it is static!
This is helpful if you need to assign a class based off of some dynamic input... But in general terms it's best to stick to the class name!
$anotherClassInstance = new test;
echo test::$count; 3;

Can I pass a type as parameter in PHP?

I'd like to pass (any type, not only PHP's primitives) Type as a function parameter. More like a C++'s template. Is it possible in PHP? imaginary code:
function foo(T a)
{
$output = new T();
//do something.
}
I tried pass the type name as string and then use settype() to the the variable to that type but settype() work only with PHP's primitives types. My goal is actually pass a class type as parameter.
If you want to instantiate something like the above, how about passing the classname as a string and then instantiating it!
function foo($obj_string)
{
$object = new $obj_string();
//do stuff with $object
}
I see that you already accepted an answer, but from the original post, it shows passing an object variable in the function. For those viewing this that need to do it that way, instead of being able to pass the name of the class as a string, you can do it this way:
class Blah
{
public $x = 123;
}
function Foo($b) {
$class = get_class($b);
$object = new $class();
var_dump($object);
}
$aa = new Blah();
Foo($aa);
I realize this is a bit old but I'll leave an answer anyway just in case it's helpful.
If I am going to pass an object as a parameter to another object, it's going to be after I have instantiated the object argument and adjusted the properties to my needs. The following is an example of how I would go about it. I'm using this on PHP 7.4.x and haven't tested on PHP 8.x yet.
Class Blah is the object that will be passed to an instance of Class Bleep after the property $x within the Class Blah object has been changed from 123 to 456.
<?php
class Blah {
public $x = 123;
function __construct() {}
function set_x($x) {
$this->x = $x;
}
function get_x() {
return $this->x;
}
}
class Bleep {
public $object;
function __construct($object) {
$this->object = $object;
}
function get_object_x() {
return $this->object->get_x();
}
}
// Example in use.
$obj_bla = new Blah();
print '<p>On instantiation of <u>$obj_bla</u> as a <strong>Blah</strong> object, $x = '.$obj_bla->get_x().'</p>';
$obj_bla->set_x(456);
print '<p>After using the method <i>set_x()</i> on <u>$obj_bla</u>, $x = '.$obj_bla->get_x().'</p>';
$obj_bleep = new Bleep($obj_bla);
print '<p>Instantiate <u>$obj_bleep</u> as a new <strong>Bleep</strong> object and pass it the instance of <u>$obj_bla</u> then use the <i>get_object_x()</i> method on <u>$obj_bleep</u> to get the value of x from the object that was passed = '.$obj_bleep->get_object_x().'</p>'
?>

String containing function-line. How to echo in other file?

$str = "$obj = new class(); $obj->getSomeFunction();"
Is this possible? I am trying to develop a very dynamic platform to base my website off of.
Anyway to get this working? From a string by "echo $str;" it will make the object and run the function?
Instead of passing an object as a string, just create a new instance of your object. And once you've included a file.. All variables, objects, etc. exist in the file that includes that file.
Edit:
Instead of passing a class as a string, you can create classes dynamically:
<?php
class cc {
function __construct() {
echo 'hi!';
}
}
$type = 'cc';
$obj = new $type; // outputs "hi!"
?>
Alternatively you can use static classes:
<?php
class Foo {
public static function aStaticMethod() {
echo 'hi!';
}
}
Foo::aStaticMethod(); // outputs "hi!"
// or:
$classname = 'Foo';
$classname::aStaticMethod(); // outputs "hi!"
?>
I am in the process of writing my own mvc framework(as an learning project), and needed to dynamically create objects and call a method. I ended up using the reflection api in order to create a new instance of the object and then call the method. in this case i ended up passing an associative array that had two key/value pairs, the class name, and the method I wanted to call. I hope this helps.
$class = $command['class'];
$method = $command['method'];
try{
$reflectorClass = new ReflectionClass($class);
$reflectedInstance = $reflectorClass->newInstance($matches);
} catch (Exception $e) {
exceptionHandler::catchException($e);
}
try {
$reflectorMethod = new ReflectionMethod($reflectedInstance, $method);
$reflectorMethod->invoke($reflectedInstance);
} catch (Exception $e) {
exceptionHandler::catchException($e);
}
In PHP included files are executed when you call include() or require(). They follow variable scope rules and even allow you to return results as if the include was a function like so:
dynamicPlatform.php
<?php
$object = include('createObjAndDoStuff.php');
?>
createObjAndDoStuff.php
<?php
$obj = new class();
$obj->getSomeFunction();
return $obj;
?>
As #zerkms has pointed out, you probably should be using factories.
class Factory {
public static function someclass() {
include_once('./classes/someclass.php'); //Although some discourage the use of *_once() functions
$obj = new someclass();
$obj->getSomeFunction();
return $obj;
}
}
//And to get a new class instance
$object = Singleton::someclass();
Or pseudo-singletons with factories:
class SingletonFactory {
private static $someclass;
public static function someclass() {
if(!self::$someclass) {
include('./classes/someclass.php');
self::$someclass = new someclass();
self::$someclass->getSomeFunction();
}
return self::$someclass;
}
}
What you are searching for is eval but while it will do exactly what you are asking for, it's considered bad solution and can lead to messy code.
You can just include file that contains PHP code, or you can serialize meta data about the actions to be performed and then parse that data.
Depending on what you are trying to achieve, you may be interested in serializing objects in session as well as in Command Pattern (a way to encapsulate set of operations in object(s))

how to store constructed variable name

I wold like to get the following variable name:
class ClassA
{
public $my_name_is = "";
function __construct($tag,$cont = null)
{
$this->my_name_is = ???;
}
}
$OBJ = new ClassA();
echo($OBJ->my_name_is);
This should output
OBJ
Is it possible?
I make tag HTML generator and the id of the tag should be the object name so I must not write it twice:
$input_pwd = new tag("td>input TYPE=PASSWORD.box_lg#input_pwd"); //old way
$input_pwd = new tag("td>input TYPE=PASSWORD.box_lg"); //upgraded way
should generate:
<td><input TYPE=PASSWORD ID='input_pwd' CLASS='box_lg'></td>
No, it's not. An object doesn't know the names of variables that refer to it.
"Needing" this is usually a design flaw.
You can use the magic constant __CLASS__ for retrieving the name of the current class, but there is no way for a class to get the name of the variable which stores the class. You may want to extend your class and still use __CLASS__:
class OBJ extends ClassA {
public function getName() {
return __CLASS__;
}
}
$OBJ = new OBJ();
$OBJ->getName();
See also: http://php.net/manual/en/language.constants.predefined.php
If you simply want to ensure that each reference to the object has a unique ID, you can do that with a static variable.
class ClassA {
public function getUniqueName() {
static $count = 0;
++$count;
return __CLASS__ . '.' . $count;
}
}
$OBJ = new ClassA();
echo($OBJ->getUniqueName();
Every time that method is called, it will give you a different result. If you call it only once on each variable, you should be fine.

instantiate a class from a variable in PHP?

I know this question sounds rather vague so I will make it more clear with an example:
$var = 'bar';
$bar = new {$var}Class('var for __construct()'); //$bar = new barClass('var for __construct()');
This is what I want to do. How would you do it? I could off course use eval() like this:
$var = 'bar';
eval('$bar = new '.$var.'Class(\'var for __construct()\');');
But I'd rather stay away from eval(). Is there any way to do this without eval()?
Put the classname into a variable first:
$classname=$var.'Class';
$bar=new $classname("xyz");
This is often the sort of thing you'll see wrapped up in a Factory pattern.
See Namespaces and dynamic language features for further details.
If You Use Namespaces
In my own findings, I think it's good to mention that you (as far as I can tell) must declare the full namespace path of a class.
MyClass.php
namespace com\company\lib;
class MyClass {
}
index.php
namespace com\company\lib;
//Works fine
$i = new MyClass();
$cname = 'MyClass';
//Errors
//$i = new $cname;
//Works fine
$cname = "com\\company\\lib\\".$cname;
$i = new $cname;
How to pass dynamic constructor parameters too
If you want to pass dynamic constructor parameters to the class, you can use this code:
$reflectionClass = new ReflectionClass($className);
$module = $reflectionClass->newInstanceArgs($arrayOfConstructorParameters);
More information on dynamic classes and parameters
PHP >= 5.6
As of PHP 5.6 you can simplify this even more by using Argument Unpacking:
// The "..." is part of the language and indicates an argument array to unpack.
$module = new $className(...$arrayOfConstructorParameters);
Thanks to DisgruntledGoat for pointing that out.
class Test {
public function yo() {
return 'yoes';
}
}
$var = 'Test';
$obj = new $var();
echo $obj->yo(); //yoes
I would recommend the call_user_func() or call_user_func_arrayphp methods.
You can check them out here (call_user_func_array , call_user_func).
example
class Foo {
static public function test() {
print "Hello world!\n";
}
}
call_user_func('Foo::test');//FOO is the class, test is the method both separated by ::
//or
call_user_func(array('Foo', 'test'));//alternatively you can pass the class and method as an array
If you have arguments you are passing to the method , then use the call_user_func_array() function.
example.
class foo {
function bar($arg, $arg2) {
echo __METHOD__, " got $arg and $arg2\n";
}
}
// Call the $foo->bar() method with 2 arguments
call_user_func_array(array("foo", "bar"), array("three", "four"));
//or
//FOO is the class, bar is the method both separated by ::
call_user_func_array("foo::bar"), array("three", "four"));

Categories