Портативный и безопасный способ получить PATH_INFO

Я ищу портативный способ получить (удобную) переменную $_SERVER['PATH_INFO'] .

Прочитав некоторое время, выясняется, что PATH_INFO происходит из CGI / 1.1, и мой не всегда присутствует во всех конфигурациях.

Каков наилучший (в основном безопасный) способ получить эту переменную – помимо ее извлечения вручную (проблема безопасности).

    Ну, я (почти) уверен, что без использования суперглобальных ключей $_SERVER предоставление альтернативного способа определения PATH_INFO просто невозможно, так как это позволяет сначала перечислить все ключи $ _SERVER, которые мы можем использовать:

    • 'PHP_SELF'
    • 'СТРОКА ЗАПРОСА'
    • 'SCRIPT_FILENAME'
    • 'PATH_TRANSLATED'
    • 'SCRIPT_NAME'
    • 'REQUEST_URI'
    • 'PATH_INFO'
    • 'ORIG_PATH_INFO'

    Мы, очевидно, должны игнорировать последние два. Теперь мы должны ( я не знаю этого по факту, я просто предполагаю, потому что вы так сказали ) фильтруют все ключи, которые существуют в указанной вами ссылке ( какой BTW является автономным банкоматом ), что оставляет нас со следующими ключами :

    • 'PHP_SELF'
    • 'SCRIPT_FILENAME'
    • 'REQUEST_URI'

    Что касается вашего комментария к Anthonys, ответьте :

    Теперь вы просто жонглируете переменными. SCRIPT_FILENAME является частью спецификации CGI. Он недоступен, если PATH_INFO недоступен. Что касается REQUEST_URI , это особенность mod_rewrite от apache. – LiraNuna

    Я запускаю LightTPD / 1.4.20-1 (Win32) с PHP 5.3.0, поскольку CGI, cgi.fix_pathinfo = 1 и $_SERVER['REQUEST_URI'] мне очень доступны , я также помню, что использовал эту же переменную в в те дни, когда никто не использовал mod_rewrite поэтому моя честная скромная догадка заключается в том, что в этом mod_rewrite вы ошибаетесь . Что касается ключа SCRIPT_FILENAME я не могу проверить этот банкомат. Тем не менее, если мы очень сильно закрываем глаза и считаем, что вы правы, что оставляет нас только с одной переменной:

    • 'PHP_SELF'

    Я не пытаюсь быть суровым здесь (и я по-прежнему считаю, что есть больше решений), но если PHP_SELF – это единственный ключ, с которым вы хотите работать ( при условии, что на самом PHP_SELF нет наложений ) остается только одно решение:

     function PATH_INFO() { if (array_key_exists('PATH_INFO', $_SERVER) === true) { return $_SERVER['PATH_INFO']; } $whatToUse = basename(__FILE__); // see below return substr($_SERVER['PHP_SELF'], strpos($_SERVER['PHP_SELF'], $whatToUse) + strlen($whatToUse)); } 

    Эта функция должна работать, однако могут возникнуть некоторые проблемы с использованием константы __FILE__ так как она возвращает путь к файлу, в котором __FILE__ константа __FILE__ а не путь к запрошенному скрипту PHP , поэтому именно поэтому $ whatToUse существует для: sou вы можете заменить его 'SCRIPT_FILENAME' или если вы действительно верите в то, что вы говорите, просто используйте '.php' .

    Вы также должны прочитать это, почему бы не использовать PHP_SELF .

    Если это не сработает для вас, извините, но я могу придумать что-нибудь еще.

    РЕДАКТИРОВАТЬ – Еще немного чтения для вас:

    • Drupal request_uri () (почему они продолжают говорить, что REQUEST_URI специфичен для Apache?)
    • PHP_SELF vs PATH_INFO против SCRIPT_NAME и REQUEST_URI

    Я думаю, что здесь есть трюк, чтобы получить «path_info» по-другому:

     $path_info = str_replace($_SERVER['SCRIPT_NAME'], '', $_SERVER['PHP_SELF']); 

    Например, доступ к URL-адресу, например: http://somehost.com/index.php/some/path/here , значением $path_info будет: "/some/path/here"

    Он работал для меня на разных серверах apache, работающих на Windows и Linux, но я не уверен на 100%, если он «безопасен» и «переносим», но я не тестировал его в конфигурациях серверов «ВСЕ», но, похоже, работает …

     function getPathInfo() { if (isset($_SERVER['PATH_INFO'])) { return $_SERVER['PATH_INFO']; } $scriptname = preg_quote($_SERVER["SCRIPT_NAME"], '/'); $pathinfo = preg_replace("/^$scriptname/", "", $_SERVER["PHP_SELF"]); return $pathinfo; } 

    Изменить: без SCRIPT_NAME и при условии, что у вас есть DOCUMENT_ROOT (или можете определить / открыть его самостоятельно), и если у вас есть SCRIPT_FILENAME, тогда:

     function getPathInfo() { if (isset($_SERVER['PATH_INFO'])) { return $_SERVER['PATH_INFO']; } $docroot = preg_quote($_SERVER["DOCUMENT_ROOT"], "/"); $scriptname = preg_replace("/^$docroot/", "", $_SERVER["SCRIPT_FILENAME"]); $scriptname = preg_quote($scriptname, "/"); $pathinfo = preg_replace("/^$scriptname/", "", $_SERVER["PHP_SELF"]); return $pathinfo; } 

    Также @ Anthony (недостаточно повторить комментарий, извините): Использование str_replace () будет соответствовать в любом месте строки. Это не гарантированно работает, вы хотите только совместить его с самого начала. Кроме того, ваш метод только перехода 1 слэш назад (через strrpos) для определения SCRIPT_NAME будет работать, только если скрипт находится под корнем, поэтому вы лучше разбираетесь в скрипте_filename против docroot.

    Это зависит от определений «портативный» и «безопасный».

    Позвольте мне посмотреть, понял ли я:

    1) Вы не заинтересованы в CLI:

    • вы упомянули PHP / CGI
    • PATH_INFO – это часть URL-адреса; поэтому имеет смысл обсуждать PATH_INFO при доступе к сценарию из URL-адреса (т. е. из HTTP-соединения, обычно запрашиваемого браузером)

    2) Вы хотите иметь PATH_INFO во всех OS + HTTP-серверах + сочетание PHP:

    • ОС может быть Windows, Linux и т. Д.
    • HTTP-сервером может быть Apache 1, Apache 2, NginX, Lighttpd и т. Д.
    • PHP может быть версией 4, 5, 6 или любой версией

    Хммм … PHP_INFO, в массиве $ _SERVER, предоставляется PHP скрипту, исполняемому только при определенных условиях, в зависимости от программного обеспечения, упомянутого выше. Это не всегда доступно. То же самое верно для всего массива $ _SERVER!

    Вкратце: « $ _SERVER зависит от сервера » … поэтому переносимое решение не может ретранслировать на $ _SERVER … (просто для примера: у нас есть учебник по настройке переменных PHP / CGI $ _SERVER на NginX HTTP-сервер в kbeezie.com/view/php-self-path-nginx/)

    3) Несмотря на то, что было упомянуто выше, стоит упомянуть, что если у нас есть полный URL-адрес, который был запрошен как строка, можно получить от него PATH_INFO, применяя регулярные выражения и другие строковые функции PHP, безопасно (также проверяя входная строка как допустимый URI).

    Итак, при условии, что у нас есть строка URL … тогда ДА, МЫ ИМЕЕМ портативный и безопасный способ определить PATH_INFO.


    Теперь у нас есть две четкие и целенаправленные проблемы внедрения:

    1. Как получить URL-адрес?
    2. Как получить PATH_INFO из URL?

    Вот несколько возможных возможностей: вот возможный подход:

    Как получить URL-адрес?

    1) Используя свои глубокие и всесторонние знания о каждой комбинации HTTP-сервера + OS + PHP, проверьте и попробуйте каждую возможность получить URL-адрес из массива $ _SERVER (проверьте «PHP_SELF», «QUERY_STRING», «SCRIPT_FILENAME», «PATH_TRANSLATED», , 'SCRIPT_NAME', 'REQUEST_URI', 'PATH_INFO', 'ORIG_PATH_INFO', 'HTTP_HOST', 'DOCUMENT_ROOT' или что-то еще)

    2) Если предыдущий шаг завершился неудачно, сделайте PHP-скрипт возвратом javascript-кода, который возвращает информацию «document.URL». (Проблема переносимости переносится на клиентскую сторону.)

    Как получить PATH_INFO из URL?

    Этот код, связанный здесь, делает это.

    Это мое скромное мнение и подход к проблеме.

    Как вы думаете?

    Я не видел комментариев или ссылку перед публикацией. Вот что-то, что может сработать, основываясь на том, что приведенная выше страница дает в качестве переменных CGI:

     function getPathInfo() { if (isset($_SERVER['PATH_INFO'])) { return $_SERVER['PATH_INFO']; } $script_filename = $_SERVER["SCRIPT_FILENAME"]; $script_name_start = strrpos($script_filename, "/"); $script_name = substr($script_filename, $script_name_start); //With the above you should have the plain file name of script without path $script_uri = $_SERVER["REQUEST_URI"]; $script_name_length = strlen($script_name); $path_start = $script_name_length + strpos($script_name, $script_uri); //You now have the position of where the script name ends in REQUEST_URI $pathinfo = substr($script_uri, $path_start); return $pathinfo; } 

    вы можете попробовать

     $_ENV['PATH_INFO']; or getenv('PATH_INFO'];