5

这应该很简单,但我希望能够像 php 框架一样使用 url 作为变量。

mywebsite.com/hello-world

我希望我的 index.php 将“hello-world”视为一个变量,并且我希望 index.php 加载。这是通过 php 完成的还是我必须使用 htaccess 文件?

许多 php 框架使用 url 向索引文件发送消息......例如......

mysite.com/controller/view

我将如何通过 php 自己路由这些?

一点帮助?

4

3 回答 3

3

有2个步骤:

  1. 使用.htaccess文件(在 linux 上)重写 url。您需要确保所有请求都转到您的 php 文件,因此您需要将所有对不存在文件和文件夹的请求重写到您的 php 文件;
  2. 在您的 php 文件中,您分析 url(例如使用$_SERVER['REQUEST_URI'])并根据其内容采取行动。

对于第 1 步,您可以使用以下内容:

RewriteEngine On
RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ your_file.php?url=$1 [L,QSA]

然后在步骤 2 中的 php 文件中。您在$_GET['url'].

编辑:

如果您只想重写某些子目录,您还可以使用如下规则:

RewriteRule ^sub/dir/to/rewrite/(.*)$ your_file.php?url=$1 [L,QSA]

一些细节:

  • ^(.*)$^捕获 start和 end之间的所有内容(所有字符)$。它们是使用括号捕获的,因此您可以在查询字符串中使用它们,例如$1. 在编辑后的示例中,仅..../rewrite/捕获后面的部分;
  • 之间的选项[ ... ]意味着它是L要处理的最后一条规则,并且QSA原始查询字符串也将添加到新 url。这意味着如果您的 url 是/hello-world?some_var=4变量some_var被附加到重写的 url: your_file.php?url=hello-world&some_var=4
于 2013-06-22T02:24:30.030 回答
1

这种重新路由必须在网络服务器级别完成,要么在您服务器的 Apache 配置文件中,要么(更有可能)通过.htaccess文件。

这是.htaccess我在自己的网站上使用的文件来进行这种重新路由:

# Allow any files or directories that exist to be displayed directly
RewriteCond %{REQUEST_FILENAME} !-f

#Route everything else through index.php
RewriteRule .* index.php/?$0 [PT,L]

然后在index.php我的数据库中查找 URL 以提取页面内容:

if(isset($_SERVER['REQUEST_URI']) and strlen($_SERVER['REQUEST_URI']) > 1)
    $requested_url = substr($_SERVER['REQUEST_URI'], 1);
else
    $requested_url = 'home';
于 2013-06-22T02:30:19.997 回答
1

您想要实现的称为“前端控制器”模式。通常使用 Apache 的mod_rewrite. 如果不重写 URL,您仍然可以执行类似的操作,但您的 URL 将如下所示:

mysite.com/index.php/controller/view

而不是: mysite.com/controller/view 如你所愿。

这是用于进行 URL 重写的最小 .htaccess 文件:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]

然后,您从其中解析 URL,$_SERVER['REQUEST_URI']但请记住在确定视图名称时去掉最后的任何 GET 参数。

我个人最近想要这样的东西,但没有一个成熟的框架,所以我使用这个微框架来做路由,它工作得非常好:

http://www.slimframework.com/

然后就可以编写自己的控制器类并设置路由了;这是我使用的代码:

$app = new \Slim\Slim();

$app->map('/:controller(/:action)', 'dispatchControllerAction')
    ->via('GET', 'POST');

function dispatchControllerAction($controllerName, $action='index') {
    //multi-word controllers and actions should be hyphen-separated in the URL
    $controllerClass = 'Controllers\\'.ucfirst(camelize($controllerName, '-'));
    $controller = new $controllerClass;
    $controller->execute(camelize($action, '-'));
}

/**
 * Adapted from the Kohana_Inflector::camelize function (from the Kohana framework)
 * Added the $altSeparator parameter
 * 
 * Makes a phrase camel case. Spaces and underscores will be removed.
 *
 *     $str = Inflector::camelize('mother cat');     // "motherCat"
 *     $str = Inflector::camelize('kittens in bed'); // "kittensInBed"
 *
 * @param   string  $str    phrase to camelize
 * @param   string  $altSeparator  Alternate separator to be parsed in addition to spaces. Defaults to an underscore.
 *      If your string is hyphen-separated (rather than space- or underscore-separated), set this to a hyphen
 * @return  string
 */
function camelize($str, $altSeparator='_')
{
    $str = 'x'.strtolower(trim($str));
    $str = ucwords(preg_replace('/[\s'.$altSeparator.']+/', ' ', $str));

    return substr(str_replace(' ', '', $str), 1);
}
于 2013-06-22T02:35:42.360 回答