Как сделать виртуальные каталоги nginx доступными в php?
Допустим у меня есть веб-сервер (nginx) server.com
где у меня только один файл php index.php
(отсутствует структура каталогов). Я хочу иметь доступ к чему-либо после server.com - ... Это будет структура url. Например server.com/google.com, server.com/yahoo.com.au etc...
пример http://whois.domaintools.com/google.com
(их нет каталоге, который называется /google.com, да?)
Вопрос 1: как я могу получить доступ к тому, что после 'server.com" от .в PHP
Вопрос 2: могу ли я получить протокол из такого URL? Например server.com/http://www.google.com
или server.com/https://www.google.com
PS Я не уверен, что термин виртуальный каталог здесь используется правильно. Я просто хочу сделать то, что видел в другом месте.
5 ответов
location / {
rewrite ^/(.*)$ /index.php?q=
}
location = /index.php {
#Do your normal php passing stuff here now
}
это то, что вы искали?
в качестве ответа на ваш второй вопрос вы можете проанализировать протокол на php. Nginx не должен этого делать. Для анализа url-адреса можно использовать parse_url
функции
location / {
try_files $uri @dynamic;
}
location @dynamic {
fastcgi_pass backend;
include fastcgi_params;
fastcgi_param PATH_INFO $uri;
fastcgi_param SCRIPT_NAME /index.php;
fastcgi_param SCRIPT_FILENAME /absolute/path/to/index.php;
}
на fastcgi_params
файл в комплекте с nginx
$ cat fastcgi_params
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
#fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param HTTPS $https if_not_empty;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;
и у вас есть доступ ко всем этим параметрам среды fastcgi с помощью встроенного $_SERVER
массив в PHP. http://php.net/manual/en/reserved.variables.server.php
Ну, matzahboy и VBart уже внесли выдержки конфигурации nginx, которые правильно показывают вам, как переписать URL-адрес переменной GET. Но чтобы использовать это, вы должны интерпретировать значение, указанное в $_GET['q']
. Вы не указали правила, которым хотите следовать, поэтому вот предложение.
быть испытанным в этом заказе:
- действительный URL на RFC2396 использование фильтра проверки PHP: тест с завитком, отвечает TRUE для кодов ответа HTTP
- (хозяин.)example.com/path (отсутствует протокол): предположим протокол HTTP, тест на #1.
- host.example.com (только имя хоста): то же самое, что #2
- example.com (только домен): тест как #2, затем тест как www.example.com.
- все остальное: неудача.
если это имеет смысл для вас, то следующий индекс.php может помочь вам начать:
<?php
function http_response($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, TRUE);
curl_setopt($ch, CURLOPT_NOBODY, TRUE); // remove body
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$head = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if (!$head) {
return FALSE;
}
if ($httpCode < 400) {
return $url;
} else {
return FALSE;
}
}
function test_string($q) {
if (filter_var($q, FILTER_VALIDATE_URL)) {
// Matches RFC2396, so let's generate a hit.
return http_response($q);
}
elseif (preg_match('/^([a-z0-9][a-z0-9-]+\.)+[a-z]{2,}(:[0-9]+)?\/.+$/', $q)) {
// Matches: (host.)example.com/path
return http_response("http://" . $q);
}
elseif (preg_match('/^([a-z0-9][a-z0-9-]+\.){2,}[a-z]{2,}$/', $q)) {
// Matches: host.example.com
return http_response("http://" . $q . "/");
}
elseif (preg_match('/^([a-z0-9][a-z0-9-]+\.)+[a-z]{2,}$/', $q)) {
// Matches: example.com
$ret=http_response("http://" . $q . "/");
if ($ret === FALSE) {
return http_response("http://www." . $q . "/");
} else {
return $ret;
}
}
else {
return FALSE;
}
}
$q = $_GET['q'];
//$q = $argv[1]; // for command-line testing
$url = test_string($q);
if ($url === FALSE) {
printf("<p>The URL <strong>%s</strong> is invalid.</p>\n", $q);
} else {
printf("<p>The URL is <strong>%s</strong>.</p>\n", $url);
}
Я не утверждаю, что это самый красивый или самый безопасный код, но, по крайней мере, он реализует стратегию анализа для предоставленных URL-адресов, таких как:
-
http://example.com/https://www.example.net/foo/bar
, -
http://example.com/example.org/foo/bar
или http://example.com/example.org
обратите внимание, что поддержка gopher cURL может быть нарушена и другие протоколы (которые не возвращают HTTP-ответ коды) не поддерживаются кодом выше. Если вам нужно поддерживать протоколы, отличные от HTTP и HTTPS, пожалуйста, скажите об этом в своем вопросе, и я соответствующим образом настрою PHP.
в частности, если вы хотите иметь возможность проверить http://example.com/ping://host.example.net
Это было бы нетрудно, но его нужно было бы закодировать отдельно от бита, обрабатываемого cURL.
используя код nginx matzahboy:
location / {
rewrite ^/(.*)$ /index.php?q=
}
вместе со следующим кодом PHP:
$basis = array(
'scheme' => 'http',
);
$info = array_merge( $base, parse_url( 'www.google.com' ) );
print_r( $info );
который вернет что-то вроде этого для example.com/google.com или example.com/http://google.com/
Array ( [scheme] => http [path] => www.google.com )
обратите внимание, что массив $base содержит значение 'scheme ''http'. Это значение по умолчанию scheme, чтобы вы могли позже сделать что-то вроде
$info['scheme'] . '://' . $info['path'];
что привело бы к http://google.com/
надеюсь, это отвечает на ваш вопрос.
вы думали о переписывании? Я знаю только правила Апачей. В Apache я бы сделал это так:
RewriteCond !^(index\.php|js|css|admin|images|img|png|robots\.txt|sitemap\.xml|sitemap\.xml\.gz|sitemap\.kml|robots\.txt|javascripts|style.css)
RewriteRule ^(.*)$ index.php/?page= [L]
Это передаст все на $_GET['page']
(PHP), за исключением случаев, когда что-либо в URL соответствует index.php
, js
, css
и другие.
если у вас есть какие-либо вопросы, дайте мне знать. Надеюсь, это помогло.