用多个参数PHP Apache重写url

时间:2012-12-04 22:10:46

标签: php apache mod-rewrite

我只是花了几个小时环顾四周,但没有找到解决方案。

我目前有典型的查询字符串,如;

 http://www.site/jobs/results.php?keyword=Accounting+%26+Finance&type=10&state_id=130&location=NSW&order=1&page=1

我喜欢重写

 http://www.site/jobs/find/accounting-finance/NSW/free-jobs/1/?order=1

但我不知道params会发送什么,这将取决于用户做什么,过滤器,类别,订单等

我想保持简单并在PHP中解析url并使用简单的重写规则,但后来我需要键/值对,所以我知道哪个值属于哪个param类似的东西;

http://www.site/jobs/find/keyword/accounting-finance/state/NSW/type/free-jobs/page/1/?order=1

我被告知这对seo来说不是一个好选择。

除了在.htacces中编写许多不同的规则以涵盖所有场景之外,您可以建议更好的方法来解决这个问题

由于

2 个答案:

答案 0 :(得分:1)

.htaccess:

RewriteEngine on
# skip rewriting if file/dir exists (optionally)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# rewrite all to results.php
RewriteRule . results.php

php(使用key =>值对的简单方法):

// current URI (/jobs/find/keyword/accounting-finance/state/NSW/type/free-jobs/page/1/?order=1)
$path = $_SERVER['REQUEST_URI'];

// remove base path (/jobs)
if (($len = strlen(basename($_SERVER['SCRIPT_FILENAME'])))) 
    $path = substr($len, $path);

// remove GET params (?order=1)
if (false !== ($pos = strpos($path, '?'))) 
    $path = substr($path, 0, $pos);

$path = explode('/', trim($path, '/'));

// extract action (or whatever 'find' is)
$action = array_shift($path);

// make key => value pairs from the rest
$params = array();
for ($i = 1, $c = count($path) ; $i < $c ; $i += 2) {
    $params[urldecode($path[$i - 1])] = urldecode($params[$i]);
    // or put it to GET (only remember that it will overwrite already existing values)
    //$_GET[urldecode($path[$i - 1])] = urldecode($params[$i]);
}

您可以修改此脚本以仅在没有密钥的情况下实现值,但问题是 - 是否可以确定值是一个还是另一个?如果params总是在同一个位置而你只能得到更少或更多,那么它很容易:

// skip this step from previous example
//$action = array_shift($path);    

$params = array(
    'action' => null,
    'keyword' => null,
    'state' => null,
    'type' => null,
    'page' => null,
);
$keys = array_keys($params);
for ($i = 0 , $c = min(count($path), count($keys) ; $i < $c ; ++$i) {
    $params[$keys[$i]] = urldecode($path[$i]);
}

但是如果你不知道哪个位置在哪个位置,那么事情就会变得更加复杂。您需要对每个参数进行一些检查并确定它是哪一个 - 如果从某些已知值列表中选择所有这些值,那么它也不会非常困难,例如:

$params = array(
    'action' => null,
    'keyword' => null,
    'state' => null,
    'type' => null,
    'page' => null,
);
$params['action'] = array_shift($path);
$keys = array_keys($params);
foreach ($path as $value) {
    if (is_numeric($value)) $params['page'] = intVal($value);
    else {
        $key = null;
        // that switch is not very nice - because of hardcode
        // but is much faster than using 'in_array' or something similar
        // anyway it can be done in many many ways
        switch ($value) {
            case 'accounting-finance' :
            case 'keyword2' :
            case 'keyword3' :
                $key = 'keyword';
                break;
            case 'NSW' :
            case 'state2' :
                $key = 'state';
                break;
            case 'type1' :
            case 'type2' :
            case 'type3' :
                $key = 'type';
                break;
            // and so on...
        }
        if ($key === null) throw new Exception('Unknown value!');
        $params[$key] = $value;
    }
}

你也可以尝试在.htaccess中编写一些非常复杂的正则表达式,但IMO它不是一个地方 - apache应该在你的应用程序中匹配请求和正确的端点并运行它,它不适用于扩展的params逻辑(如果无论如何它会在你的应用程序中转到同一个地方)。将应用程序中的逻辑保存在应用程序中也更加方便 - 当您更改某些内容时,您可以在应用程序代码中执行此操作而无需更改htaccess或apache配置中的任何内容(在生产环境中,我主要将.htaccess内容移动到apache配置)并关闭.htaccess支持 - 当apache没有搜索这些文件时会提供一些加速,但任何更改都需要重启apache。)

答案 1 :(得分:0)

如果您想要做的就是将任何与搜索引擎优化相关的内容推送到网址中,那么您的重写实际上变得非常简单:只是不要进行任何重写,将参数保留在原来的位置,只需填写{{ {1}}使用您的SEO关键字:

results.php

它不应该对PHP产生影响,因为这条不存在的路径最终被解析为$ _SERVER ['PATH_INFO'],但脚本执行保持不变。

现在的问题是:您的SEO相关关键字的来源是什么? :)