PHP: Specify a variable name for a function call - php

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;

Related

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.

Accessing class constant trough property doesn't work

Example:
class LOL{
const
FOO = 1;
}
$x = new LOL;
$arr = array('x' => $x);
echo $x::FOO; // works
echo $arr['x']::FOO; // works too
But if I make my class instance a property, I can't access the constant anymore:
class WWW{
protected $lol;
public function __construct($lol){
$this->lol= $lol;
}
public function doSMth(){
echo $this->lol::FOO; // fail. parse error.. wtf
}
}
$w = new WWW;
$w->doSMth();
:(
I know I can just do echo LOL::FOO, but what if the class name is unknown? From that position I only have access to that object/property, and I really don't want that WWW class to be "aware" of other classes and their names. It should just work with the given object
You can do this much easier by assigning the lol property to a local variable, like so:
public function doSMth(){
$lol = $this->lol;
echo $lol::FOO;
}
This is still silly, but prevents having to use reflections.
If the class name is not known, you can use ReflectionClass to get the constant. Note you must be using PHP 5 or greater.
Example:
$c = new ReflectionClass($this->lol);
echo $c->getConstant('FOO'); // 1
As of PHP 5.3.0, you can access the constant via a variable containing the class name:
$name = get_class($this->lol);
echo $name::FOO; // 1
For more info, see Scope Resolution Operator - PHP
$lol = &$this->lol;
echo $lol::FOO;
..
unset($lol);

How to pass method argument to class property?

I am trying to create properties based on the method arguments. For example:
class Test{
public function newProperty($prop1,$prop2){
//I want to create $this->argu1 and $this->argu2 after calling newProperty method.
}
}
$test=new Test();
$test->newProperty('argu1','argu2')
Is this possible? Thanks for any helps.
as simple as:
$this->$prop1 = 'whatever';
suppose you wanted to handle an undefined number of arguments, you could use:
foreach(func_get_args() as $arg) {
$this->$arg = 'some init value';
}
On the other hand, all this is quite unnecessary as all these properties will be public and thus:
$test->argu1 = 'whatever';
would do exactly the same.
Try this:
class Test{
private argu1 = '';
private argu2 = '';
public function newProperty($argu1,$argu2){
//This is a great place to check if the values supplied fit any rules.
//If they are out of bounds, set a more appropriate value.
$this->prop1 = $argu1;
$this->prop2 = $argu2;
}
}
I'm a little unclear from the question if the class properties should be named $prop or $argu. Please let me know if I have them backwards.

PHP string to object name

Ok I have a string...
$a_string = "Product";
and I want to use this string in a call to a object like this:
$this->$a_string->some_function();
How the dickens do I dynamically call that object?
(don't think Im on php 5 mind)
So you the code you want to use would be:
$a_string = "Product";
$this->$a_string->some_function();
This code implies a few things. A class called Product with the method some_function(). $this has special meaning, and is only valid inside a class definition. So another class would have a member of Product class.
So to make your code legal, here's the code.
class Product {
public function some_function() {
print "I just printed Product->some_function()!";
}
}
class AnotherClass {
public $Product;
function __construct() {
$this->Product = new Product();
}
public function callSomeCode() {
// Here's your code!
$a_string = "Product";
$this->$a_string->some_function();
}
}
Then you can call it with this:
$MyInstanceOfAnotherClass = new AnotherClass();
$MyInstanceOfAnotherClass->callSomeCode();
I seem to have read this question differently from everyone else who's responded, but are you trying to use variable variables?
In the code you've shown, it looks like you're trying to call a function from string itself. My guess is that you want to call a function from a class with the same name as that string, in this case "Product."
This is what that would look like:
$this->Product->some_function();
It seems you might instead be looking for something like this:
$Product = new Product();
$Product->some_function();
EDIT: You need to be running PHP5 in order to do any method chaining. After that, what you have is perfectly legal.
Let's see if I got your intentions correctly...
$some_obj=$this->$a_string;
$some_obj->some_function();
So you've got an object, and one of it's properties (called "Product") is another object which has a method called some_function().
This works for me (in PHP5.3):
<?PHP
class Foo {
var $bar;
}
class Bar {
function some_func(){
echo "hello!\n";
}
}
$f = new Foo();
$f->bar = new Bar();
$str = 'bar';
$f->$str->some_func(); //echos "hello!"
I don't have PHP4 around, but if it doesn't work there, you might need to use call_user_func() (or call_user_func_array() if you need to pass arguments to some_function()

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