Crea sottodomini al volo con .htaccess (PHP)


122

Sto cercando di creare un sistema che al momento della registrazione creerà un sottodominio sul mio sito web per l'area dell'account utente.

ad esempio johndoe.website.com

Penso che sarebbe qualcosa a che fare con il file .htaccess e possibilmente reindirizzare a un'altra posizione sul sito web? In realtà non lo so. Ma qualsiasi informazione per iniziare sarebbe molto apprezzata.

La creazione di un'area di registrazione non è il problema: l'ho fatto molte volte. Non sono sicuro da dove iniziare con il sottodominio.

Risposte:


125

La rapida carrellata

  1. Devi creare un dominio con caratteri jolly sul tuo server DNS * .website.com
  2. Quindi nel tuo contenitore vhost dovrai specificare anche il carattere jolly * .website.com - Questo viene fatto nei ServerAlias DOC
  3. Quindi estrai e verifica il sottodominio in PHP e visualizza i dati appropriati

La versione lunga

1. Creare una voce DNS con caratteri jolly

Nelle impostazioni DNS è necessario creare una voce di dominio con caratteri jolly come *.example.org. Una voce con caratteri jolly ha questo aspetto:

*.example.org.   3600  A  127.0.0.1

2. Includere il carattere jolly in vhost

Successivamente nella configurazione di Apache è necessario impostare un contenitore vhost che specifichi il carattere jolly nella direttiva ServerAlias DOCs . Un esempio di container vhost:

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

3. Individua il sottodominio in PHP

Quindi nei tuoi script PHP puoi scoprire il dominio guardando nella $_SERVERvariabile super globale. Ecco un esempio di acquisizione del sottodominio in PHP:

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

Ho usato regex qui per consentire alle persone di visitare il tuo sito tramite www.subdomain.example.org o subdomain.example.org.

Se non ti aspetti mai di avere a che fare con www. (o altri sottodomini) allora potresti semplicemente usare una sottostringa in questo modo:

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

Hosting virtuale di massa

L'hosting virtuale di massa è uno schema leggermente diverso da quanto sopra in quanto lo usereste solitamente per ospitare molti siti Web distinti piuttosto che tentare di utilizzarlo per alimentare un'applicazione come propone la domanda.

Ho già documentato il mio ambiente di hosting virtuale di massa basato su mod_rewrite in un post sul mio blog , che potresti guardare se questa è la strada che desideri prendere. C'è anche, ovviamente, la rispettiva pagina di manuale di Apache .

Apache ha anche un modo interno di gestire l'hosting virtuale di massa che è leggermente meno flessibile del metodo mod_rewrite che ho usato. Tutto questo è descritto nella pagina di manuale dell'hosting virtuale di massa configurato dinamicamente Apache .


A condizione che tu possa usare wildcard subdomains, vedi la mia soluzione per farlo in .htaccess.
Dan Bray

Non credo che un host virtuale possa essere aggiunto da .htaccess, mi rende anche nervoso per la sicurezza. Dalla 2.4, dovrebbe essere possibile selezionare una directory di base dipendente dal nome host (ma anche il metodo di Dan ha alcuni problemi) Considera:RewriteRule "^/?(.*)" "http://%{HTTP_HOST}/%{HTTP_HOST}/$1" [L,R,NE]
symcbean

Si noti che il codice PHP che implementa questo NON DEVE essere eseguito come uid del server web (dovrebbe essere come utente dedicato tramite sudo)
symcbean

12

Potresti consentire in primo luogo ogni sottodominio e poi controllare se il sottodominio è valido. Per esempio:

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

All'interno di index.phpè possibile estrarre il sottodominio utilizzando:

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

Ma tutto ciò richiede che il tuo server web accetti ogni nome di sottodominio.


3
Inoltre, richiede che il tuo server DNS risolva ogni nome di sottodominio.
caos

1
L'ho visto fare su altri siti Web, sicuramente non devono risolvere ogni sottodominio ogni volta che lo fanno?
Ben McRae,

1
Beh, dipende da cosa intendi con questo. Se vuoi dire, ogni volta che qualcuno su Internet cerca foo.somedomain.com e non è memorizzato nella cache, il loro server DNS deve risolverlo, quindi sì.
caos

Se intendi, devono impostare i record DNS specificamente per ogni dominio, vedi la risposta di Treffynnon.
caos

ok grazie per quello. non capisco bene cosa significa Treffynnon specificando il carattere jolly nel vhost?
Ben McRae,


6

