Phalcon: how to get controller and action name
Solution 1
I think that untill you call $app->handle()
the dispatcher won't be properly setup.
Maybe not a direct response, but I've manage to successfully implement authorization using Vokuro app as a example: https://github.com/phalcon/vokuro.
Your bootstrap looks ok should work.
I'm using this in bootstrap file :
/**
* Handle the request
*/
$application = new \Phalcon\Mvc\Application();
$application->setDI($di);
if (!empty($_SERVER['REQUEST_URI'])) {
$uriParts = explode('?', $_SERVER['REQUEST_URI']);
$uri = $uriParts[0];
} else {
$uri = '/';
}
echo $application->handle($uri)->getContent();
As you can see there is $uri parameter passed to $application->handle()
function.
Inside controllers: $this->dispatcher->getControllerName()
works fine.
Solution 2
I am using a Router object so the following works for me before the ->handle
call
/** @var $router \Phalcon\Mvc\Router */
$router = require APPLICATION_PATH.'/routes/default.php';
$router->handle($url);
$router->setUriSource(\Phalcon\Mvc\Router::URI_SOURCE_SERVER_REQUEST_URI);
/** @var $matched \Phalcon\Mvc\Router\Route */
$matched = $router->getMatchedRoute();
$paths = $matched->getPaths();
echo 'controller : ',$paths['controller'],"<br />";
echo 'action : ',$paths['action'],"<br />";
Solution 3
This is an old thread but in case people still need it, I will show you two ways to properly handle authorization.
In both cases, you should check authorization in a "before middleware", not anywhere else.
Checking authorization directly in your front controller is a bit premature.
1. By retrieving the handler, as you asked
Here you perform authorization checks only if needed. It is a bit more code, but a bit more effective too because you don't have to even use the database if you don't need to.
$app = \Phalcon\Mvc\Micro;
$app->before(function() use ($app)
{
/**
* @var \Phalcon\Mvc\Controller $oHandler
*/
$oHandler = null;
$sAction = null;
$aHandlerArr = (array)$app->getActiveHandler();
if (!empty($aHandlerArr) && !empty($aHandlerArr[1]))
{
$oHandler = $aHandlerArr[0];
$sAction = $aHandlerArr[1];
}
if ($oHandler && $oHandler->isAuthRequired($sAction))
{
// Do auth, and send an error if failed
}
});
2. Without voodoo magic
The other way is to simply try authorization in your before middleware without checking if you need it. It is the same code as above, but without the handler retrieval.
$app = \Phalcon\Mvc\Micro;
$app->before(function() use ($app)
{
// Do auth ...
// Set member in your app, if auth succeeded.
// Then in your controller actions, simply check for the member in your app
});
Quasipickle
Updated on June 04, 2022Comments
-
Quasipickle almost 2 years
I'm trying to build some authorization into my Phalcon-based app. In my bootstrap file I instantiate my Auth class (which extends Component), and run my
authorize()
function. Inside that function I get the dispatcher by calling$Dispatcher = $this->di->getShared('dispatcher')
.That all seems to run fine. However, when I then call
$Dispatcher->getControllerName()
, it returns NULL.How do I access the controller name?
Here is my bootstrap file:
$Debug = new \Phalcon\Debug(); $Debug->listen(); #try{ # Create a Dependency Injection container $DI = new \Phalcon\DI\FactoryDefault(); # Load config $Config = require '../app/config/config.php'; $DI->setShared('config',$Config); # Register an autoloader $Loader = new \Phalcon\Loader(); $Loader->registerDirs($Config->phalcon->load_dirs->toArray()); $Loader->registerNamespaces($Config->phalcon->namespaces->toArray()); $Loader->register(); # Initialize Session $Session = new \Phalcon\Session\Adapter\Files(); $Session->start(); $DI->setShared('session',$Session); # Set up the View component $DI->set('view',function() use($Config){ $View = new \Phalcon\Mvc\View(); $View->setViewsDir($Config->dir->views_dir); $View->registerEngines(['.phtml'=> function($View,$DI) use ($Config){ $Volt = new \Phalcon\Mvc\View\Engine\Volt($View,$DI); $Volt->setOptions([ 'compiledPath' => $Config->dir->views_compile_dir, 'compileAlways' => $Config->app->views_compile_always ]); return $Volt; } ]); $View->Config = $Config; return $View; }); # Check authorization $Auth = new Auth($DI); if($Auth->authorize()){ $DI->setShared('user',$Auth->getUser()); } else{ $DI->get('view')->render('system','notallowed'); exit(); } # Set up connection to database $DI->set('db',function() use($Config){ return new \Phalcon\DB\Adapter\Pdo\Mysql([ 'host' => $Config->database->host, 'dbname' => $Config->database->database, 'username' => $Config->database->username, 'password' => $Config->database->password ]); }); # Set up base URL $DI->set('url',function() use($Config){ $URL = new \Phalcon\Mvc\Url(); $URL->setBaseUri('/'.basename($Config->dir->app_dir_web)); return $URL; }); # Set up message flashing to use session instead of direct $DI->set('flash',function(){ return new \Phalcon\Flash\Session(); }); # Handle the requested URL $App = new \Phalcon\Mvc\Application($DI); # Echo the output echo $App->handle()->getContent(); /* } catch(\Phalcon\Exception $e){ echo 'Phalcon Exception: ',$e->getMessage(); } */
-
Quasipickle almost 11 yearsSo I guess there is no Phalcon-specific way to get the controller/action name in the bootstrap then? Guess I'll roll my own like you showed. Thanks.
-
Quasipickle over 8 yearsThanks for this update. Note, however, that my initial question wasn't for a Micro application, so this isn't really applicable to the original question.
-
Lideln Kyoku over 8 yearsOk Pickle, my bad! Though the principles stay the same. For FullMVC, you can try the dispatcher and events manager as described here: docs.phalconphp.com/en/latest/reference/dispatching.html (although I am not sure it did actually exist when you asked your question a long time ago :) )
-
Luke almost 8 yearsAnswer is correct but consider describing response using full sentences and possibly avoid emoticons. That's the answers style we (the community) are trying to keep for clarity