Erstellen Sie Subdomains im laufenden Betrieb mit .htaccess (PHP)

122

Ich möchte ein System erstellen, das bei der Anmeldung eine Subdomain auf meiner Website für den Benutzerkontobereich erstellt.

zB johndoe.website.com

Ich denke, es würde etwas mit der .htaccess-Datei zu tun haben und möglicherweise an einen anderen Ort auf der Website umleiten? Ich weiß es eigentlich nicht. Aber jede Information, um mich anzufangen, wäre sehr dankbar.

Das Erstellen eines Anmeldebereichs ist nicht das Problem - das habe ich schon oft gemacht. Ich bin mir nur nicht sicher, wo ich mit der Subdomain anfangen soll.

Ben McRae
quelle

Antworten:

125

Der schnelle Überblick

  1. Sie müssen eine Platzhalterdomäne auf Ihrem DNS-Server * .website.com erstellen
  2. Dann müssen Sie in Ihrem vhost-Container auch den Platzhalter angeben * .website.com - Dies erfolgt in den ServerAlias DOCs
  3. Extrahieren und überprüfen Sie dann die Subdomain in PHP und zeigen Sie die entsprechenden Daten an

Die lange Version

1. Erstellen Sie einen Platzhalter-DNS-Eintrag

In Ihren DNS-Einstellungen müssen Sie einen Platzhalter-Domäneneintrag erstellen, z *.example.org. Ein Platzhaltereintrag sieht folgendermaßen aus:

*.example.org.   3600  A  127.0.0.1

2. Fügen Sie den Platzhalter in vhost ein

Als nächstes müssen Sie in der Apache-Konfiguration einen vhost-Container einrichten, der den Platzhalter in der ServerAlias DOCs- Direktive angibt . Ein Beispiel für einen vhost-Container:

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

3. Ermitteln Sie, auf welcher Subdomain Sie sich in PHP befinden

Dann können Sie in Ihren PHP-Skripten die Domäne herausfinden, indem Sie in die $_SERVERsuperglobale Variable schauen . Hier ist ein Beispiel für das Abrufen der Subdomain in PHP:

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

Ich habe hier Regex verwendet, um zu ermöglichen, dass Personen Ihre Website über www.subdomain.example.org oder subdomain.example.org aufrufen.

Wenn Sie nie damit rechnen müssen, sich mit www zu befassen. (oder andere Subdomains) dann könnten Sie einfach einen Teilstring wie folgt verwenden:

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

Virtuelles Massenhosting

Virtuelles Massenhosting ist ein etwas anderes Schema als das oben beschriebene, da Sie es normalerweise zum Hosten vieler verschiedener Websites verwenden würden, anstatt zu versuchen, es für eine Anwendung zu verwenden, wie in der Frage vorgeschlagen.

Ich habe meine mod_rewrite-basierte virtuelle Massenhosting-Umgebung bereits in einem Beitrag in meinem Blog dokumentiert , den Sie sich ansehen können, wenn dies der Weg ist, den Sie einschlagen möchten. Natürlich gibt es auch die entsprechende Apache-Handbuchseite .

Apache hat auch eine interne Methode für den Umgang mit virtuellem Massenhosting, die etwas weniger flexibel ist als die von mir verwendete mod_rewrite-Methode. Dies alles wird auf der Handbuchseite Apache Dynamically Configured Mass Virtual Hosting beschrieben .

Treffynnon
quelle
Vorausgesetzt, Sie können verwenden wildcard subdomains, sehen Sie meine Lösung, um dies zu tun .htaccess.
Dan Bray
Ich glaube nicht, dass ein virtueller Host über .htaccess hinzugefügt werden kann. Das macht mich auch wegen der Sicherheit nervös. Ab 2.4 sollte es möglich sein, ein Basisverzeichnis auszuwählen, das vom Hostnamen abhängt (aber Dans Methode hat auch einige Probleme). RewriteRule "^/?(.*)" "http://%{HTTP_HOST}/%{HTTP_HOST}/$1" [L,R,NE]
Beachten
Beachten Sie, dass der PHP-Code, der dies implementiert, NICHT als Webserver-UID ausgeführt werden darf (sollte als dedizierter Benutzer über sudo sein)
symcbean
12

Sie können zunächst jede Subdomain zulassen und dann prüfen, ob die Subdomain gültig ist. Beispielsweise:

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

Innerhalb der können index.phpSie dann die Subdomain extrahieren mit:

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

All dies erfordert jedoch, dass Ihr Webserver jeden Subdomainnamen akzeptiert.

Gumbo
quelle
3
Darüber hinaus muss Ihr DNS-Server jeden Subdomainnamen auflösen.
Chaos
1
Ich habe dies auf anderen Websites gesehen, sicherlich müssen sie nicht jedes Mal jede Subdomain auflösen, oder?
Ben McRae
1
Nun, es kommt darauf an, was du damit meinst. Wenn Sie meinen, jedes Mal, wenn jemand im Internet nach foo.somedomain.com sucht und es nicht zwischengespeichert wird, muss sein DNS-Server es beheben, dann ja.
Chaos
Wenn Sie meinen, müssen sie DNS-Einträge speziell für jede Domain einrichten, siehe Treffynnons Antwort.
Chaos
Okay, danke dafür. Ich verstehe nicht ganz, was Treffynnon bedeutet, wenn ich den Platzhalter im vhost spezifiziere.
Ben McRae
6

