Я ищу портативный способ получить (удобную) переменную $_SERVER['PATH_INFO']
.
Прочитав некоторое время, выясняется, что PATH_INFO
происходит из CGI / 1.1, и мой не всегда присутствует во всех конфигурациях.
Каков наилучший (в основном безопасный) способ получить эту переменную – помимо ее извлечения вручную (проблема безопасности).
Ну, я (почти) уверен, что без использования суперглобальных ключей $_SERVER
предоставление альтернативного способа определения PATH_INFO
просто невозможно, так как это позволяет сначала перечислить все ключи $ _SERVER, которые мы можем использовать:
Мы, очевидно, должны игнорировать последние два. Теперь мы должны ( я не знаю этого по факту, я просто предполагаю, потому что вы так сказали ) фильтруют все ключи, которые существуют в указанной вами ссылке ( какой BTW является автономным банкоматом ), что оставляет нас со следующими ключами :
Что касается вашего комментария к 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
нет наложений ) остается только одно решение:
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
.
Если это не сработает для вас, извините, но я могу придумать что-нибудь еще.
РЕДАКТИРОВАТЬ – Еще немного чтения для вас:
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:
2) Вы хотите иметь PATH_INFO во всех OS + HTTP-серверах + сочетание PHP:
Хммм … 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) Используя свои глубокие и всесторонние знания о каждой комбинации 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». (Проблема переносимости переносится на клиентскую сторону.)
Этот код, связанный здесь, делает это.
Это мое скромное мнение и подход к проблеме.
Как вы думаете?
Я не видел комментариев или ссылку перед публикацией. Вот что-то, что может сработать, основываясь на том, что приведенная выше страница дает в качестве переменных 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'];