3

I have a class from which I want to call a function, but the instantiated class variable is taken from a string.

class Myclass
{
 public function myFunction($param1,$param2) {
  return 'blah';
 }
}

I am trying the following but it doesn't work. Errors from log file below.

$myclass='myclass';
${$myclass}=new ucfirst($myclass);
$args=array($stringvar,1);
$retval=call_user_func_array(array(${$myclass}, 'myFunction'), $args);

What am I doing wrong ?

Errors :

PHP Warning:  call_user_func_array() expects parameter 1 to be a valid callback, first array member is not a valid class name or object in file.php on line 100
PHP Notice:  Undefined variable: myclass in file.php on line 134
PHP Fatal error:  Call to a member function myFunction() on a non-object in file.php on line 134
4
  • 1
    Why are you doing this... such a mess :D Commented Apr 10, 2014 at 21:53
  • Any help welcome. I've explained a bit more below. Commented Apr 10, 2014 at 22:18
  • I appreciate that you are after an answer to the problem you have. May i ask, what was the original problem that you were trying to solve? I keep remembering this 'maxim': it is hard to remember, when you are up to your as in crocodiles, that the original intention was to drain the swamp. Your code, by its nature, will be hard to maintain and change in the future. Commented Apr 11, 2014 at 1:29
  • @RyanVincent my man, this is what I meant :) Commented Apr 11, 2014 at 6:44

1 Answer 1

2

You're overcomplicating it a bit with the extra ${} bracketing on the class reference.

$myclass='myCLaSs';
$myObject = new $myclass();
$retval = $myObject->myFunction($stringvar, 1);

Or if you need to use call_user_func_array:

$args=array($stringvar,1);
$retval=call_user_func_array(array($myObject, 'myFunction'), $args);

When you use the ${} bracketing, you are referencing variables by a variable name. For example:

$myVariable = "A";
$aVariableThatIsHoldingAVariableName = "myVariable";
echo ${$aVariableThatIsHoldingAVariableName}; // outputs "A".

Applying this to your code shows the following logic happening:

Set the variable $myclass equal to the string 'myclass'

$myclass='myclass';

Set the variable ${$myclass}:

This gets the value of the variable $myclass ('myclass') and uses that as the variable name. In other words, the following variable name resolution happens: ${$myclass} => ${'myclass'} => $myclass.

So this line sets $myclass to a new Myclass(); object:

${$myclass}=new ucfirst($myclass);

The first parameter to call_user_func_array is a callable (See https://www.php.net/manual/en/language.types.callable.php). The callback it looks like you are trying to reference here is Type 3: array($object, $method). But the same variable resolution happens. Now, ${$myclass} is going to resolve differently, because the value of $myclass is a Myclass Object. Variable names have to be strings, not objects (obviously), so ${Myclass Object} is totally invalid.

$args=array($stringvar,1);
$retval=call_user_func_array(array(${$myclass}, 'myFunction'), $args);

But since $myclass at that point is an object already, you can just do the following (as mentioned initially above):

$retval=call_user_func_array(array($myclass, 'myFunction'), $args);
Sign up to request clarification or add additional context in comments.

8 Comments

I forgot to say that the ${$myclass} is necessary because I'm taking the class name as a string from a DB table.
In the example I've included, $myclass is a string. You can reference it directly in the new () call.
I've edited my answer to include an example of how the ${} bracketing syntax works.
Let's say that I have an array from which I get the various class names which I want to instantiate. Whenever I want to reference these, I have to get the string (myclass, myclass1, myclassn). Am I too tired to understand how to apply this or should I look for a way to store the objects somewhere ?
Too tired is my bet :) If you dont want to create an object and just want to call the functions on the class (maybe they are static for example), you can pass the string directly in as the class name to the callback parameter for call_user_func_array, e.g., with $myclass being the variable with the class name, call_user_func_array($myclass, 'myFunction'), $args). Copy and paste this code and your class definition in to a test script and play around with it, might help shake the cobwebs off :)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.