Ich fand es einfacher mit PHP. Tatsächlich wird eine Unterdomäne in cPanel erstellt und Ihr Ordner unter dem gewünschten Domänennamen erstellt. Wie Sie es manuell in cPanel tun werden, aber alles wird in Millisekunden durch eine einfache PHP-Funktion erledigt. Kein Klick nötig :)

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

}
Adrian P.
quelle
Überprüfen Sie, ob es erfolgreich in cPanel erstellt wurde, und überprüfen Sie per FTP (oder Dateimanager), was sich im Ordner public_html / subdomain befindet. Wenn Sie eine cPanel-Einstellung haben, die beim Erstellen einer Subdomain Inhalte hinzufügt, hängt dies nicht mit dem Erstellen von Subdomains im laufenden Betrieb zusammen.
Adrian P.
Nein wurde nicht in cPanel
Ruchi
Dann haben Sie nicht genug Berechtigungen für cPanel. Ist dies ein Shared Hosting VPS oder ein dedizierter Server?
Adrian P.
Es kann mehrere Gründe geben, warum die Subdomain nicht erstellt wurde. Nicht im Zusammenhang mit dem obigen Skript, sondern mit Ihrer DNS-Konfiguration. Lesen Sie das und bitten Sie in den cPanel-Foren um Hilfe. forums.cpanel.net/threads/subdomains-not-working.228132
Adrian P.
5

Am einfachsten ist es, alle Subdomains (mit Platzhalter *) umzuleiten, um auf Ihre / wwwroot zu verweisen. Fügen Sie dann .htaccess mit dem folgenden Code in diesen Ordner ein:

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]

Dadurch wird erreicht, dass jeder Unterordner des Ordners / wwwroot über die Unterdomäne (foldername.domain.com) akzeptabel ist.

Gefunden vor Jahren auf http://www.webmasterworld.com/apache/3163397.htm

Glavić
quelle
4

Es hat nichts mit .htaccess zu tun. Sie müssen DNS-Einträge und virtuelles Hosting für die Subdomains einrichten.

Chaos
quelle
4

Mod_vhost_alias ist das richtige Modul dafür.

Mit einer Zeile können Sie Apache anweisen, an der richtigen Stelle nachzuschauen, mit Verzeichnis-Hashing usw. Zum Beispiel die Zeile:

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

würde Apache anweisen, das Dokumentstammverzeichnis auf / http / users / s / u / subdomain zu setzen, wenn dies für subdomain.yourdomain.com angefordert wird

Julien Tartarin
quelle
0

Ich denke, das Wildcard-DNS mit Apaches Dynamic Mass Virtual Hosting ist auch eine vernünftige Lösung. Obwohl ich es nie versucht habe.

Wenn Sie auf mehrere Server skalieren müssen oder die anderen Lösungen für Sie einfach nicht funktionieren, empfehle ich die Verwendung eines datenbankgesteuerten DNS-Servers. Ich habe MyDNS in der Vergangenheit erfolgreich eingesetzt . Da es MySQL (oder PostgreSQL) verwendet, können Sie Ihr DNS im laufenden Betrieb mit PHP oder fast allem anderen aktualisieren. Der Code sieht nicht so aus, als wäre er seit einiger Zeit aktualisiert worden, aber er ist DNS und daher nicht gerade auf dem neuesten Stand.

Barrett Conrad
quelle
0

Methoden zur Erstellung von Platzhalter-Subdomänen

Zuerst müssen Sie die DNS-Einstellungen mit Ihrem Server-DNS-Editor erstellen.

  1. Erstellen Sie Aeinen Eintrag in den DNS-Einstellungen mit dem Host- *Platzhalter in der Server-IP-Adresse.

    * 1400 IN A ip_address

  2. Erstellen Sie erneut einen AEintrag in den DNS-Einstellungen mit Host- @oder domain_name.tldServer-IP-Adresse. tld bedeutet Top-Level-Domains oder die Erweiterung der Domains wie .com, .org, etc ....

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

  3. Erstellen Sie einen CNAMEDatensatz wie:

    www 1400 IN A domainname.tld

  4. Erstellen Sie die Subdomain mit *Platzhalter wie*.domain.tld
  5. Erstellen Sie htaccess in Ihrem Subdomain-Verzeichnis von *.domain.tldund geben Sie diesen Code ein:

    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

    Testen Sie Ihre erste Wildcard-Subdomain wie example.domainname.tld

Wenn Sie nicht daran interessiert sind, die Daten mit htaccess als Parameter zu übergeben, können Sie die Daten auch mithilfe der folgenden Codierung abrufen:

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

und verwenden Sie Ihre globale Variable an einem beliebigen Ort wie global $get_data.

echo $get_data->data; //example

(Anmerkung: Diese Klasse hauptsächlich für die bekommen die genaue SUBDOMAINNAME aus , http_hostweil einige zusätzliche Namen vor Ihrer Sub - Domain kombiniert ist auch anwendbar , wie. www.example.domainname.tldDiese Rückkehr. $_GET['data']='wwww'Also mein Vorschlag die zu verwenden ist $_SERVER['http_host']für bekommen die genauen Werte , statt die Verwendung$_SERVER['query_string'] das Abrufen oder übergebenen htaccess-Parameter in zu verwenden Ihre Indexseite)

6. Beschleunigen Sie die Ausführung dieser Platzhalter-Subdomänen mit N Sekunden in TTL - DNS-EINSTELLUNGEN.

7.Überprüfen Sie die Subdomain nach Ihrer angegebenen Zeit (600 - 10 Minuten) wie => http://abc.domain.tld

(Hinweis: Platzhalter-Subdomänen überschreiben die vorhandenen Subdomänen nicht. Weil die erste Priorität immer für Ihre vorhandenen Subdomänen gilt.)

karthikeyan ganesan
quelle