【问题标题】:Apache mod_rewrite and PHP GET ArraysApache mod_rewrite 和 PHP GET 数组
【发布时间】:2010-12-12 10:41:01
【问题描述】:

我想要一个像http://localhost/folder1/folder2/folder3/file 这样的网址 然后我希望 mod_rewrite 将其转换为 URL 中的 $_GET['d'] 它看起来像 d[]=folder1&d[]=folder2&d[]=folder3

这可能吗?

谢谢。

【问题讨论】:

    标签: php arrays mod-rewrite get


    【解决方案1】:

    是的,有可能:

    RewriteRule ^(([^/]+/)*)([^/]+)/([^/]+)$ /$1$4?d[]=$3 [QSA,N]
    RewriteRule ^([^/]+)$ - [L]
    

    但是 mod_rewrite 并不真正适合这种工作。实际上,您可以使用N flag 快速创建无限循环。

    您应该使用 PHP 来提取请求的 URL 路径及其段:

    $path = strtok($_SERVER['REQUEST_URI'], '?');
    $segments = implode('/', ltrim($path, '/'));
    

    然后使用这条规则将请求重写到您的文件:

    RewriteRule ^([^/]+/)+([^/]+)$ $2 [L]
    

    【讨论】:

      【解决方案2】:

      我不知道自动执行此操作的方法,但您可以从 $_SERVER['REQUEST_URI'] 检索请求的 URL 并对其执行自己的字符串处理以提取所需的信息。

      【讨论】:

      • 直接解析 REQUEST_URI 有时是最好的选择。有些事情 mod_rewrite 并不是很有效——一个例子是尝试重写包含“&”和“?”的 URL。人物。但是,mod_rewrite 的性能将比 PHP 重写高很多倍,这在某些情况下可能很重要。
      【解决方案3】:

      这就是我为具有无限级别的搜索引擎友好 URL 所做的。它还让您可以选择是否允许查询字符串,并且不会将 url 重写为真实文件夹或文件,如图像、CSS 和 JavaScript。

      阿帕奇...

      # Do not use htaccess if you can avoid it, instead write all of this in the httpd.conf <VirtualHost /> and disable .htaccess for performance/security.
      RewriteEngine On
      RewriteBase /
      
      # Redirect non-www traffic to www.domain.co.uk/request
      RewriteCond %{HTTP_HOST} !^www\.domain\.co\.uk$ [NC]
      RewriteRule ^(.*)$ http://www.domain.co.uk/$1 [R=301,L]
      
      # Do not rewrite real files
      RewriteCond %{REQUEST_FILENAME} -f [OR]
      RewriteCond %{REQUEST_FILENAME} -d
      RewriteRule ^.*/ - [L]
      
      # Use 1 or 2 Below
      
      # 1. SEO Friendly URLs (don't allow additional query strings /foo/bar/)
      # RewriteRule ^([A-Za-z0-9/-]*)$ index.php?request=$1 [L]
      
      # 2. SEO Friendly URLs (allow additional query strings /foo/bar/?q=search)
      RewriteRule ^([A-Za-z0-9/-]*)$ index.php?request=$1 [L,QSA]
      

      PHP...

      <?php
      
      /*
          Title: Request
          Gets the client request and sanitizes the user input.
      
          Returns:
              Array of parts of the URL.
      
              > $request = /path/to/page/
              > var_dump($request);
              > array(3) { [0]=>  string(4) "path" [1]=>  string(2) "to" [2]=>  string(4) "page" }
      */
      
      // Check request exists
      if (isset($_GET['request']) && !empty($_GET['request']))
      {
          // Yes. Sanitize request.
          // request should be made lowercase, as URLs should not be case-sensitive.
          $request = strtolower($_GET['request']);
      
          // Sanitize request incase the user tries to circumvent the .htaccess rules and uses the query string directly. index.php?request=
          $request = preg_replace("([^a-z0-9-/])", '', $request);
      
          // Check if request ends with trailing slash to ensure all crawled URLs end with a trailing slash. ($request does not include other query strings or anchors)
          if ((substr($request, -1, 1)) == '/')
          {
              // Yes, request should now be safe to use.
              $safe['url'] = $request;
      
              // Split request into an array with values for each directory.
              $safe['request'] = explode('/', $request, -1);
      
              // Destroy user input to prevent usage.
              unset($_GET['request'], $request);
          }
          else
          {
              // No, redirect to request with trailing slash.
              header('Location: /' . $request . '/', true, 301);
              exit;
          }
      }
      else
      {
          // No.
          $safe['request'] = false;
      }
      
      ?>
      

      然后我有一个路由文件,它使用适当的功能处理请求。它可能看起来像很多代码,但有助于保持组织和高效,因为我只包含请求所需的类/函数。

      我正在考虑发布一个代码库(呃,不是我听到你哭泣的另一个框架)我用于我的项目,所以请随意使用 GPL v3 下的代码。

      希望这会有所帮助。

      【讨论】:

        【解决方案4】:

        这应该让您大致了解您需要什么......

        Rewrite Rule ^(.*)/(.*)/(.*)/(.*)$ /my_script.php?d[]=$1&d[]=$2&d=$3&f=$4
        

        如果您想支持任意数量的目录,而不是 3 个固定目录,那将完全是另一个问题。

        【讨论】:

        【解决方案5】:

        前端控制器(MVC 设计模式的一部分)是一种很好的使用技术。前端控制器是一个 (PHP) 文件,您的网站获得的每个请求都会被路由到该文件。然后前端控制器根据请求的类型将请求分派到其他文件(查看页面 X、提交表单 Y 等)。例如,您可以使用@Ray Hidayat 描述的技术“剪切”请求的 url,然后查看它以确定您网站的哪个部分应该处理和/或响应请求。

        例如:Zend Framework 和 Drupal 都使用这种技术。在这些情况下,我认为在大多数情况下,站点根目录中的 index.php 是前端控制器,因此 www.example.com/index.php

        您可以使用 mod_rewrite 将每个请求路由到该前端控制器。

        RewriteEngine on
        RewriteRule .* index.php
        

        您可以将以下 mod_rewrite 脚本用于图像/文件/CSS 和 javascript 库。

        RewriteEngine off
        

        祝你好运!

        【讨论】:

        • 我的回答有点离题,但如果你想要复杂的 url,我认为这种技术非常有用。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-11-12
        • 1970-01-01
        • 2012-08-27
        • 1970-01-01
        • 2013-07-07
        • 2011-06-08
        • 2014-01-08
        相关资源
        最近更新 更多