วันศุกร์ที่ 2 กันยายน พ.ศ. 2559

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

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

      จากบทความในตอนที่แล้วจะเห็นได้ว่า 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

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

ไม่มีความคิดเห็น:

แสดงความคิดเห็น