laravel ออกแบบมาไม่เหมาะกับ server ที่เป็น share host หรือจำเป็นต้องวางไว้ใน subdirectory / subfolder ร่วมกับโปรเจคอื่นๆ เท่าไหร่เพราะว่าตัวที่ทำงานจะอยู่ที่ /public/index.php แต่ไฟล์ config จะอยู่ที่ /.env นี่ไม่รวมที่เก็บไฟล์ ที่อยู่ใน /storage แต่มันก็เหมือน php framework อื่น ๆ ทุกเจ้านั่นละ
สาเหตุที่มันไม่เหมาะเพราะว่า ใส่ไปใน document root ทั้ง project ( / ) แบบนี้เวลาเรียกใช้จะเป็นแบบ http://localhost/blog/public ก็ดูไม่มีปัญหาอะไร แต่ถ้าคนที่เป็น hacker มาเห็น มาดูว่าเว็บนี้เขียนมากับ laravel นี่หวามหมูเลยเพราะถ้าเรียก http://localhost/blog/public/.env นี่จะสามารถโหลด config file ออกไปได้เลย ซึ่งเป็นอะไรที่พลาดมาก
ถ้าแก้ไม่ได้ ก็ทำได้โดยการแก้ apache ให้เห็น folder นี้เป็น Alias Directive หรือที่ iis ใช้คำว่า Virtual Directory ( เป็นวิธีที่ตั้งให้เรียก folder ใน url ได้เหมือนกับว่ามี folder นั้นตาม path นั้น ๆ แต่จริงๆ แล้ว folder นั้นไม่มีอยู่จริงๆ อาจจะชื่ออื่น หรือ link ไป folder อื่น )
- ถ้าใช้ xampp (เรารู้ว่าคนเขียน PHP ชอบ) config ของ apache จะอยู่ที่ C:\apache\conf\extra\httpd-vhosts.conf ถ้าใช้ตัวอื่นก็หาไฟล์ .conf ใน apache\conf ดูครับ
- เพิ่มบรรทัด Alias “/blog” “C:\xampp\htdocs\blog\public”
- “/blog” คือ folder ปลอม ๆ ที่จะให้เห็นใน url
- “C:\xampp\htdocs\blog\public” คือ path ของ folder ที่เก็บไฟล์จริงๆ
- restart apache
ถ้ายังใช้ไม่ได้อาจจะเพราะว่า config จากส่วนมีผลทำให้ใช้ไม่ได้อาจจะเพิ่ม
<Directory C:\xampp\htdocs\blog\public>
AllowOverride All
Require all granted
</Directory>
จากนั้น restart อีกครั้ง ในส่วนนี้จะยังไม่สามารถส่ง query string ได้จะต้องแก้ /public/.htaccess โดยเพิ่ม RewriteBase /laravel-site
เช่น RewriteBase /blog
จากตัวอย่าง
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Send Requests To Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
แก้เป็น
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
RewriteBase /blog
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Send Requests To Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
ทดสอบดูโดย
- เปิดเว็บ http://localhost/blog จะต้องเข้าเว็บได้ปกติ
- เปิดเว็บ http://localhost/blog/robots.txt จะต้องเห็นไฟล์ robots.txt ที่อยู่ใน C:\xampp\htdocs\blog\public
- เปิดเว็บ http://localhost/blog/.env ต้องไม่เห็น เนื้อหาของไฟล์เด็ดขาดจะเป็น error 404 หรืออะไรก็ว่าไป
ข้อมูลเพิ่มเติม
About the author