สร้างโดเมนย่อยได้ทันทีด้วย. htaccess (PHP)


122

ฉันต้องการสร้างระบบซึ่งในการสมัครจะสร้างโดเมนย่อยบนเว็บไซต์ของฉันสำหรับพื้นที่บัญชีผู้ใช้

เช่น johndoe.website.com

ฉันคิดว่ามันน่าจะเกี่ยวกับไฟล์. htaccess และอาจเปลี่ยนเส้นทางไปยังตำแหน่งอื่นบนเว็บไซต์? ฉันไม่รู้จริง แต่ข้อมูลใด ๆ ที่จะเริ่มต้นฉันจะได้รับการชื่นชมอย่างมาก

การสร้างพื้นที่ลงทะเบียนไม่ใช่ปัญหา - ฉันทำหลายครั้งแล้ว ฉันไม่แน่ใจว่าจะเริ่มต้นด้วยโดเมนย่อยที่ใด

คำตอบ:


125

บทสรุปอย่างรวดเร็ว

  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ตัวแปร super global นี่คือตัวอย่างของการคว้าโดเมนย่อยใน PHP:

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

ฉันใช้ regex ที่นี่เพื่ออนุญาตให้มีคนเข้าชมไซต์ของคุณผ่าน www.subdomain.example.org หรือ subdomain.example.org

หากคุณไม่เคยคาดหวังว่าจะต้องจัดการกับ www. (หรือโดเมนย่อยอื่น ๆ ) จากนั้นคุณสามารถใช้สตริงย่อยดังนี้:

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

โฮสติ้งเสมือนจริงจำนวนมาก

โฮสติ้งเสมือนจริงจำนวนมากเป็นรูปแบบที่แตกต่างกันเล็กน้อยจากข้างต้นซึ่งโดยปกติคุณจะใช้เพื่อโฮสต์เว็บไซต์ที่แตกต่างกันจำนวนมากแทนที่จะพยายามใช้แอปพลิเคชันดังกล่าว

ฉันได้จัดทำเอกสารสภาพแวดล้อมการโฮสต์เสมือนที่ใช้ mod_rewrite ของฉันก่อนหน้านี้ในโพสต์บนบล็อกของฉันซึ่งคุณสามารถดูได้ว่าเป็นเส้นทางที่คุณต้องการใช้หรือไม่ นอกจากนี้ยังมีของหลักสูตรที่เกี่ยวข้อง Apache หน้าคู่มือ

Apache ยังมีวิธีภายในในการจัดการกับโฮสติ้งเสมือนจำนวนมากซึ่งมีความยืดหยุ่นน้อยกว่าวิธี mod_rewrite ที่ฉันเคยใช้เล็กน้อย นี่คือทั้งหมดที่อธิบายในการเต้นรำแบบไดนามิกกำหนดค่ามวล Virtual Hosting หน้าคู่มือ


ให้คุณสามารถใช้ดูวิธีการแก้ปัญหาของผมที่จะทำเช่นนี้ในwildcard subdomains .htaccess
Dan Bray

ฉันไม่เชื่อว่าโฮสต์เสมือนสามารถเพิ่มได้จาก. htaccess มันยังทำให้ฉันเบื่อหน่ายเกี่ยวกับความปลอดภัย จาก 2.4 ควรเลือกไดเร็กทอรีฐานตามชื่อโฮสต์ได้ (แต่วิธีการของ Dan ก็มีปัญหาเช่นกัน) ลองพิจารณา:RewriteRule "^/?(.*)" "http://%{HTTP_HOST}/%{HTTP_HOST}/$1" [L,R,NE]
symcbean

โปรดทราบว่าโค้ด PHP ที่ใช้สิ่งนี้จะต้องไม่รันเป็น uid เว็บเซิร์ฟเวอร์ (ควรเป็นผู้ใช้เฉพาะผ่าน sudo)
symcbean

12

คุณสามารถอนุญาตทุกโดเมนย่อยตั้งแต่แรกแล้วตรวจสอบว่าโดเมนย่อยนั้นถูกต้องหรือไม่ ตัวอย่างเช่น:

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]);
}

แต่ทั้งหมดนี้กำหนดให้เว็บเซิร์ฟเวอร์ของคุณยอมรับทุกชื่อโดเมนย่อย


3
ยิ่งไปกว่านั้นเซิร์ฟเวอร์ DNS ของคุณต้องแก้ไขชื่อโดเมนย่อยทุกชื่อ
ความวุ่นวาย

1
ฉันเคยเห็นสิ่งนี้ในเว็บไซต์อื่น ๆ แล้วแน่นอนว่าพวกเขาไม่จำเป็นต้องแก้ไขทุกโดเมนย่อยทุกครั้งหรือไม่?
Ben McRae

