การทำ Virtual host กับ Pretty url เพื่อเรียก URL ได้ง่ายๆ และเป็นมิตรกับ SEO

โดย สุรกิจ ชูเดช 02 ก.ย. 2016 15:31:19
1,121 ครั้ง

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

      จากบทความในตอนที่แล้วจะเห็นได้ว่า URL ที่ใช้รัน Frontend และ Backend นั้นทั้งยาวและไม่สวยงาม ในความต้องการคืออยากจะให้ Frontend เข้า URL แรกของเว็[เลยโดยไม่ต้องเข้าหลาย Sub folder และ Backend ก็ให้เป็น Sub folder หนึ่งของ Frontend ในลักษณะอย่างนี้

  1. Frontend จาก Url เดิม http://localhost/yii-application/frontend/web/ เปลี่ยนไปเป็น http://yiiapp.local/
  2. Backend จาก Url เดิม http://localhost/yii-application/backend/web/ เปลี่ยนไปเป็น http://yiiapp.local/admin/

      เมื่อได้ความต้องการอย่างนี้แล้วอย่าเพิ่งคิดว่า "งั้นก็จับย้าย index.php มาอยู่โฟลเดอร์แรกเลยสิ หรือปรับโครงสร้างของไฟล์ และโฟลเดอร์ แล้วค่อยไปไล่โค๊ดเอา" ใจเย็นๆ ก่อนวิธีการนั้นเป็นวิธีการที่ผิดอย่างแรง และยุ่งยากซับซ้อนมาก อีกทั้งถึงสามารถแก้โค๊ดจนทำงานได้ก็จะเจอความลำบากแน่ๆ ในอนาคต 

Virtual host

        การที่เราจะใช้งานเว็บไดๆ เราก็ต้องพิมพ์ URL ลงใน Web browser แล้วเว็บนั้นก็จะแสดงผลใน Web browser แล้วเคยสงสัยไหมว่าเราพิมพ์เว็บนี้ลงไปแล้ว Web มันรู้ได้ไงว่าจะเอาข้อมูลมาจากเซิฟเวอร์ตัวไหน คำตอบก็คือก่อนที่จะโหลดข้อมูลเหล่านั้นมา Request Url ของเราจะทำการถามหาที่อยู่ของเว็บไซต์ที่เราใส่ลงไปจาก Domain Name Server หรือชื่อย่อ DNS (ไม่ขออธิบาย DNS นะ นี่ก็ยาวมากแล้ว) แล้วรู้อีกหรือไม่ว่าเครื่องที่เราใช้อยู่ทุกวันนี้เป็น DNS ส่วนตัวอยู่แล้ว ซึ่งมันจะถูกทำงานก่อนจะออกไปหา DNS ข้างนอกก่อนเสมอ ดังนั้นถ้าเราไปปรับตั้งค่าว่าให้เว็บไไดเว็บนึงให้วิ่งไปหาเซิฟเวอร์อะไรก็สามารถทำได้ (แต่จะมีผลเฉพาะเครื่องเราเท่านั้นนะ) เช่นาเราไปตั้งค่า DNS ในเครื่องเราไว้ว่าเว็บไซต์ google.co.th ให้เอาข้อมูลมาจากเซิฟเวอร์ไอพี 127.0.0.1 ดังนั้นเมื่อเครื่องของเราเปิดเว็บ google.co.th ก็จะโหลดข้อมูลจากเครื่องตัวเองเสมอ ไม่เชื่อลองทำดู 55555

        เอาละพร่ามมาซะยาวไปกันต่อดีกว่า จากย่อหน้าที่แล้วเราก็ใช้หลักการนี้เพื่อตั้ง URL ของเราเอง ก็ให้ไปเปิดไฟล์ hosts ด้วย Text editor ทั่วไป เช่น notepad เป็นต้น ไฟล์ hosts จะอยู่ที่

  • Windows: c:\Windows\System32\Drivers\etc\hosts
  • Mac OS X / Linux: /etc/hosts

        แล้วให้เพิ่มข้อความ 127.0.0.1   yiiapp.local ลงในบรรทัดล่างสุดเพื่อที่จะบอกเครื่องเราว่าถ้ามีการเรียก URL yiiapp.local ก็ให้ไปโหลดข้อมูลจากไอพี 127.0.0.1 แล้วเซฟไฟล์ hosts และปิดได้เลย

        ลำดับต่อมาเราต้องไปบอก Apache ด้วยว่าถ้ามีการเรียกโหลดข้อมูลจากมันโดยใช้ Url yiiapp.local ให้โฟลเดอร์ไหนเป็น Web root โดยการเข้าไปแก้ไขไฟล์ config vhost ของ Apache ซึ่งเราต้องหาไฟล์นี้ให้เจอส่วนใหญ่แล้วก็จะถูกเก็บไว้ที่โฟลเดอร์เดียวกับโปรแกรม Web server ที่เราเลือกใช้นั่นแหละ แล้วเข้าไปใน conf/apache/httpd.conf (ย้ำอีกครั้งว่าแค่ส่วนใหญ่) และส่วนใหญ่อีกเช่นกันไฟล์ที่เก็บ config ของ virtual host มักจะถูก Include เข้ามาในไฟล์ httpd.conf อีกที โดยส่วนใหญ่(อีกละ) จะชื่อไฟล์ว่า httpd-vhost.conf ยังไงก็แล้วแต่มันจะต้องมีอยู่บรรทัดนึงในไฟล์ httpd.conf ที่ Include ไฟล์ httpd-vhost.conf เข้ามา เพราะฉนั้นเราต้องเปิดไฟล์ httpd.conf เพื่อหาเส้นทางที่ไฟล์ httpd-vhost.conf อยู่ แล้วเปิดขึ้นมาแก้ไข (วนไปวนมา งงกันไหมเนี่ยะ) จากนั้นให้เพิ่มข้อความชุดนี้ลงไป (ซึ่งมันเองก็น่าจะมีตัวอย่างให้ดูอยู่แล้ว)

<VirtualHost *:80>
    ServerAdmin webmaster@yiiapp.local #<--- อีเมลล์ของเว็บมาสเดตอร์ ใส่อะไรก็ได้แต่ต้องอยู่ในฟอร์แมตอีเมลล์
    DocumentRoot "c:/xampp/htdocs/yii-application" #<--- ที่อยู่ของโฟลเดอร์โปรเจ็คเรา
    ServerName yiiapp.local #<--- ชื่อเว็บที่ต้องการใช้
    ErrorLog "logs/yiiapp.local-error_log" #<--- ที่เก็บ log เมื่อ error
    CustomLog "logs/yiiapp.local-access_log" common ที่เก็บ log การเข้าถึงเว็บเรา
</VirtualHost>

      เมื่อเสร็จแล้วให้เซฟและปิดไฟล์นี้ได้เลย และอย่าลืม Restart Apache ด้วย

      เอาละไปต่อ ถึงขั้นตอนนี้เมื่อเราเรียก URL http://yiiapp.local มันก็เปิดเว็บจากโฟลเดอร์โปรเจ็คของเราแล้ว แต่มันก็แสดงรายการไฟล์และโฟลเดอร์อยู่ เพราะฉนั้นเราต้องให้ .htaccess เข้ามาช่วยจัดการ URL อีกแรงนึง 


.htaccess

        มันมีวิธีการที่จะประมวลผล URL ก่อนที่จะเข้าไปทำงานในโฟลเดอร์ไดๆ อยู่แล้วซึ่งใน Apache (Web server ของเรา) มีการรองรับความต้องการตรงนี้อยู่ด้วยการใช้การประมวลผล URL ด้วยไฟล์ .htaccess ซึ่งหลักการทำงานของมันก็คือเมื่อ Request url มาที่โฟลเดอร์ที่มีไฟล์ .htaccess อยู่ Apache จะอ่าน และประมวลผลไฟล์ .htaccess ก่อนเสมอ ดังนั้นถ้า Request url มาที่โฟลเดอร์หลักของโปรเจ็คก็ใช้ .htaccess ไปสัง Apache ให้ไปรันโฟลเดอร์ frontend/web ซ่ะ เช้นเดียวกันหาก Request url แล้วมี /backend มาด้วยก็ให้เข้าไปรันในโฟลเดอร์ backend/web เลย ทีนี้ URL ของเราก็จะไม่ยาวแล้ว เอาละเริ่มต้นกันเลย

  1. สร้างไฟล์ .htaccess ในโฟลเดอร์หลักของโปรเจ็ค
  2. ไม่ต้องทำอธิบายโค๊ดของ .htaccess แล้วนะ เอาเป็นว่าโค๊ดชุดนี้ทำงานตอมคอนเซ็ปข้างต้นให้ Copy โค๊ดชุดนี้ไป Past ในไฟล์ .htaccess

    Options FollowSymLinks
    AddDefaultCharset utf-8

    <IfModule mod_rewrite.c>
        RewriteEngine On

        # the main rewrite rule for the frontend application
        RewriteCond %{REQUEST_URI} !^/(backend/web|admin)
        RewriteRule !^frontend/web /frontend/web%{REQUEST_URI} [L]

        # redirect to the page without a trailing slash (uncomment if necessary)
        #RewriteCond %{REQUEST_URI} ^/admin/$
        #RewriteRule ^(admin)/ /$1 [L,R=301]
        # the main rewrite rule for the backend application
        RewriteCond %{REQUEST_URI} ^/admin
        RewriteRule ^admin(.*) /backend/web/$1 [L]

        # if a directory or a file of the frontend application exists, use the request directly
        RewriteCond %{REQUEST_URI} ^/frontend/web
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        # otherwise forward the request to index.php
        RewriteRule . /frontend/web/index.php [L]

        # if a directory or a file of the backend application exists, use the request directly
        RewriteCond %{REQUEST_URI} ^/backend/web
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        # otherwise forward the request to index.php
        RewriteRule . /backend/web/index.php [L]

        RewriteCond %{REQUEST_URI} \.(htaccess|htpasswd|svn|git)
        RewriteRule \.(htaccess|htpasswd|svn|git) - [F]
    </IfModule>

        ถึงตอนนี้เราสามารถที่จะเรียกเว็บเราด้วย URL ที่ต้องการได้แล้ว แต่อย่าเพิ่งดีใจมันยังไม่จบ ลองคลิ๊กที่เมนูต่างๆ ดูสิจะเห็นว่า URL มันยังไปที่ /frontend/index.php?xxx/xxx อยู่ ถึงคราวที่เราต้องเข้าไปแก้ไข config ของโปรเจ็คเรากันบ้างแล้วดูในหัวข้อถัดไป


Project Config

        มาเริ่มกันเลยดีกว่า ไม่พูดพร่ำทำเพลงละ เพราะยาวมากแล้ว เราจะแก้ไข Config หลักของ Frontend และ Backend กัน

  • แก้ไขไฟล์ frontend/config/main.php
    1. เพิ่ม 'homeUrl' => '/', อยู่ในระดับเดียวกับ components
    2. เพิ่ม 'baseUrl' => '', อยู่ใน components > request
    3. ยกเลิกคอมเมนต์ urlManager
      <?php
      //ไม่ใช่เอาสคริปต์นี้ไปแทนที่สคริปต์เดิมนะ ของเดิมเป็นยังไงก็อยู่อย่างนั้น อันนี้แค่ให้ดูว่าอะไๆรมันไปอยู่ตรงใหนแค่นั้นเอง
      return [
          'homeUrl' => '/',
          'components' => [
              'request' => [
                  'baseUrl' => '',
              ],
              'urlManager' => [
                  'enablePrettyUrl' => true,
                  'showScriptName' => false,
              ],
          ],
      ];
  • แก้ไขไฟล์ frontend/web/robots.txt เพื่อให้พวก Search Engine เข้าไปยุ่มย่ามกับ Url frontend กับ backend ให้เอาสคริปต์ชุดนี้แทนที่ทั้งหมดไปเลย
    User-agent: *
    Disallow: /frontend/web
    Disallow: /backend/web
  • แก้ไขไฟล์ backend/config/main.php ทำเหมือนกันกับ config ของ frontend เลยเลี่ยนแค่ค่าของ homeUrl และ baseUrl ตามการตั้งค่าใน .htaccess

    1. เพิ่ม 'homeUrl' => '/admin', อยู่ในระดับเดียวกับ components
    2. เพิ่ม 'baseUrl' => '/admin', อยู่ใน components > request
    3. ยกเลิกคอมเมนต์ urlManager
      <?php
      //ไม่ใช่เอาสคริปต์นี้ไปแทนที่สคริปต์เดิมนะ ของเดิมเป็นยังไงก็อยู่อย่างนั้น อันนี้แค่ให้ดูว่าอะไๆรมันไปอยู่ตรงใหนแค่นั้นเอง
      return [
          'homeUrl' => '/admin',
          'components' => [
              'request' => [
                  'baseUrl' => '/admin',
              ],
              'urlManager' => [
                  'enablePrettyUrl' => true,
                  'showScriptName' => false,
              ],
          ],
      ];

       

อ้างอิง: https://github.com/mickgeek/yii2-advanced-one-domain-config

     

เห้อเสร็จสักทีพอเขียนเป็นบทความดูหมือนขั้นตอนจะยุ่งยาก แต่ถ้าลองทำดูจริงๆ ขั้นตอนมันไม่เยอะหรอก ยิ่งถ้าทำบ่อยๆ เดี๋ยวก็คล่องเอง หลับตาทำก็ยังได้ อิอิ

โพสต์เมื่อ: 02 ก.ย. 2016 15:31:19
ปรับปรุงเมื่อ: 10 ม.ค. 2017 09:01:26
ปรับปรุงโดย: สุรกิจ ชูเดช