我實現了router
,securityplugin (for ACL)
和notfoundplugin
。Phalcon中子控制器結構的路由問題
我想我的網站設置了一個子控制器結構:Link
該網站是建立在以下幾個主要部分:
- 指數
- 聯繫
- 門票
- 帳戶
的問題,我有:
當調用:域/管理/ actionofadmin
返回自定義404: 「頁面不存在」,而不是正常作用的結果
調用時:domain/admin/actionofadmin。 (< - 介意結束點)指數控制器
收益指數的行動,而不是正常的動作結果
爲什麼路由器返回論文的結果嗎?他們如何修復?
額外的問題:
如何爾康知道在哪裏可以找到一個視圖,並將其鏈接到正確的控制器?示例:dashboardController駐留在文件夾「controllers」內的「admin」文件夾中。
Phalcon如何知道在SecurityPlugin ACL中,它需要搜索正確的控制器,但它沒有獲得命名空間?示例:當我想允許控制器命名空間app \ controllers \ admin的票證僅由管理員用戶查看時。
的額外信息:
- 爾康3.0.3
- PHP 5.6
讓我知道如果你需要更多的信息/文件,或者我應該張貼它在其他地方易於閱讀。
文件:
/應用/控制器/ AdminController。PHP
<?php
namespace Ontrack\Controllers;
class AdminController extends ControllerBase
{
public function indexAction(){
}
public function testAction(){
echo "test";
}
}
/app/config/services.php摘錄
//This makes sure the routes are correctly handled for authorized/unauthorized
/**
* MVC dispatcher
*/
$di->set("dispatcher", function() use ($di) {
// Create an events manager
$eventsManager = $di->getShared('eventsManager');
/**
*Check if the user is allowed to access certain action using the SecurityPlugin
*Listen for events produced in the dispatcher using the Security plugin
*/
$eventsManager->attach("dispatch:beforeDispatch", new SecurityPlugin());
// Handle exceptions and not-found exceptions using NotFoundPlugin
$eventsManager->attach("dispatch:beforeException", new NotFoundPlugin());
$dispatcher = new Dispatcher();
$dispatcher->setDefaultNamespace('Ontrack\Controllers');
// Assign the events manager to the dispatcher
$dispatcher->setEventsManager($eventsManager);
return $dispatcher;
}
);
/app/config/loader.php
<?php
$loader = new \Phalcon\Loader();
/**
* We're a registering a set of directories taken from the configuration file
*/
$loader->registerDirs(
[
$config->application->controllersDir,
$config->application->modelsDir,
$config->application->pluginsDir
]
)->register();
$loader->registerNamespaces(
[
'Ontrack\Controllers' => APP_PATH . '/controllers/',
'Ontrack\Controllers\Admin' => APP_PATH . '/controllers/admin',
'Ontrack\Models' => APP_PATH . '/models/'
]
)->register();
/應用/ config/routes.php
<?php
$router = new Phalcon\Mvc\Router(false);
$router->setDefaults(
[
"controller" => "index",
"action" => "index",
]
);
$router->add('/:controller/:action/:params', [
'namespace' => 'Ontrack\Controllers',
'controller' => 1,
'action' => 2,
'params' => 3,
]);
$router->add('/:controller/:action', [
'namespace' => 'Ontrack\Controllers',
'controller' => 1,
'action' => 2,
]);
$router->add('/:controller', [
'namespace' => 'Ontrack\Controllers',
'controller' => 1,
]);
$router->add('/admin/:controller/:action/:params', [
'namespace' => 'Ontrack\Controllers\Admin',
'controller' => 1,
'action' => 2,
'params' => 3,
]);
$router->add('/admin/:controller/:action', [
'namespace' => 'Ontrack\Controllers\Admin',
'controller' => 1,
'action' => 2,
]);
$router->add('/admin/:controller', [
'namespace' => 'Ontrack\Controllers\Admin',
'controller' => 1,
]);
$router->removeExtraSlashes(true);
return $router;
/app/plugins/SecurityPlugin.php
<?php
use Phalcon\Acl;
use Phalcon\Acl\Role;
use Phalcon\Acl\Adapter\Memory as AclList;
use Phalcon\Acl\Resource;
use Phalcon\Events\Event;
use Phalcon\Mvc\User\Plugin;
use Phalcon\Mvc\Dispatcher;
class SecurityPlugin extends Plugin
{
/**
* Returns an existing or new access control list
*
* @returns AclList
*/
public function getAcl()
{
if (!isset($this->persistent->acl)) {
$acl = new AclList();
$acl->setDefaultAction(Acl::DENY);
// Register roles
$roles = [
'admins' => new Role(
'admins',
'Website administrators'
),
'users' => new Role(
'users',
'Member privileges, granted after sign in.'
),
'guests' => new Role(
'guests',
'Anyone browsing the site who is not signed in is considered to be a "Guest".'
)
];
foreach ($roles as $role) {
$acl->addRole($role);
}
//Private area resources
$privateResources = array(
'account' => array('*')
);
$privateResourcesAdmin = array(
'admin' => array('*'),
'tickets' => array('*')
);
//Public area resources
$publicResources = array(
'index' => array('*'),
'register' => array('*'),
'errors' => array('show401', 'show404', 'show500'),
'register' => array('*'),
'login' => array('*'),
'logout' => array('*')
);
foreach ($privateResources as $resource => $actions) {
$acl->addResource(new Resource($resource), $actions);
}
foreach ($privateResourcesAdmin as $resource => $actions) {
$acl->addResource(new Resource($resource), $actions);
}
foreach ($publicResources as $resource => $actions) {
$acl->addResource(new Resource($resource), $actions);
}
//Grant access to public areas to users, admins and guests
foreach ($roles as $role) {
foreach ($publicResources as $resource => $actions) {
foreach ($actions as $action){
$acl->allow($role->getName(), $resource, $action);
}
}
}
//Grant access to private area to role Users
foreach ($privateResources as $resource => $actions) {
foreach ($actions as $action){
$acl->allow('users', $resource, $action);
}
}
foreach ($privateResourcesAdmin as $resource => $actions) {
foreach ($actions as $action){
$acl->allow('admins', $resource, $action);
}
}
//The acl is stored in session, APC would be useful here too
$this->persistent->acl = $acl;
}
return $this->persistent->acl;
}
/**
* This action is executed before execute any action in the application
*
* @param Event $event
* @param Dispatcher $dispatcher
* @return bool
*/
public function beforeDispatch(Event $event, Dispatcher $dispatcher){
$auth = $this->session->has('auth');
if (!$auth){
$role = 'guests';
} else {
$authSession = $this->session->get("auth");
if($authSession['account_type'] == 99){
$role = 'admins';
} else {
$role = 'users';
}
}
$controller = $dispatcher->getControllerName();
$action = $dispatcher->getActionName();
$acl = $this->getAcl();
if (!$acl->isResource($controller)) {
$dispatcher->forward([
'controller' => 'errors',
'action' => 'show404'
]);
return false;
}
$allowed = $acl->isAllowed($role, $controller, $action);
if (!$allowed) {
if($controller === 'admin'){
$dispatcher->forward(array(
'controller' => 'errors',
'action' => 'show404'
));
} else {
$dispatcher->forward(array(
'controller' => 'errors',
'action' => 'show401'
));
}
return false;
}
}
}
/app/plugins/NotFoundPlugin.php
<?php
use Phalcon\Events\Event;
use Phalcon\Mvc\User\Plugin;
use Phalcon\Dispatcher;
use Phalcon\Mvc\Dispatcher\Exception as DispatcherException;
use Phalcon\Mvc\Dispatcher as MvcDispatcher;
/**
* NotFoundPlugin
*
* Handles not-found controller/actions
*/
class NotFoundPlugin extends Plugin
{
/**
* This action is executed before execute any action in the application
*
* @param Event $event
* @param MvcDispatcher $dispatcher
* @param Exception $exception
* @return boolean
*/
public function beforeException(Event $event, MvcDispatcher $dispatcher, Exception $exception)
{
error_log($exception->getMessage() . PHP_EOL . $exception->getTraceAsString());
if ($exception instanceof DispatcherException) {
switch ($exception->getCode()) {
case Dispatcher::EXCEPTION_HANDLER_NOT_FOUND:
case Dispatcher::EXCEPTION_ACTION_NOT_FOUND:
$dispatcher->forward(array(
'controller' => 'errors',
'action' => 'show404'
));
return false;
}
}
$dispatcher->forward(array(
'controller' => 'errors',
'action' => 'show500'
));
return false;
}
}
謝謝你的回答。我設法通過檢查名稱空間何時轉發給控制器以及SecurityPlugin.php文件中給定URL中的動作來解決我的問題。 – Dragon54