开发者

Apache mod_rewrite and PHP GET Arrays

开发者 https://www.devze.com 2022-12-10 13:13 出处:网络
I want to have a url like http://localhost/folder1/folder2/folder3/fil开发者_Go百科e Then i want mod_rewrite to convert it to $_GET[\'d\'] in the url it would look like d[]=folder1&d[]=folder2&

I want to have a url like http://localhost/folder1/folder2/folder3/fil开发者_Go百科e Then i want mod_rewrite to convert it to $_GET['d'] in the url it would look like d[]=folder1&d[]=folder2&d[]=folder3

Is this possible?

Thank You.


Yes it is possible:

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

But mod_rewrite is not really suited for that kind of work. In fact, you can quickly create an infinite loop with the N flag.

You should rather use PHP to extract the requested URL path its segments:

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

Then use this single rule to rewrite the requests to your file:

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


I don't know of a way to do it automatically, but you can retrieve what the requested URL was from $_SERVER['REQUEST_URI'] and perform your own string processing on it to extract the information you want.


This is what I do for Seach Engine Friendly URLs with unlimited amount of levels. It also gives you the option of allowing query strings or not, and will not rewrite urls to real folders or files like images, CSS and JavaScript.

Apache...

# 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;
}

?>

I then have a routing file which handles the request with the appropriate functions. It might seem like a lot of code but helps keep things organised and efficient as I only include the classes/functions that the request requires.

I'm considering releasing a library of code (Urgh, not another framework I hear you cry) I use for my projects so feel free to use the code under GPL v3.

Hope this helps.


This should give you a rough idea of what you'd need...

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

If you want to support an arbitrary number of directories, rather than 3 fixed directories, that'll be another issue altogether.


A good technique to use is a front controller (part of the MVC design pattern). A front controller is a (PHP) file to which every request that your website gets is routed. The front controller then dispatches the request to other files depending on the kind of request (look at page X, submission of form Y, etc). For example you can "cut up" the url of the request, using the technique described by @Ray Hidayat, and look at it to determine which part of your site should handle and or answer the request.

For example: Zend Framework and Drupal both use this technique. In those cases, and I think in most cases, index.php in the root of the site is the front controller, so www.example.com/index.php

You can use mod_rewrite to route every request to that the front controller.

RewriteEngine on
RewriteRule .* index.php

You can use the following mod_rewrite script for images/files/CSS and javascript library.

RewriteEngine off

Good luck!

0

精彩评论

暂无评论...
验证码 换一张
取 消