[CI Day 8] Hack Route Core
เอาล่ะ มาต่อกันเลยกับการ Hack Route Core ของ Codeigniter เพื่อที่จะได้ url อย่างที่เราต้องการจริงๆ วิธีการไม่ยากเลยครับ แต่ก่อนอื่น ต้องสร้างพื้นฐานในการ Create Core Class ก่อน
โดยครั้งนี้เราจะมา extends ตัว Core ของ Route เพื่อทำการแก้ไขในส่วน url กัน โดยเป้าหมายเราจะสร้าง page ที่ user สามารถเข้าถึงได้ 2 แบบคือ
user.domain.com และ domain.com/user
โดยทั้ง 2 รูปแบบจะไปใช้ code ณ จุดเดียวกัน คุ้นๆ มั้ยครับมันเหมือนกับการ setup WP MU ที่ให้ user สามารถเลือก ลักษณะ ของ url ได้นั่นเอง
ซึ่งในการ เทส localhost นั้น ผมแนะนำให้ทดสอบโดยการ set host file ไว้ โดยไปที่
แล้วเพิ่ม line ลงไปตามนี้
127.0.0.1 domain.com
127.0.0.1 www.domain.com
ส่วนของจริงนั้น คงต้องสั่ง wild card dns ให้จับ subdomain ด้วย * นะครับ
เอาล่ะมาลงมือกันเลยครับ....
ก่อนอื่นไปที่ application/libraries/ แล้วสร้าง ไฟล์ชื่อว่า MY_router.php ขึ้นมา แบบนี้จะหมายถึงการที่เราจะสั่งให้ CI มา access เรื่อง route ที่ไฟล์นี้แทนของเดิม นั่นเอง
แล้วเขียนตามนี้ลงไป
โดย method ที่ผมจะทำการ extends มาแก้ไขคือ _validate_request ซึ่งเป็นส่วนที่จะทำการ คัดเอา segment มา และทำการจัดตำแหน่งใหม่กัน
ทีนี้เราลองมาแตก กันดูว่าผมทำอะไรไปบ้าง ใน method นี้
ส่วนนี้นั้น เป็นการตรวจสอบ uri ก่อนว่า มี subdomain มาด้วยหรือไม่ ถ้ามีมา ให้ทำการเช็คอีกทีว่า ไอ้ตัวที่ตัดออกมาด้วยคำสั่ง preg_match นั้น ไม่ใช่ www
ถ้าตรงตามเงื่อนไขแล้ว ก็จะย้าย segment มาที่ตำแหน่่งที่ 0 (segment ในส่วนนี้ คือ rsegment) ที่ย้ายมาตำแหน่งนี้ เพราะว่าเราต้องการ map ทั้ง แบบ subdomain และ subpath ถ้า ต้องการแค่ subdomain จริงๆ ผมย้ายไป segment ที่ 3 ก็จะเสร็จแล้วล่ะครับ
ในส่วนนี้ ผมทำการ จัดลำดับ และทำการเช็คอีกที ว่า url ในลักษณะนี้ มันไม่ใช่ทั้ง Controller หรือว่า Folder ใดๆ ที่มีอยู่จริงๆ
ตรงนี้ล่ะครับ หัวใจมัน คือถ้าสรุปออกมาแล้ว มันไม่ใช่ ทั้ง file และ directory ที่มีอยู่จริงๆ ผมก็พอจะ อนุมาน ได้ว่ามันน่าจะเป็น user ของผมล่ะมั้ง
ผมก็เลยจัดการ สับตำแหน่งมันซะใหม่ โดยที่ผมจะให้ segment ออกมาในรูปแบบนี้แทน
user / [controller = home] / [method = index] / [user = segment = 0]
หรือ ถ้ามี controller ระบุมาด้วย จะเปลี่ยนเป็น
user / [controller] / [method = index] / [user = segment = 0]
และถ้าระบุมาครบรวมไปถึง method ก็จะถูกเปลี่ยนเป็น
user / [controller] / [method] / [user = segment = 0] --> case default
เท่านี้ล่ะครับ เราก็จะแก้ไข rsegment ได้โดยที่ url ยังแสดงผลแบบที่เราต้องการ โดยที่ username จะอยู่ที่ segment 3 โดยตลอด
มาทดสอบกัน....
เราจะทำการทดสอบโดยการสร้าง controller ขึ้นมาใน folder: user ตามที่เรากำหนดไว้ ดังนั้นเราจะ สร้าง controller ตาม path นี้
[CI]/application/controller/user/
โดยสร้างไฟล์ home.php ก่อน แล้วเขียนลงไป แบบนี้
จากนั้นลอง รันด้วย
http://user.domain.com/CodeIgniter/
OR
http://www.domain.com/CodeIgniter/user
เราก็จะได้ค่าคำว่า user ออกมา เพื่อนำไปใช้งานต่อได้ทันที หรือเราสามารถ get ค่าออกมา โดยเขียน
$this->uri->rsegment(3)
ก็จะได้เหมือนกัน
จบแล้วล่ะครับ บทความวันนี้ ฟังๆ ดูอาจจะวุ่นวาย แต่พอไปทำจริงมันง่ายมากเลยล่ะครับ สังเกตุได้จาก โคด มีนิดเดียวเอง ลองดูนะครับ หนุกๆ
โดยครั้งนี้เราจะมา extends ตัว Core ของ Route เพื่อทำการแก้ไขในส่วน url กัน โดยเป้าหมายเราจะสร้าง page ที่ user สามารถเข้าถึงได้ 2 แบบคือ
user.domain.com และ domain.com/user
โดยทั้ง 2 รูปแบบจะไปใช้ code ณ จุดเดียวกัน คุ้นๆ มั้ยครับมันเหมือนกับการ setup WP MU ที่ให้ user สามารถเลือก ลักษณะ ของ url ได้นั่นเอง
ซึ่งในการ เทส localhost นั้น ผมแนะนำให้ทดสอบโดยการ set host file ไว้ โดยไปที่
C:WINDOWSsystem32driversetchosts
แล้วเพิ่ม line ลงไปตามนี้
127.0.0.1 domain.com
127.0.0.1 www.domain.com
ส่วนของจริงนั้น คงต้องสั่ง wild card dns ให้จับ subdomain ด้วย * นะครับ
เอาล่ะมาลงมือกันเลยครับ....
ก่อนอื่นไปที่ application/libraries/ แล้วสร้าง ไฟล์ชื่อว่า MY_router.php ขึ้นมา แบบนี้จะหมายถึงการที่เราจะสั่งให้ CI มา access เรื่อง route ที่ไฟล์นี้แทนของเดิม นั่นเอง
แล้วเขียนตามนี้ลงไป
<?php
class MY_Router extends CI_Router {
var $_reserved = array(‘www’);
function __construct()
{
parent::CI_Router();
}
function _validate_request($segments)
{
preg_match(‘/^([a-z0-9_-]+).([a-z0-9_-]+).(com|net|org|info)/i’, $_SERVER[‘HTTP_HOST’], $ms);
// Mapping sub domain to user
if (isset($ms[1]))
{
if (!in_array($ms[1], $this->_reserved))
array_splice($segments, 0, 0, $ms[1]);
}
// Finding a user first
$current = APPPATH.‘controllers/’.$segments[0];
if (!file_exists($current.EXT) && !is_dir($current))
{
$swap = $segments[0];
unset($segments[0]);
array_splice($segments, 0, 0, ‘user’);
switch (count($segments))
{
case 1: $tailer = array(‘home’, ‘index’, $swap); break;
case 2: $tailer = array(‘index’, $swap); break;
default: $tailer = $swap;
}
array_splice($segments, 3, 0, $tailer);
}
return parent::_validate_request($segments);
}
}
?>
โดย method ที่ผมจะทำการ extends มาแก้ไขคือ _validate_request ซึ่งเป็นส่วนที่จะทำการ คัดเอา segment มา และทำการจัดตำแหน่งใหม่กัน
ทีนี้เราลองมาแตก กันดูว่าผมทำอะไรไปบ้าง ใน method นี้
preg_match(‘/^([a-z0-9_-]+).([a-z0-9_-]+).(com|net|org|info)/i’, $_SERVER[‘HTTP_HOST’], $ms);
// Mapping sub domain to user
if (isset($ms[1]))
{
if (!in_array($ms[1], $this->_reserved))
array_splice($segments, 0, 0, $ms[1]);
}
ส่วนนี้นั้น เป็นการตรวจสอบ uri ก่อนว่า มี subdomain มาด้วยหรือไม่ ถ้ามีมา ให้ทำการเช็คอีกทีว่า ไอ้ตัวที่ตัดออกมาด้วยคำสั่ง preg_match นั้น ไม่ใช่ www
ถ้าตรงตามเงื่อนไขแล้ว ก็จะย้าย segment มาที่ตำแหน่่งที่ 0 (segment ในส่วนนี้ คือ rsegment) ที่ย้ายมาตำแหน่งนี้ เพราะว่าเราต้องการ map ทั้ง แบบ subdomain และ subpath ถ้า ต้องการแค่ subdomain จริงๆ ผมย้ายไป segment ที่ 3 ก็จะเสร็จแล้วล่ะครับ
$current = APPPATH.'controllers/'.$segments[0];
if (!file_exists($current.EXT) && !is_dir($current))
{
// code here
}
ในส่วนนี้ ผมทำการ จัดลำดับ และทำการเช็คอีกที ว่า url ในลักษณะนี้ มันไม่ใช่ทั้ง Controller หรือว่า Folder ใดๆ ที่มีอยู่จริงๆ
$current = APPPATH.'controllers/'.$segments[0];
if (!file_exists($current.EXT) && !is_dir($current))
{
$swap = $segments[0];
unset($segments[0]);
array_splice($segments, 0, 0, 'user');
switch (count($segments))
{
case 1: $tailer = array('home', 'index', $swap); break;
case 2: $tailer = array('index', $swap); break;
default: $tailer = $swap;
}
array_splice($segments, 3, 0, $tailer);
}
ตรงนี้ล่ะครับ หัวใจมัน คือถ้าสรุปออกมาแล้ว มันไม่ใช่ ทั้ง file และ directory ที่มีอยู่จริงๆ ผมก็พอจะ อนุมาน ได้ว่ามันน่าจะเป็น user ของผมล่ะมั้ง
ผมก็เลยจัดการ สับตำแหน่งมันซะใหม่ โดยที่ผมจะให้ segment ออกมาในรูปแบบนี้แทน
user / [controller = home] / [method = index] / [user = segment = 0]
หรือ ถ้ามี controller ระบุมาด้วย จะเปลี่ยนเป็น
user / [controller] / [method = index] / [user = segment = 0]
และถ้าระบุมาครบรวมไปถึง method ก็จะถูกเปลี่ยนเป็น
user / [controller] / [method] / [user = segment = 0] --> case default
เท่านี้ล่ะครับ เราก็จะแก้ไข rsegment ได้โดยที่ url ยังแสดงผลแบบที่เราต้องการ โดยที่ username จะอยู่ที่ segment 3 โดยตลอด
มาทดสอบกัน....
เราจะทำการทดสอบโดยการสร้าง controller ขึ้นมาใน folder: user ตามที่เรากำหนดไว้ ดังนั้นเราจะ สร้าง controller ตาม path นี้
[CI]/application/controller/user/
โดยสร้างไฟล์ home.php ก่อน แล้วเขียนลงไป แบบนี้
<?php
class Home extends Controller {
function __construct()
{
parent::Controller();
}
function index($user)
{
echo $user;
}
}
?>
จากนั้นลอง รันด้วย
http://user.domain.com/CodeIgniter/
OR
http://www.domain.com/CodeIgniter/user
เราก็จะได้ค่าคำว่า user ออกมา เพื่อนำไปใช้งานต่อได้ทันที หรือเราสามารถ get ค่าออกมา โดยเขียน
$this->uri->rsegment(3)
ก็จะได้เหมือนกัน
จบแล้วล่ะครับ บทความวันนี้ ฟังๆ ดูอาจจะวุ่นวาย แต่พอไปทำจริงมันง่ายมากเลยล่ะครับ สังเกตุได้จาก โคด มีนิดเดียวเอง ลองดูนะครับ หนุกๆ

4 comments