Отличный способ заставить единую точку входа (фронт-контроллер) работать с наиболее распространенными настройками веб-сервера

Это не будет легко, спасибо всем читающим это!:)

6 дней спустя: только кстати: это мой второй подход для решения этой проблемы: пересылка всех запросов в один файл index.php для несуществующих файлов, но * включая * сам index.php

И вот реальный код, который я пытаюсь решить это: https://github.com/kpion/point1

; TL; DR;

Как мы можем узнать, что является корнем документа независимо от настройки веб-сервера (nginx/apache/apache с hattacces). В случае, когда корнем htaccess является местоположение самого htaccess.

Вступление

Я постараюсь быть максимально информативным:)

Это все о пересылке всех запросов в один файл index.php (исключая существующие файлы). Да, довольно распространенные задачи.

Проект живет в: /var/www/html/point/point1

Это может быть как dev, так и prod env.

Я хочу, чтобы все запросы отправлялись в "index.php" с информацией о том, что на самом деле было запрошено.

подробности

Предполагая, что хостом проекта является 'point1', и он живет в /var/www/html/point/point1 -

Когда пользователь вводит http://point1/foo/bar - я хочу, чтобы веб-сервер запустил /var/www/html/point/index.php и отправил на него информацию о запрошенном URL (в данном случае /foo/bar).

Я хочу знать "foo" и "bar";

Это довольно просто с vhosts на apache и nginx. Например, в Apache:

<directory /var/www/html/point/point1>
      RewriteEngine On
      RewriteCond %{SCRIPT_FILENAME} !-d
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteRule ^.*$ index.php
</directory>  

И nginx:

location /{
    server_name point1;
    root /var/www/html/point/point1;
    try_files $uri $uri/ /index.php$is_args$args
}
location ~ \.php$ {
 #...handle php
}

Это легко, потому что тогда мы можем легко получить "оставшуюся часть" в

 var_dump($_SERVER['REQUEST_URI']); 

"REQUEST_URI" var сообщает нам, что находится после "host".

Хорошо.

Теперь приходит.htaccess. Предполагая, что у пользователя нет доступа к настройкам веб-сервера, вот типичный способ:

RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,L]

проблема

Я хочу, чтобы мой сценарий обрабатывал все эти ситуации. Это легко, если мы ограничим это "vhosts". В этом случае "корень документа" известен. Вот почему это работает:

$request = $_SERVER['REQUEST_URI'];
$file =  $_SERVER['REQUEST_URI'][1];
$method =  $_SERVER['REQUEST_URI'][2];

Мы знаем, что $file теперь относится к $_SERVER['DOCUMENT_ROOT'];

За исключением того, что когда я хочу поддержать.htaccess, это не так просто. Потому что я не знаю "document_root", то есть знаю - но это часто корень всех проектов - /var/www/html

Итак, что я получаю в "$_SERVER['REQUEST_URI']", это "/point/point1/foo/bar", и я не знаю, какая часть отвечает за "foo" и "bar";

Кажется, что в Symfony эта часть кода имеет дело с этим:

https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpFoundation/Request.php

Но я не совсем уверен.

Что я сделал, так это то, что я добавил в.htaccess это:

RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,L]
SetEnv USE_URI_PROTOCOL PATH_INFO

Как вы можете видеть, я устанавливаю переменную окружения, чтобы потом использовать ее в моей единственной точке входа php:

    $uriProtocol = getenv('USE_URI_PROTOCOL')?:'REQUEST_URI';
    $request = isset($_SERVER[$uriProtocol])?$_SERVER[$uriProtocol]:'';

    //getting only what's before ? (uri query string) if it exists 
    if (($pos = strpos($request, '?')) !== false){
        $request = substr($request, 0, $pos);
    } 

    //trimming slashes
    $request = trim($request, '/');
    $requestArray  = empty($request)? [] : explode('/', $request);

    var_dump('controller',$requestArray[0] ?? 'undefined');
    var_dump('method',$requestArray[1] ?? 'undefined');

Это работает. Но что-то говорит мне, что это не очень круто.

Надеюсь, мне ясно здесь? Речь идет об одном простом решении, которое можно сделать на передней панели контроллера.

0 ответов

Другие вопросы по тегам