Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
604 views
in Technique[技术] by (71.8m points)

apache - Pretty URLs in PHP frameworks

I know that you can add rules in htaccess, but I see that PHP frameworks don't do that and somehow you still have pretty URLs. How do they do that if the server is not aware of the URL rules?

I've been looking Yii's url manager class but I don't understand how it does it.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is usually done by routing all requests to a single entry point (a file that executes different code based on the request) with a rule like:

# Redirect everything that doesn't match a directory or file to index.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.php [L]

This file then compares the request ($_SERVER["REQUEST_URI"]) against a list of routes - a mapping of a pattern matching the request to a controller action (in MVC applications) or another path of execution. Frameworks often include a route that can infer the controller and action from the request itself, as a backup route.

A small, simplified example:

<?php

// Define a couple of simple actions
class Home {
    public function GET() { return 'Homepage'; }
}

class About {
    public function GET() { return 'About page'; }
}

// Mapping of request pattern (URL) to action classes (above)
$routes = array(
    '/' => 'Home',
    '/about' => 'About'
);

// Match the request to a route (find the first matching URL in routes)
$request = '/' . trim($_SERVER['REQUEST_URI'], '/');
$route = null;
foreach ($routes as $pattern => $class) {
    if ($pattern == $request) {
        $route = $class;
        break;
    }
}

// If no route matched, or class for route not found (404)
if (is_null($route) || !class_exists($route)) {
    header('HTTP/1.1 404 Not Found');
    echo 'Page not found';
    exit(1);
}

// If method not found in action class, send a 405 (e.g. Home::POST())
if (!method_exists($route, $_SERVER["REQUEST_METHOD"])) {
    header('HTTP/1.1 405 Method not allowed');
    echo 'Method not allowed';
    exit(1);
}

// Otherwise, return the result of the action
$action = new $route;
$result = call_user_func(array($action, $_SERVER["REQUEST_METHOD"]));
echo $result;

Combined with the first configuration, this is a simple script that will allow you to use URLs like domain.com/about. Hope this helps you make sense of what's going on here.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...