1
มันขึ้นอยู่กับว่าคุณหมายถึงอะไร หากคุณหมายถึงทุกครั้งที่มีคนบนอินเทอร์เน็ตค้นหา foo.somedomain.com และไม่ได้แคชไว้เซิร์ฟเวอร์ DNS ของพวกเขาจะต้องแก้ไขใช่
ความวุ่นวาย

ถ้าคุณหมายถึงพวกเขาต้องตั้งค่าระเบียน DNS โดยเฉพาะสำหรับแต่ละโดเมนหรือไม่ดูคำตอบของ Treffynnon
ความวุ่นวาย

โอเคขอบคุณสำหรับสิ่งนั้น ฉันไม่ค่อยเข้าใจว่า Treffynnon หมายถึงอะไรโดยการระบุสัญลักษณ์แทนใน vhost?
Ben McRae


6

ฉันพบว่ามันง่ายกว่าที่จะทำด้วย 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";

}

ตรวจสอบว่าสร้างสำเร็จบน cPanel หรือไม่และตรวจสอบโดย FTP (หรือตัวจัดการไฟล์) สิ่งที่อยู่ภายในโฟลเดอร์ public_html / subdomain หากคุณมีการตั้งค่า cPanel เพื่อเพิ่มสิ่งต่างๆเมื่อคุณสร้างโดเมนย่อยสิ่งนี้จะไม่เกี่ยวข้องกับการสร้างโดเมนย่อยในทันที
Adrian P.

ยังไม่มีการสร้างใน cPanel
Ruchi

คุณไม่มีสิทธิ์เพียงพอใน cPanel VPS โฮสติ้งที่ใช้ร่วมกันนี้หรือเซิร์ฟเวอร์เฉพาะ
Adrian P.

อาจมีสาเหตุหลายประการในการไม่สร้างโดเมนย่อย ไม่เกี่ยวข้องกับสคริปต์ด้านบน แต่เกี่ยวข้องกับการกำหนดค่า DNS ของคุณ อ่านและขอความช่วยเหลือในฟอรัม cPanel forums.cpanel.net/threads/subdomains- not
Adrian P.

5

วิธีที่ง่ายที่สุดคือเปลี่ยนเส้นทางโดเมนย่อยทั้งหมด (โดยใช้สัญลักษณ์แทน *) เพื่อชี้ไปที่ / 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



4

Mod_vhost_aliasเป็นโมดูลที่เหมาะสมในการทำสิ่งนี้

ด้วยบรรทัดเดียวคุณสามารถบอกให้ Apache ดูตำแหน่งที่ถูกต้องโดยมีการแฮชไดเร็กทอรี ฯลฯ ตัวอย่างเช่นบรรทัด:

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

จะบอกให้ Apache ตั้งค่ารูทเอกสารเป็น / http / users / s / u / subdomain เมื่อถูกร้องขอสำหรับ subdomain.yourdomain.com


0

ฉันคิดว่าไวด์การ์ด DNS ที่มี Dynamic Mass Virtual Hosting ของ Apache ก็เป็นทางออกที่สมเหตุสมผลเช่นกัน แม้ว่าฉันไม่เคยลอง

หากคุณจำเป็นต้องขยายขนาดไปยังเซิร์ฟเวอร์หลายเครื่องหรือโซลูชันอื่น ๆ ไม่ได้ผลสำหรับคุณขอแนะนำให้ใช้เซิร์ฟเวอร์ DNS ที่ขับเคลื่อนด้วยฐานข้อมูล ฉันเคยใช้MyDNSสำเร็จแล้วในอดีต เนื่องจากใช้ MySQL (หรือ PostgreSQL) คุณจึงสามารถอัปเดต DNS ของคุณได้ทันทีด้วย PHP หรืออะไรก็ได้ ดูเหมือนว่าโค้ดจะไม่ได้รับการอัปเดตในช่วงเวลาหนึ่ง แต่เป็น DNS ดังนั้นจึงไม่ทันสมัยอย่างแน่นอน


0

วิธีการสร้างโดเมนย่อยของสัญลักษณ์ตัวแทน

คุณต้องสร้างการตั้งค่า DNS โดยใช้ตัวแก้ไข DNS ของเซิร์ฟเวอร์

  1. สร้างAบันทึกในการตั้งค่า DNS ด้วย*ไวลด์การ์ดโฮสต์ในที่อยู่ IP ของเซิร์ฟเวอร์

    * 1400 IN A ip_address

  2. สร้างAระเบียนอีกครั้งในการตั้งค่า DNS ด้วยโฮสต์@หรือ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

(หมายเหตุ: โดเมนย่อยที่เป็นสัญลักษณ์แทนไม่ได้แทนที่โดเมนย่อยที่มีอยู่เนื่องจากมีความสำคัญอันดับแรกเสมอสำหรับโดเมนย่อยที่คุณมีอยู่)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.