Как сделать виртуальные каталоги 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']. Вы не указали правила, которым хотите следовать, поэтому вот предложение.

быть испытанным в этом заказе:

  1. действительный URL на RFC2396 использование фильтра проверки PHP: тест с завитком, отвечает TRUE для кодов ответа HTTP
  2. (хозяин.)example.com/path (отсутствует протокол): предположим протокол HTTP, тест на #1.
  3. host.example.com (только имя хоста): то же самое, что #2
  4. example.com (только домен): тест как #2, затем тест как www.example.com.
  5. все остальное: неудача.

если это имеет смысл для вас, то следующий индекс.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 и другие.

если у вас есть какие-либо вопросы, дайте мне знать. Надеюсь, это помогло.