Reputation:
I can't seem to get the Slim framework to access functions inside the scope of a PHP class:
<?php
class Controller {
private $app;
public function __construct() {
$this->app = new Slim();
$this->app->get('/', $this->home);
$this->app->run();
}
public function home() {
echo 'hi';
}
}
This causes the following error:
Fatal error: Uncaught exception 'ErrorException' with message 'Undefined property: Controller::$home' in /Users/Oliver/Dropbox/Sites/grapevine/application/controller.php:9 Stack trace: #0 /Users/Oliver/Dropbox/Sites/grapevine/application/controller.php(9): Slim::handleErrors(8, 'Undefined prope...', '/Users/Oliver/D...', 9, Array) #1 /Users/Oliver/Dropbox/Sites/grapevine/public/index.php(14): Controller->__construct() #2 {main} thrown in /Users/Oliver/Dropbox/Sites/grapevine/application/controller.php on line 9
I have tried doing this instead:
$this->app->get('/', $this->home());
But then the routing is ignored, and 'hi' is displayed on every page, not just '/'.
Upvotes: 2
Views: 7386
Reputation: 10412
I have this solution with constructor injection from Slim internal container
Basically the main magic is hidden in __call
function
class App extends Slim
public function __call($name, $params) {
return function () use ($name, $params) {
list($class, $action) = explode('_', $name . '_handle'); // default method is handle
$args = [];
$class = new \ReflectionClass($class);
$constructor = $class->getConstructor();
foreach ($constructor->getParameters() as $param) {
$args[] = ($param->name === 'app') ? $this : $this->container->get($param->name);
}
$controller = $class->newInstanceArgs($args);
return call_user_func([$controller, $action], func_get_args() + $params);
};
}
}
controller need to have App in constructor params:
class Homepage {
public $app;
public function __construct(\App $app) {
$this->app = $app;
}
}
And index.php have just router settings
$app = new \App();
$app->get('/', $app->Homepage());
$app->run(
See whole code here https://gist.github.com/OzzyCzech/7230064
Upvotes: 1
Reputation: 318778
Use the callback syntax for member functions:
$this->app->get('/', array($this, 'home'));
Upvotes: 12
Reputation: 17166
The following should work (it might be neccessary to change your home-function to be static, though!):
$this->app->get('/', "Controller::home");
Upvotes: 2