Вообще-то, это не лучший способ обойти это. Лучше использовать маршрутизатор, который в основном использует одно правило htaccess, чтобы поймать все запросы, где файл/папка не существует, а затем отправить их в один файл php. Затем этот файл инициализирует маршрутизатор, который определяет, какие параметры основаны на шаблонах, сопоставленных с URI запроса.
Например, используя symfony/routing
component в index.php:
// this is our index.php
// assuming we installed with composer
// and that the vendor dir is one level up from the document root
require_once __DIR__.'/../vendor/autoload.php';
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
// Create a Route Collection
$routes = new RouteCollection();
// lets use an array to define our routes
$routeDefinitions = array(
'foo_archive' => array(
// note the {} wraped parts are params
'path' => '/foo/{p1}/{p2}',
'defaults' => array('controller' => 'foo/archive.php'),
'requirements' => array(
// not a very specific match but lets pretend this matches a
// category or something
'p1'=> '[a-z0-9-_]+',
// matches a date
'p2'=> '[0-9]{4}-[0-9]{2}-[0-9]{2}',
)
// there are other things we can add like options, a requrired host,
// or a specific HTTP mehtod (PUT, GET, POST, etc.)
),
'foo_index' => array(
'path' => '/foo',
'defaults' => array('controller' => 'foo/index.php')
);
);
// lets add our routes
$routeReflector = new \ReflectionClass('Symfony\Component\Routing\Route');
foreach ($routeDefinitions as $name => $def) {
$routes->add($name, $routeReflector->newInstanceArgs($def));
}
$context = new RequestContext($_SERVER['REQUEST_URI']);
$matcher = new UrlMatcher($routes, $context);
$parameters = $matcher->match($_SERVER['PATH_INFO']);
/* so assuming PATH_INFO matched one of our patterns and its
requirements parameters will be an array -
lets pretend PATH_INFO had: /foo/bar/2014-04-20
so we would have an array like:
array(
'controller' => 'archive.php',
'_route' => 'foo_archive',
'p1' => 'bar',
'p2' => '2014-04-20'
)
*/
$controllersDir = realpath(__DIR__ . '/controllers');
$controller = $controllersDir . '/' . $parameters['controller'];
if (file_exists($controller) {
// include our controller and let it do its work
// note that normally you would be instantiating a controller object
// here and invoking some method on it, but for ease of example lets
// just assume it a normal php file with all the logic for the page
include($controller);
} else {
// generate a 500 or 404 error depending on how you want to handle
// it
}
И тогда ваши .htacces будет что-то вроде:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php [QSA,L]
В качестве альтернативы, если вы открыты для него можно использовать Микрофотография, например, Silex, которая проложит все это для вас и даст возможность делать что-то из коробки.
Silex Пример (index.php):
// assuming we installed with composer
// and that the vendor dir is one level up from the document root
require_once __DIR__.'/../vendor/autoload.php';
$app = new Silex\Application();
// you can define routes as closures like this but normally
// i prefer to use classes... You can look at the docs for
// how to do that: http://silex.sensiolabs.org/doc/usage.html#controllers-in-classes
$app->get('/foo/{p1}/{p2}', function($p1, $p2) use($app) {
// do whatever logic you need to do to render the page
});
$app->get('/foo}', function() use($app) {
// do whatever logic you need to do to render the page
});
$app->run();
Почему бы вам не попробовать это самостоятельно и посмотреть, если он работает «без какого-либо вопроса»? – Crembo
Какой грубый комментарий .. – Matheno
Нет, это не сработает, нет правильного синтаксиса –