9

I'm trying to step through some PHP code that I did not write, and I have come to an impasse where I can't figure out how to continue.

I have reached as far as a class member function which looks like this:

public function exec($cmd, $args) {

// ... some argument checks here

$result = $this->$cmd($args);

What is this code doing? The value of $cmd is the string "info" so I assumed that it is calling the member function "info"... but when I put trace code at the top of that function, it is not producing any output.

I have also tried using var_dump($this->$cmd) but it prints NULL. Yet the function is being called and is returning a result, so maybe var_dump can't dump functions?

I have found another answer here which suggests that the above shouldn't work anyway. However, it definitely is assigning a complex value to $result which I am able to dump after the call returns.

If it matters, my trace code is below. I'm looking in the Apache error.log file, and it works fine everywhere else so I'm assuming the trace code is good:

$STDERR = fopen('php://stderr', 'w+');
ob_start();
var_dump($some_variable);
$result999 = ob_get_clean();
fwrite($STDERR, "TRACE: $result999\n");
fclose($STDERR);

Update: I have also tried putting an empty return statement as the first line of the "info" function, but $result still gets assigned the same value as before...

Community
  • 1
  • 1
Michael
  • 9,060
  • 14
  • 61
  • 123
  • 1
    As you said it just calls the method with the name of value of `$cmd` and `$args` are the arguments, pretty straightforward! – Rizier123 Apr 20 '15 at 23:53
  • 1
    @Rizier123 How could this to be useful? – SaidbakR Apr 20 '15 at 23:55
  • @Rizier123 That's what I thought, but anything I do in that method (such as putting trace output) doesn't appear to happen. – Michael Apr 20 '15 at 23:55
  • @Michael Do you have output buffering on? – Rizier123 Apr 20 '15 at 23:56
  • @Rizier123 my trace code is going to stderr and is being close immediately - should flush any buffers, right? In any case, if I put trace code on either side of the call, I see the output from both, but not from the trace in the presumed target of the call. – Michael Apr 20 '15 at 23:57
  • I'd strongly urge you to use a PHP IDE and single step through the code, if at all possible. See my response below. It also contains links to some PHP debuggers, including [XDebug](http://xdebug.org/). – FoggyDay Apr 21 '15 at 01:19
  • If u are saying `The value of $cmd is the string "info" ` then definitely it should be a method named `info` inside current class or the any of parent class – Umair Ayub Apr 21 '15 at 04:22
  • 1
    If the class in question is a controller or command like class, odds are good it's calling the "info" method on a child class somewhere. – Erik Apr 21 '15 at 15:15

1 Answers1

4

As you know, $result and $args are variables.

As you can guess,$this and $cmd are ALSO variables.

$this refers to the class instance. For example, if myClass.a, then "a" can be referenced by any "myClass" method as "$this->a".

PHP, unlike many other object oriented languges, also supports member names as variables. It supports "Variable variables'. That's what $cmd is: whatever value of "cmd" you pass as a parameter, the function expects to find a matching method.

You can find more details here:

http://php.net/manual/en/functions.variable-functions.php

How to explain 'this' keyword in a best and simple way?

As to why you're not hitting your trace statement - that's simply a matter of debugging:

  • Does "$cmd" translate to the name you think it does?
  • Does your class have such a method?
  • Are there any other classes that might be conflicting?
  • Etc

I would fire up your favorite PHP debugger and single-step through the code, if at all possible.

Here are some IDEs that support PHP debugging:

http://www.sitepoint.com/best-php-ide-2014-survey-results/

Community
  • 1
  • 1
FoggyDay
  • 11,962
  • 4
  • 34
  • 48
  • thanks for confirming that this call really is doing what i thought it should be doing. turns out it was calling the "info" function, but in a derived class, no the base class. i'll file this under "Are there any other classes that might be conflicting". – Michael Apr 21 '15 at 15:34