Ho trovato più facile farlo con PHP. In effetti sta creando un sottodominio all'interno di cPanel e crea la tua cartella con il nome di dominio desiderato. Come lo farai manualmente in cPanel ma tutto è fatto in millisecondi da una semplice funzione PHP. Nessun clic necessario :)

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";

}

Controlla se è stato creato con successo su cPanel e, controlla tramite FTP (o file manager), cosa c'è dentro la cartella public_html / subdomain. Se hai un'impostazione cPanel che aggiunge elementi quando crei un sottodominio, ciò non è correlato alla creazione di sottodomini al volo.
Adrian P.

No non è stato creato in cPanel
Ruchi

Quindi non hai abbastanza permessi su cPanel. Questo è un VPS di hosting condiviso o un server dedicato?
Adrian P.

Possono essere molteplici i motivi per non creare il sottodominio. Non correlato allo script sopra ma con la tua configurazione DNS. Leggilo e chiedi aiuto sui forum di cPanel. forums.cpanel.net/threads/subdomains-not-working.228132
Adrian P.

5

Il modo più semplice è reindirizzare tutti i sottodomini (con carattere jolly *) in modo che puntino al tuo / wwwroot. Quindi metti .htaccess in questa cartella con il seguente codice:

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]

In questo modo, ogni sottocartella della cartella / wwwroot sarà accettabile tramite sottodominio (nomecartella.dominio.com).

Trovato anni fa su http://www.webmasterworld.com/apache/3163397.htm


4

Non ha niente a che fare con .htaccess. Dovrai configurare i record DNS e l'hosting virtuale per i sottodomini.


4

Mod_vhost_alias è il modulo giusto per farlo.

Con una riga puoi dire ad Apache di guardare nel posto giusto, con l'hashing delle directory, ecc. Ad esempio, la riga:

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

direbbe ad Apache di impostare la root del documento su / http / utenti / s / u / sottodominio quando richiesto per sottodominio.tuodominio.com


0

Penso che anche il DNS wild card con Dynamic Mass Virtual Hosting di Apache sia una soluzione ragionevole. Anche se non l'ho mai provato.

Se hai la necessità di scalare su più server o le altre soluzioni semplicemente non funzionano per te, ti consiglio di utilizzare un server DNS basato su database. Ho utilizzato con successo MyDNS in passato. Dato che usa MySQL (o PostgreSQL) puoi aggiornare il tuo DNS al volo con PHP o qualsiasi altra cosa. Il codice non sembra essere stato aggiornato da un po ', ma è DNS e quindi non esattamente all'avanguardia.


0

Metodi per la creazione di sottodomini con caratteri jolly

Per prima cosa devi creare le impostazioni DNS utilizzando l'editor DNS del tuo server.

  1. Crea Arecord nelle impostazioni DNS con il carattere *jolly dell'host nell'indirizzo IP del server.

    * 1400 IN A ip_address

  2. Crea ancora una volta un Arecord nelle impostazioni DNS con host @o domain_name.tldnell'indirizzo IP del server. tld indica i domini di primo livello o l'estensione dei domini come .com, .org, ecc ...

    @ 1400 IN A ip_address o domain_name.tld 1400 IN A ip_address

  3. Crea CNAMErecord come:

    www 1400 IN A domainname.tld

  4. Crea il sottodominio con *caratteri jolly simili*.domain.tld
  5. Crea htaccess nella directory del tuo sottodominio *.domain.tlde inserisci questo codice:

    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

    Prova il tuo primo sottodominio con caratteri jolly come example.domainname.tld

Se non sei interessato a passare i dati come parametro utilizzando htaccess, puoi anche ottenere i dati utilizzando la seguente codifica:

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();

e usa la tua variabile globale in qualsiasi posto come global $get_data.

echo $get_data->data; //example

(nota: questa classe viene utilizzata principalmente per ottenere il sottodominio esatto da http_host. perché anche alcuni nomi extra combinati prima del tuo sottodominio sono applicabili come www.example.domainname.tld. Questo ritorno $_GET['data']='wwww'Quindi il mio suggerimento è di utilizzare $_SERVER['http_host']per ottenere i valori esatti invece di utilizzare i $_SERVER['query_string']parametri htaccess o passati in la tua pagina indice)

6.Accelerare l'esecuzione di questi sottodomini jolly utilizzando N secondi in TTL - IMPOSTAZIONI DNS.

7.Controlla il sottodominio dopo il tempo ttl dato (600-10 minuti) come => http://abc.domain.tld

(nota: i sottodomini con caratteri jolly non sovrascrivono i sottodomini esistenti. Perché la prima priorità è sempre per i tuoi sottodomini esistenti)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.