it-roy-ru.com

Создание поддоменов на лету с помощью .htaccess (PHP)

Я ищу, чтобы создать систему, которая при регистрации создаст поддомен на моем сайте для области учетной записи пользователя. 

например johndoe.website.com

Я думаю, что это будет что-то делать с файлом .htaccess и, возможно, перенаправить в другое место на сайте? Я на самом деле не знаю. Но любая информация, чтобы начать меня, будет принята с благодарностью.

Создание области регистрации не проблема - я делал это много раз. Я просто не уверен, с чего начать с субдомена. 

119
Ben McRae

Быстрое краткое изложение

  1. Вам нужно создать подстановочный домен на вашем DNS-сервере * .website.com
  2. Затем в вашем vhost-контейнере вам нужно будет также указать шаблон * .website.com - Это делается в ServerAlias DOCs
  3. Затем извлеките и проверьте поддомен в PHP и отобразите соответствующие данные.

Длинная версия

1. Создайте шаблонную запись DNS

В настройках DNS вам нужно создать запись домена с подстановочными знаками например, *.example.org. Подстановочный знак выглядит так:

*.example.org.   3600  A  127.0.0.1

2. Включите подстановочный знак в vhost

Далее в конфигурации Apache вам нужно настроить контейнер vhost, который задает подстановочный знак в ServerAlias DOCs директива. Пример контейнера vhost:

<VirtualHost *:80>
  ServerName server.example.org
  ServerAlias *.example.org
  UseCanonicalName Off
</VirtualHost>

3. Определите, на каком поддомене вы находитесь в PHP

Затем в ваших PHP сценариях вы можете найти домен, посмотрев в суперглобальную переменную $_SERVER. Вот пример захвата поддоменов в PHP:

preg_match('/([^.]+)\.example\.org/', $_SERVER['SERVER_NAME'], $matches);
if(isset($matches[1])) {
    $subdomain = $matches[1];
}

Я использовал здесь регулярные выражения, чтобы люди могли заходить на ваш сайт через www.subdomain.example.org или subdomain.example.org.

Если вы никогда не предполагали иметь дело с www. (или другие субдомены), тогда вы можете просто использовать подстроку так:

$subdomain = substr(
                 $_SERVER['SERVER_NAME'], 0,
                 strpos($_SERVER['SERVER_NAME'], '.')
             );

Массовый виртуальный хостинг

Массовый виртуальный хостинг - это схема, немного отличающаяся от описанной выше, в которой вы обычно используете его для размещения множества отдельных веб-сайтов вместо того, чтобы пытаться использовать его в качестве приложения, как предлагает вопрос.

Я задокументировал свою среду массового виртуального хостинга на основе mod_rewrite в посте в моем блоге , на который вы могли бы взглянуть, если вы хотите пойти по этому пути. Также есть, конечно, соответствующая страница руководства Apache .

Apache также имеет внутренний способ работы с массовым виртуальным хостингом, который немного менее гибок, чем метод mod_rewrite, который я использовал. Все это описано на странице руководства Apache Динамически конфигурируемый массовый виртуальный хостинг .

121
Treffynnon

Вы можете разрешить каждый поддомен в первую очередь, а затем проверить, является ли поддомен действительным. Например:

RewriteEngine on
RewriteCond %{HTTP_Host} ^[^.]+\.example\.com$
RewriteRule !^index\.php$ index.php [L]

Внутри index.php вы можете извлечь поддомен, используя:

if (preg_match('/^([^.]+)\.example\.com$/', $_SERVER['HTTP_Host'], $match)) {
    var_dump($match[1]);
}

Но все это требует, чтобы ваш веб-сервер принимал каждое имя субдомена.

12
Gumbo

В дополнение к настройке подстановочного знака DNS вы можете взглянуть на Динамический массовый виртуальный хостинг для Apache именно так я и решил в прошлом

7
Rowland Shaw

Мне было легче делать это с PHP. На самом деле создается поддомен в cPanel и создается папка под нужным доменным именем. Как вы будете делать это вручную в cPanel, но все это делается за миллисекунды с помощью простой функции PHP. Нет необходимости нажимать :)

function create_subdomain($subDomain,$cPanelUser,$cPanelPass,$rootDomain) {

    //  $buildRequest = "/frontend/x3/subdomain/doadddomain.html?rootdomain=" . $rootDomain . "&domain=" . $subDomain;

    $buildRequest = "/frontend/x3/subdomain/doadddomain.html?rootdomain=" . $rootDomain . "&domain=" . $subDomain . "&dir=public_html/subdomains/" . $subDomain;

    $openSocket = fsockopen('localhost',2082);
    if(!$openSocket) {
        return "Socket error";
        exit();
    }

    $authString = $cPanelUser . ":" . $cPanelPass;
    $authPass = base64_encode($authString);
    $buildHeaders  = "GET " . $buildRequest ."\r\n";
    $buildHeaders .= "HTTP/1.0\r\n";
    $buildHeaders .= "Host:localhost\r\n";
    $buildHeaders .= "Authorization: Basic " . $authPass . "\r\n";
    $buildHeaders .= "\r\n";

    fputs($openSocket, $buildHeaders);
        while(!feof($openSocket)) {
           fgets($openSocket,128);
        }
    fclose($openSocket);

    $newDomain = "http://" . $subDomain . "." . $rootDomain . "/";

   //  return "Created subdomain $newDomain";

}
5
Adrian P.

