簡體   English   中英

帶有IndexController的友好URL

[英]Friendly URL's with an IndexController

我當前的路由器/ FrontController已設置為剖析URL,格式為:

http://localhost/controller/method/arg1/arg2/etc...

但是,我不確定如何獲取某些默認請求到IndexController的請求,以便鍵入:

http://localhost/contact
or
http://localhost/about/portfolio

代替:

http://localhost/index/contact
or
http://localhost/index/about/portfolio

如何完成的?

<?php

namespace framework;

class FrontController {
    const DEFAULT_CONTROLLER = 'framework\controllers\IndexController';
    const DEFAULT_METHOD     = 'index';

    public $controller       = self::DEFAULT_CONTROLLER;
    public $method           = self::DEFAULT_METHOD;
    public $params           = array();
    public $model;
    public $view;

    function __construct() {
        $this->model = new ModelFactory();
        $this->view = new View();
    }

    // route request to the appropriate controller
    public function route() {
        // get request path
        $basePath = trim(substr(PUBLIC_PATH, strlen($_SERVER['DOCUMENT_ROOT'])), '/') . '/';
        $path = trim(parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH), '/');
        if($basePath != '/' && strpos($path, $basePath) === 0) {
            $path = substr($path, strlen($basePath));
        }

        // determine what action to take
        @list($controller, $method, $params) = explode('/', $path, 3);
        if(isset($controller, $method)) {
            $obj = __NAMESPACE__ . '\\controllers\\' . ucfirst(strtolower($controller)) . 'Controller';
            $interface = __NAMESPACE__ . '\\controllers\\' . 'InterfaceController';
            // make sure a properly implemented controller and corresponding method exists
            if(class_exists($obj) && method_exists($obj, $method) && in_array($interface, class_implements($obj))) {
                $this->controller = $obj;
                $this->method = $method;

                if(isset($params)) {
                    $this->params = explode('/', $params);
                }
            }
        }
        // make sure we have the appropriate number of arguments
        $args = new \ReflectionMethod($this->controller, $this->method);
        $totalArgs = count($this->params);
        if($totalArgs >= $args->getNumberOfRequiredParameters() && $totalArgs <= $args->getNumberOfParameters()) {
            call_user_func_array(array(new $this->controller, $this->method), $this->params);
        } else {
            $this->view->load('404');
        }
    }
}

根據您的代碼片段,我會這樣做(偽php代碼):

$handler = get_controller($controller);
if(!$handler && ($alias = lookup_alias($path))) {
    list($handler, $method) = $alias;
}
if(!$handler) error_404();

function lookup_alias($path) {
    foreach(ALL_CONTROLLERS as $controller) {
        if(($alias = $controller->get_alias($path))) {
            return $alias;
        }
    }
    return null;
}

因此,基本上在沒有控制器處理某個位置的情況下,您要檢查是否有任何控制器配置為將給定路徑作為別名處理,如果是,則返回該控制器及其映射的方法。

您可以通過以下兩種方法之一使用URL:

以路由定義它們的方式建立控制器

example.com/contact =>使用默認或索引操作的“聯系人”控制器

example.com/about/portfolio =>使用“ portfolio”操作使一個“ about”控制器

由於您當前可用的路由說您的URL被視為“ / controller / method”,因此沒有其他方法。

建立動態路由,以允許單個控制器處理多個URL

顯然,這需要一些配置,因為一個人不知道哪個URL有效,哪個URL應該重定向到通用控制器,哪些不應該。 這在某種程度上可以替代任何重寫或重定向解決方案,但是由於它是在PHP級別進行處理的,因此更改可能更易於處理(某些Web服務器配置由於性能原因不提供.htaccess,因此通常會花費更多精力創建這些)。

您的配置輸入為:

  1. 您要處理的網址和
  2. 您想要URL傳遞給的控制器,它就是動作。

您最終將擁有這樣的數組結構:

$specialRoutes = array(
    "/contact" => "IndexController::indexAction",
    "/about/portfolio" => "IndexController::indexAction"
);

缺少的是,此操作應使當前URL作為參數傳遞,或者路徑部分成為URL架構中的指定參數。

總而言之,這種方法很難編碼。 要想出一個主意,請嘗試看一下常見的MVC框架(例如Symfony和Zend Framework)的路由。 它們提供了高度可配置的路由,因此,路由發生在多個類別中。 如果檢測到匹配,主路由器僅讀取配置,然后將任何URL的路由傳遞到已配置的路由器。

您可以在網絡服務器中為這些異常創建重寫。 例如:

RewriteRule ^contact$ /index/contact
RewriteRule ^about/portfolio$ /about/portfolio

這將使您擁有映射到常規結構的簡化URL。

如果您能夠精確定義應重寫為/ index的內容,則可以使用動態規則。 例如:

RewriteRule ^([a-z]+)$ /index/$1

嘗試以下動態htaccess重寫規則:

RewriteRule ^(.+)/?$ /index/$1 [QSA]

上面規則中的QSA標志允許您還根據需要在末尾添加查詢字符串,如下所示:

http://localhost/contact?arg1=1&arg2=2

編輯:此規則還將處理/about/portfolio

RewriteRule ^(.+)/?(.+)?$ /index/$1 [QSA]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM