1

I am trying to call a method stored as $_auto, but it will not work.

<?php
    class Index {
        private $_auto;

        public function __construct() {
            $this->_auto = "index";
            $this->_auto();
        }

        public function index() {
            echo "index";
        }
    }

    $index = new Index();
?>
David Fox
  • 10,603
  • 9
  • 50
  • 80
  • possible duplicate of [Lambda Functions in PHP aren't Logical](http://stackoverflow.com/questions/2080248/lambda-functions-in-php-arent-logical) – outis Aug 04 '13 at 21:42

4 Answers4

2

You need to use call_user_func to do this:

call_user_func(array($this, $this->_auto));

Unfortunately PHP does not allow you to directly use property values as callables.

There is also a trick you could use to auto-invoke callables like this. I 'm not sure I would endorse it, but here it is. Add this implementation of __call to your class:

 public function __call($name, $args)
 {
     if (isset($this->$name) && is_callable($this->$name)) {
         return call_user_func_array($this->$name, $args);
     }
     else {
         throw new \Exception("No such callable $name!");
     }
 }

This will allow you to invoke callables, so you can call free functions:

 $this->_auto = 'phpinfo';
 $this->_auto();

And class methods:

 $this->_auto = array($this, 'index');
 $this->_auto();

And of course you can customize this behavior by tweaking what __call invokes.

Jon
  • 428,835
  • 81
  • 738
  • 806
  • You don't *need* `call_user_func`, you can just wrap the property value in curly braces, i.e. `$this->{$this->_auto}();`, and [PHP will keep on chuggin](http://viper-7.com/bsrn88). – nickb Jan 30 '13 at 20:52
  • @nickb: I always succeed in forgetting that syntax. I really must not be liking how it looks. – Jon Jan 30 '13 at 21:07
0

You don't have a method named _auto(), you only have a property named $_auto. If your intent is for a call to an undefined method to return a similarly named property if it exists, then you would need to write a __call() magic method to perform the logic of looking at a similarly named property and returning the value. So something like this would need to be added to your class:

public function __call($called_method, $arguments) {
    if(property_exists($this, $called_method)) {
        return $this->{$called_method};
    } else {
        throw new Exception('Illegal method call.');
    }
}
Mike Brant
  • 70,514
  • 10
  • 99
  • 103
0

You code is trying to call a method called "_auto". To do what you are asking, you want to make the method name a php variable or something along the lines of what the other posters are saying.

class Foo {
    private function _auto() {
        echo "index";
    }

    public function callmethod($method) {
        $this->$method();
    }
}

$foo = new Foo();
$foo->callmethod('_auto');
Schleis
  • 41,516
  • 7
  • 68
  • 87
0

I think you mistakenly defined "_auto" as a property?

Try using:

private function _auto(){}

Instead of

private $_auto
Lloyd Banks
  • 35,740
  • 58
  • 156
  • 248