假设我有一个Web服务器(nginx)server.com
,其中我只有一个php文件index.php
(没有目录结构)。我希望能够在server.com之后访问任何内容。它将是一个网址结构。例如server.com/google.com,server.com/yahoo.com.au等...
示例是http://whois.domaintools.com/google.com
(他们没有名为 /google.com 的目录,对吗?)
Q1:如何从 index.php
访问'server.com'之后的内容 Q2:我可以从这样的网址获取协议吗?例如server.com/http://www.google.com
或server.com/https://www.google.com
PS 我不确定这里是否正确使用了虚拟目录这个术语。我只想做我在其他地方看到的事情。
答案 0 :(得分:11)
location / {
rewrite ^/(.*)$ /index.php?q=$1
}
location = /index.php {
#Do your normal php passing stuff here now
}
那是你在找什么?
作为第二个问题的答案,您可以在php中解析协议。 Nginx不需要这样做。要解析网址,您可以使用parse_url
功能
答案 1 :(得分:7)
好吧,matzahboy和VBart已经提供了nginx配置摘录,正确地向您展示了如何将URL重写为GET变量。但是为了使用它,你必须解释$_GET['q']
中提供的值。您尚未指定要遵循的规则,因此这是一个建议。
按此顺序进行测试:
如果这对您有意义,那么以下index.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
请注意,cURL的gopher支持可能会被破坏,上面的代码不支持其他协议(不返回HTTP响应代码)。如果您需要支持HTTP和HTTPS以外的协议,请在您的问题中说明,我会相应地调整PHP。
具体来说,如果你想能够检查http://example.com/ping://host.example.net
它不会很难,但它必须与cURL处理的位分开编码。
答案 2 :(得分:7)
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;
您可以使用PHP中的内置$_SERVER
数组访问所有这些fastcgi环境参数。 http://php.net/manual/en/reserved.variables.server.php
答案 3 :(得分:3)
使用matzahboy的nginx代码:
location / {
rewrite ^/(.*)$ /index.php?q=$1
}
以及以下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数组包含'http'的'scheme'值。这默认为scheme的值,以便您以后可以执行类似
的操作$info['scheme'] . '://' . $info['path'];
希望这能回答你的完整问题。
答案 4 :(得分:2)
RewriteCond $1 !^(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=$1 [L]
这会将所有内容传递给$_GET['page']
(PHP),除非网址中的任何内容与index.php
,js
,css
和其他内容相匹配。
如果您有任何疑问,请与我们联系。希望这有帮助。