如何在php中访问nginx虚拟目录?

时间:2012-07-17 11:18:52

标签: php nginx

假设我有一个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.comserver.com/https://www.google.com

PS 我不确定这里是否正确使用了虚拟目录这个术语。我只想做我在其他地方看到的事情。

5 个答案:

答案 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']中提供的值。您尚未指定要遵循的规则,因此这是一个建议。

按此顺序进行测试:

  1. 使用PHP的验证过滤器每个RFC2396的有效URL :使用cURL进行测试,对HTTP响应代码响应为< 400,其他任何事情都错了。
  2. (host。)example.com/path (缺少协议):假设HTTP协议,每#1进行一次测试。
  3. host.example.com (仅限主机名):与#2相同
  4. example.com (仅限域名):测试为#2,然后测试为 www.example.com
  5. 其他:失败。
  6. 如果这对您有意义,那么以下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'];

会导致http://google.com/

希望这能回答你的完整问题。

答案 4 :(得分:2)

你想过改写吗?我只知道Apache的规则。在Apache中我会这样做:

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.phpjscss和其他内容相匹配。

如果您有任何疑问,请与我们联系。希望这有帮助。