Самый простой способ - перенаправить все субдомены (с подстановочными знаками *), чтобы они указывали на ваш /wwwroot. Затем поместите .htaccess в эту папку со следующим кодом:

RewriteCond %{ENV:REDIRECT_SUBDOMAIN} ="" 
RewriteCond %{HTTP_Host} ^([a-z0-9][-a-z0-9]+)\.domain\.com\.?(:80)?$ [NC] 
RewriteCond %{DOCUMENT_ROOT}/%1 -d 
RewriteRule ^(.*) %1/$1 [E=SUBDOMAIN:%1,L] 
RewriteRule ^ - [E=SUBDOMAIN:%{ENV:REDIRECT_SUBDOMAIN},L]

Это позволит сделать каждую подпапку в папке/wwwroot доступной через поддомен (foldername.domain.com).

Найдено это несколько лет назад на http://www.webmasterworld.com/Apache/3163397.htm

5
Glavić

Mod_vhost_alias это правильный модуль для этого.

Одной строкой вы можете указать Apache, что нужно искать в нужном месте, с хэшированием каталогов и т.д..

VirtualDocumentRoot /http/users/%3.1/%3.2/%3

сказал бы Apache, чтобы установить корень документа в/http/users/s/u/поддомен при запросе для subdomain.yourdomain.com

4
Julien Tartarin

Это не имеет ничего общего с .htaccess. Вам нужно будет настроить записи DNS и виртуальный хостинг для поддоменов.

4
chaos

Я думаю, что подстановочный DNS с Apache Dynamic Mass Virtual Hosting также является разумным решением. Хотя я никогда не пробовал.

Если вам нужно масштабировать до нескольких серверов или другие решения просто не работают, я рекомендую использовать DNS-сервер, управляемый базой данных. Я успешно использовал MyDNS в прошлом. Поскольку он использует MySQL (или PostgreSQL), вы можете обновлять свой DNS на лету с помощью PHP или с помощью чего-либо еще. Код не выглядит так, как будто он был обновлен в течение некоторого времени, но это DNS и, следовательно, не совсем урезанный. 

0
Barrett Conrad

Методы создания поддомена

Прежде всего, вы должны создать настройки DNS с помощью редактора DNS вашего сервера.

  1. Создайте запись A в настройках DNS, используя подстановочный знак Host * в ip-адресе сервера. 

    * 1400 IN A ip_address

  2. Создайте еще раз A в настройках DNS с Host @ или domain_name.tld в ip-адресе сервера. tld означает домены верхнего уровня или расширение доменов, таких как .com, .org и т. д.

    @ 1400 IN A ip_address или же domain_name.tld 1400 IN A ip_address

  3. Создать CNAME запись как:

    www 1400 IN A domainname.tld

  4. Создайте поддомен с символом подстановки * наподобие *.domain.tld
  5. Создайте htaccess в вашем каталоге поддоменов *.domain.tld и поместите этот код:

    Options +FollowSymLinks 
    RewriteEngine On 
    RewriteBase /
    RewriteRule ^([aA-zZ0-9]+)$ index.php?data=$1
    RewriteCond %{HTTP_Host} ^([aA-zZ0-9]+)\.([aA-zZ0-9-]+)\.([aA-zZ]+)
    RewriteRule ([aA-zZ0-9]+) index.php?data=%1
    

    Проверьте свой первый субдомен подстановочного знака, например example.domainname.tld

Если вас не интересует передача данных в качестве параметра с помощью htaccess, вы также можете получить данные, используя следующую кодировку:

define("SUBDOMAIN_PARENT","domainname.tld");   
class getData
    {
         function __construct()
        {
            $this->data="";
            $http_Host=$_SERVER['HTTP_Host'];
         $subdom_data= str_replace(SUBDOMAIN_PARENT,"",$http_Host);
         $expl_subdom_data=explode(".",$subdom_data);
      $expl_subdom_data=array_filter($expl_subdom_data);

            if($expl_subdom_data!=NULL)
            {
           $this->data=end($expl_subdom_data);
            }
       }
    }
$GLOBALS['get_data']=new getData();

и используйте вашу глобальную переменную в любом месте, например global $get_data.

echo $get_data->data; //example

(примечание: этот класс в основном используется для получения точного имени субдомена из http_Host. потому что некоторые дополнительные имена, объединенные перед вашим поддоменом, также применимы, как www.example.domainname.tld. Это возвращение $_GET['data']='wwww', поэтому я предлагаю использовать $_SERVER['http_Host'] для получения точных значений вместо использования $_SERVER['query_string'] или передал параметры htaccess на вашей странице индекса)

6.Ускорьте выполнение этого поддомена с использованием подстановочных знаков, используя N секунд в TTL - DNS SETTINGS.

7.Проверьте поддомен по истечении указанного вами времени ttl (600 - 10 минут), например => http://abc.domain.tld

(примечание: поддомены с подстановочными знаками не переопределяют существующие субдомены. Поскольку приоритет всегда существует для существующих субдоменов)

0
karthikeyan ganesan