เนื้อหาตอนต่อไปนี้เราจะมาดูเกี่ยวกับการจัดการ URL และ
การใช้งาน URI Library สำหรับจัดการ URL ใน CI4 ซึ่งเกี่ยวกับ
URL เบื้องต้นเราได้อธิบายไปเล็กน้อยบ้างแล้วในหัวข้อบทความ
URI Routing สามารถทบทวนได้ที่
ทำความรู้จักกับ URL และ URI Routing ใน CodeIgniter 4 http://niik.in/996
https://www.ninenik.com/content.php?arti_id=996 via @ninenik
การใช้งาน URL ใน CI4
ใน CI4 เราสามารถจัดการ URL เบื้องต้น ไม่ว่าจะเป็นการกำหนดรูปแบบ URL หรือลิ้งค์ การทำ popup
หรือการระบุ path ของตำแหน่งไฟล์ต่างๆ เช่น css js หรือ image เหล่านี้ โดยสามารถเรียกใช้งาน URL Helper
ซึ่งเป็นส่วนที่ถูกโหลดอัตโนมัติในทุก request อยู่แล้ว
ใน URL Helper จะประกอบด้วยฟังก์ชั่นต่างๆ ให้เราเลือกใช้งาน สัมพันธ์กับการตั้งค่าในไฟล์ App.php ใน
app/Config โดยเฉพาะสองค่าหลักนี้คือ
app/Congif/App.php
/* |-------------------------------------------------------------------------- | Base Site URL |-------------------------------------------------------------------------- */ public $baseURL = 'https://www.mysslweb.com/'; /* |-------------------------------------------------------------------------- | Index File |-------------------------------------------------------------------------- */ public $indexPage = 'index.php';
ก่อนไปดูตัวอย่างการใช้งาน ให้เราเตรียม Controller สำหรับประกอบการทำความเข้าใจ ในที่นี้ใช้ไฟล์ Helloworld.php
เป็นรูปแบบอย่างง่ายดังนี้
app/Controllers/Helloworld.php
<?php namespace App\Controllers; use CodeIgniter\Controller; // เรียกใช้งาน Controller class class Helloworld extends Controller { public function index() { } }
การใช้งานฟังก์ชั่นใน URL Helper
สำหรับ URL Helper ใน CI4 เราสามารถเรียกใช้งานฟังก์ชั่นได้เลย โดยไม่ต้องการทำการโหลด เพราะตัว CI
โหลดส่วนของ URL Helper ให้อัตโนมัติ
เราสามารถใช้ฟังก์ชั่นต่างๆ ได้ดังนี้
site_url()
base_url()
ฟังก์ชั่นทั้งสอง มีรูปแบบการทำงานเหมือนกัน อ้างอิงค่าจากตัวแปร $baseURL และ $indexPage ที่กำหนดในไฟล์
app/Config/App.php รองรับ parameter แรกเป็น URI segment หรือ path ที่ต้องการ และ parameter ที่สองรองรับ
การกำหนด protocal เช่น http https ftp เหล่านี้เป็นต้น หากไม่กำหนดจะอิงจากค่าปัจจุบัน มาดูตัวอย่างผลลัพธ์ที่ได้
app/Controllers/Helloworld.php
<?php namespace App\Controllers; use CodeIgniter\Controller; // เรียกใช้งาน Controller class class Helloworld extends Controller { public function index() { echo site_url(); // https://www.mysslweb.com/index.php echo "<hr>"; echo site_url('helloworld'); // https://www.mysslweb.com/index.php/helloworld echo "<hr>"; echo base_url(); // https://www.mysslweb.com echo "<hr>"; echo base_url('helloworld');// https://www.mysslweb.com/helloworld } }
เมื่อเราเรียกใช้งานไปยัง url 'https://www.mysslweb.com/helloworld' ผลลัพธ๊ค่าก็จะแสดงตามค่า ที่ comment
ดัานบน สังเกตว่า คำสั่ง site_url() จะมีส่วนของ indexPage มาด้วย ในขณะที่คำสั่ง base_url() จะไม่แสดง indexPage
คำสั่งข้างต้น หากไม่ระบุ URI segment ก็จะใช้ค่าจากที่กำหนดใน baseURL
และเนื่้องจากเราเรียกผ่าน https จะเห็นว่าค่า protocal ก็จะเป็น https ไปด้วย หากเราต้องการให้เป็น http ก็สามารถ
เปลี่ยนโดยเพิ่ม parameter ตัวที่ 2 ตามต้องการ เช่น
echo base_url('helloworld','http');// http://www.mysslweb.com/helloworld
การกำหนด segment นอกจากเราจะกำหนดเป็น string path ที่ต้องกรแล้ว เรายังสามารถกำหนดในรูปแบบ array ก็ได้
ตัวฟังก์ชั่นจะทำการจัดรูปแบบ URI segment ให้อัตโนมัติ สมมติเช่น เรามีไฟล์รูปอยู่ที่โฟลเดอร์ images/phone/iphon.png
เราสามารถกำหนดเป็น
echo base_url('images/phone/iphon.png'); // https://www.mysslweb.com/images/phone/iphon.png
หรือแบบ array ก็จะเป็น
$segment = ['images','phone','iphone.png']; echo base_url($segment); // https://www.mysslweb.com/images/phone/iphon.png ได้ผลลัพธ์เหมือนกัน
หลักๆ แล้วคำสั่งที่ถูกใช้งานบ่อยจะเป็น base_url() เช่นใช้ในการกำหนด path ของไฟล์ css js image เป็นต้น
ตัวอย่างการใช้งานในส่วนของ view
<!doctype html> <html lang="th"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title>Document</title> <link rel="stylesheet" href="<?= base_url('bootstrap@4.5.0/dist/css/bootstrap.min.css') ?>" > </head> <body> <script src="<?= base_url('jquery@3.3.1/dist/jquery.min.js') ?>"></script> <script src="<?= base_url('bootstrap@4.5.0/dist/js/bootstrap.min.js') ?>"></script> <script type="text/javascript"> $(function(){ }); </script> </body> </html>
โดย path ของไฟล์ที่เรากำหนดก็จะมี URL แบบเต็มเป็นดังนี้
https://www.mysslweb.com/bootstrap@4.5.0/dist/css/bootstrap.min.css https://www.mysslweb.com/jquery@3.3.1/dist/jquery.min.js https://www.mysslweb.com/bootstrap@4.5.0/dist/js/bootstrap.min.js
current_url()
เป็นคำสั่งที่คืนค่าเป็น url ปัจจุบัน ที่กำลังใช้งานอยู่ สมมติเราเรียกใช้งานที url เป็นดังนี้
https://www.mysslweb.com/helloworld/index?a=1&b=2
คำสั่ง current_url() จะคืนค่าเป็น URL และมี segment ต่างๆ ของหน้าที่กำลังเปิดอยู่
* ทบทวนคำว่า segment ก็คือ ส่วนที่อยู้ใน url และแบ่งหรือคั่นด้วย / เรียกว่า segment
ดังนั้นจะได้ผลลัพธ์เป็นดังนี้
echo current_url(); // คืนค่าเป็น String // https://www.mysslweb.com/helloworld/index
จะไม่มีตัว query string มาด้วย
กรณีเราต้องการให้คืนค่าเป็น URI instance เราสามารถกำหนด parameter เป็น true ได้ดังนี้
$uri = current_url(true); // คืนค่าเป็น URI instance
ค่า URI instance สามารถแปลงเป็น string ด้วยคำสั่ง echo แล้วก็จะแสดง url แบบเต็มและมี query string มาด้วย
echo current_url(true); // คืนค่าเป็น String // https://www.mysslweb.com/helloworld/index?a=1&b=2
หรือจะแปลงเป็น string ด้วยคำสั่ง (string) ก็ได้ผลลัพธ์เหมือนกัน
$uri = current_url(true); echo (string)$uri; // https://www.mysslweb.com/helloworld/index?a=1&b=2
การแสดง url ของหน้าปัจจุบัน เรายังสามารถแสดงได้จากการใช้งาน $request object ของ Controller ดังนี้ได้ด้วย
$uri = $this->request->uri; echo (string)$uri; // https://www.mysslweb.com/helloworld/index?a=1&b=2
คำสั่งที่ให้ผลลัพธ์ เหมือนกับ current_url() คือ base_url(uri_string());
echo current_url(); // https://www.mysslweb.com/helloworld/index echo base_url(uri_string()); // https://www.mysslweb.com/helloworld/index
previous_url()
เป็นคำสั่งที่คืนค่าเป็น url ของหน้าก่อนหน้า หรือ referer page ใช้งานเหมือนคำสั่ง current_url() สามารถกำหนด
parameter แรกเป็น true จะคืนค่าเป็น URI instance
ปกติเราน่าจะคุ้นกับค่า HTTP_REFERER ของตัวแปร $_SERVER แต่ใน CI จะใช้ค่าที่เก็บผ่านตัวแปร session เก็บค่า
URL หน้าเพจที่แสดงก่อนหน้า เพื่อให้มั่นใจว่าได้เป็นข้อมูลที่ถูกต้อง แต่ถ้าไม่มีการใช้งาน session ตัว CI ก็จะยังใช้เป็น
ค่าเดียวกับตัวแปร $_SERVER['HTTP_REFERER']
// สมมติเราอยู่หน้า https://www.mysslweb.com/helloworld/prev?a=1&b=2 // แล้วกดลิ้งค์มาหน้า https://www.mysslweb.com/helloworld/index echo previous_url(); // จะได้ค่าเป็น https://www.mysslweb.com/helloworld/prev?a=1&b=2
ข้อแตกต่างระหว่าง current_url() กับ previous_url() คือ ค่าของ url ของคำสั่ง previous_url() จะหมายถึง
url เต็มที่แสดงใน address bar ซึ่งหากมี query string ด้วยก็จะแสดง แต่ในคำสั่ง current_url() จะแสดงเฉพาะ
ส่วนของ segment ซึ่งหากต้องการให้แสดงแบบเต็ม ก็ต้องกำหนด parameter แรกเป็น true ตามที่ได้อธิบายไปแล้ว
เราสามารถกำหนด parameter ให้กับคำสั่ง previous_url() เป็น true หากต้องการ URI instance สำหรับจัดการค่า
ต่างๆ ของ URL เช่น อยากเอามาแยกค่า segment เป็นต้น เกี่ยวกับ URL instance เราจะอธิบายเพิ่มในหัวข้อด้านล่าง
เกี่ยวกับการใช้งาน URI Library
$pre_uri = previous_url(true); $segments = $pre_uri->getSegments(); print_r($segments); /* Array ( [0] => helloworld [1] => prev ) */
uri_string()
เป็นคำสั่งที่คืนค่า URL ในส่วนที่เป็นเฉพาะ segment ไม่รวมส่วนที่เป็น baseURL หรือก็คือส่วนที่เป็น relative path
ของ baseURL ดูตัวอย่างประกอบ
// สมมติ url ปัจจุบันเป็น https://www.mysslweb.com/helloworld/index echo uri_string(); // จะได้ค่าเป็น helloworld/index
anchor()
เป็นคำสั่งสำหรับสร้าง HTML ลิ้งค์ รองรับ parameter ตามรูปแบบดังนี้
anchor([$uri = ''[, $title = ''[, $attributes = ''[, $altConfig = NULL]]]])
Parameters: $uri (mixed) – กำหนด URL string หรือ array ค่า URI segments ก็ได้ $title (string) – ข้อความแสดงในลิ้งค์ $attributes (mixed) – กำหนด attritube เป็น array หรือ string ก็ได้ $altConfig (\Config\App) – การปรับแต่งด้วยการตั้งค่าอื่น ถ้ามี
หลักๆ ก็จะเป็นการสร้าง HTML ลิ้งค์ทั่วไป อาจจะกำหนดเป็น url เต็มของเว็บอื่นๆ หรือกำหนดเป็น relative path
ซึ่งจะเติมส่วนของ baseURL ให้ก็ได้ กรณีเป็นโดเมนเดียวกัน ดูตัวอย่างการกำหนด ผลลัพธ์ที่ได้
echo anchor('news/local/123', 'My News', 'title="News title"'); // <a href="https://www.mysslweb.com/index.php/news/local/123" title="News title">My News</a> echo anchor('news/local/123', 'My News', ['title' => 'The best news!']); // <a href="https://www.mysslweb.com/index.php/news/local/123" // title="The best news!">My News</a> echo anchor('', 'Click here'); // <a href="https://www.mysslweb.com/index.php">Click here</a> echo anchor('https://www.ninenik.com', 'Click here'); // <a href="https://www.ninenik.com">Click here</a>
ค่า attribute ที่ส่งเข้าปกำหนดค่าจะถูก escape ค่าอัตโนมัติเพื่อป้องกัน XSS attacks
สำหรับกรณีใช้เป้นลิ้งค์ภายใน จะมีส่วนของไฟล์ index.php มาด้วย หากเราไม่การค่านี้ ในส่วนของการ
กำหนด url ให้เราใช้ฟังก์ชั่น base_url() ร่วมเข้าไปด้วย ยกตัวอย่างเช่น
echo anchor(base_url('news/local/123'), 'My News', 'title="News title"'); echo anchor(base_url('news/local/123'), 'My News', ['title' => 'The best news!','target' =>'_blank']); echo anchor(base_url(), 'Click here');
anchor_popup()
เป็นคำสั่งสำหรับสร้าง HTML ลิ้งค์ แบบ JavaScript ที่เปิดหน้าต่าง popup window รองรับ parameter ตามรูปแบบดังนี้
anchor_popup([$uri = ''[, $title = ''[, $attributes = FALSE[, $altConfig = NULL]]]])
Parameters: $uri (mixed) – กำหนด URL string หรือ array ค่า URI segments ก็ได้ $title (string) – ข้อความแสดงในลิ้งค์ $attributes (mixed) – กำหนด attritube เป็น array หรือ string ก็ได้ $altConfig (\Config\App) – การปรับแต่งด้วยการตั้งค่าอื่น ถ้ามี
การตั้งค่าหลักๆ จะอยู่ที่การกำหนด attribute ดูตัวอย่างประกอบ
$atts = [ 'width' => 800, 'height' => 600, 'scrollbars' => 'yes', 'status' => 'yes', 'resizable' => 'yes', 'screenx' => 0, 'screeny' => 0, 'window_name' => '_blank' ]; echo anchor_popup('news/local/123', 'Click Me!', $atts); /* <a href="https://www.mysslweb.com/index.php/news/local/123" onclick="window.open('https://www.mysslweb.com/index.php/news/local/123', '_blank', 'width=800,height=600,scrollbars=yes,menubar=no,status=yes,resizable=yes,screenx=0,screeny=0'); return false;">Click Me!</a> */
เช่นกันถ้าต้องการตัด index.php ก็ครอบด้วยคำสั่ง base_url()
หากต้องการลิ้งค์ไปยังหน้าต่าง iframe ที่ต้องการก็ให้กำหนดตรงชื่อ window_name เป็นชื่อของ iframe ที่จะแสดง
mailto()
เป็นคำสั่งสำหรับสร้าง HTML ลิ้งค์ สำหรับส่งอีเมล ปกติถ้าใช้ผ่านมือถือก็จะขึ้นแอปส่งเมลพร้อมข้อมูลเบื้องต้น ที่เราสามารถ
กำหนดข้อความเพิ่มเติมได้ รองรับ parameter ตามรูปแบบดังนี้
mailto($email[, $title = ''[, $attributes = '']])
Parameters: $email (string) – E-mail address $title (string) – ข้อความลิ้งค์ $attributes (mixed) – กำหนด attritube เป็น array หรือ string ก็ได้
ดูตัวอย่างประกอบ
echo mailto('me@my-site.com', 'Click Here to Contact Me'); // <a href="mailto:me@my-site.com">Click Here to Contact Me</a> $attributes = ['title' => 'Mail me']; echo mailto('me@my-site.com', 'Contact Me', $attributes); // <a href="mailto:me@my-site.com" title="Mail me">Contact Me</a>
เราสามารถป้องกันอีเมล จาก bot โดยเปลี่ยนเป็นคำสั่ง safe_mailto() แทนได้ และมีรูปแบบการใช้งานเหมือนเดิม
เพียงแค่อีเมลจะอยู่ในรูปแบบป้องกัน
auto_link()
เป็นคำสั่งสำหรับสร้าง HTML ลิ้งค์ จากการค้นหา url ในข้อความ แล้วปรับให้เป็น ลิ้งค์ ให้อัตโนมัติ รองรับ parameter
ตามรูปแบบดังนี้
auto_link($str[, $type = 'both'[, $popup = FALSE]])
Parameters: $str (string) – ข้อความหรือตัวแปรข้อความที่มีลิ้งค์ url $type (string) – ประเภทลิ้งค์ที่ต้องการแปลง (‘email’, ‘url’ or ‘both’) $popup (bool) – แสดงเป็นแบบหน้าต่างใหม่ หรือไม่ กำหนด้วย true / false
ดูตัวอย่าง
$my_string_contents = ' admin@mysslweb.com การใช้งาน Pagination หรือการแบ่งหน้าใน CodeIgniter 4 http://niik.in/1005 https://www.ninenik.com/content.php?arti_id=1005 via @ninenik '; echo auto_link($my_string_contents);
หากเรากำหนดเฉพาะ ข้อความที่ต้องการ ประเภทของลิ้งค์ทั้งหมดจะถูกแปลงอัตโนมัติทั้งอีเมล และ ลิ้งค์ปกติ
กรณีต้องการให้แสดงเป็นแบบหน้าต่างใหม่ ก็สามารถกำหนดดังนี้
echo auto_link($my_string_contents,'both',true);
อย่างไรก็ตาม จะมีข้อจำกัดอยู่ที่ว่า ถ้าหากว่าในข้อความนั้นมีโครงสร้างลิ้งค์ html บางลิ้งค์อยู่ จะเกิดการสร้างลิ้งค์ที่ผิดพลาด
ขึ้นได้ ยกตัวอย่างรูปแบบข้อความที่มีลิ้งค์อยู่บางค่า
$my_string_contents = ' admin@mysslweb.com การใช้งาน Pagination หรือการแบ่งหน้าใน CodeIgniter 4 <a href="http://niik.in/1005">http://niik.in/1005</a> https://www.ninenik.com/content.php?arti_id=1005 via @ninenik ';
วิธีแก้คือให้เราทำการใช้คำสั่ง strip_tags() เพื่อยกเลิก html แท็กทั้งหมดให้เหลือเฉพาะข้อความ ก็จะสามารถใช้คำสั่ง auto_link()
ได้ และไม่เกิดข้อผิดพลาด หรือกรณีมีบางแท็ก ไม่ต้องการตัดก็กำหนด แท็กที่อนุญาตได้ เช่น
$my_string_contents = ' <span>admin@mysslweb.com</span> การใช้งาน Pagination หรือการแบ่งหน้าใน CodeIgniter 4 <a href="http://niik.in/1005">http://niik.in/1005</a> https://www.ninenik.com/content.php?arti_id=1005 via <strong>@ninenik</strong> '; echo auto_link(strip_tags($my_string_contents,'<span><strong>'),'both',true); // แบบ strip ทั้งหมด echo auto_link(strip_tags($my_string_contents),'both',true);
url_title()
เป็นคำสั่งสำหรับสร้างรูปแบบ URL ในลักษณะ human-friendly หรือ seo-engine-friendly รองรับ parameter ตามรูปแบบดังนี้
url_title($str[, $separator = '-'[, $lowercase = FALSE]])
Parameters: $str (string) – ข้อความที่ต้องการ $separator (string) – ตัวอักขระแบ่ง ปกติใช้ ‘-‘ หรือ ‘_’ $lowercase (bool) – ต้องการแปลงเป็นตัวพิมพ์เล็กหรือไม่ กำหนด true / false
ถ้าคุ้นเคยการลิ้งค์บทความหรือบล็อก เราจะพบบ่อยว่าส่วนใหญ่แล้วจะเอาหัวข้อมากำหนดเป็น url ซึ่งหัวข้อก็มักจะมีช่องว่าง
ระหว่างคำ การจะทำให้เป็นรูปแบบ url ก็จำเป็นต้องจัดการโดยการเปลี่ยนช่องว่างเป็นค่าที่สามารถใช้งานใน url ได้ ซึ่งก็จะใช้เป็น
- (dash) หรือ _ (underscore) ที่พบบ่อยจะเเป็น - ขีดกลาง (dash)
ดูตัวอย่างการใช้งาน
$title = "What's wrong with CSS?"; $url_title = url_title($title, '_'); // Whats_wrong_with_CSS $title = "What's wrong with CSS?"; $url_title = url_title($title, '-', TRUE); // whats-wrong-with-css
เวลากำหนดใช้งานกับ url เต็ม ก็จะใช้ร่วมกับฟังก์ชั่นอื่นๆ เข่น
$category = "learning"; $title = "What's wrong with CSS?"; echo base_url([$category, url_title($title, '-', TRUE)]); // https://www.mysslweb.com/learning/whats-wrong-with-css
กรณีใช้กับข้อความภาษาไทย และไม่ต้องการให้เข้ารหัสข้อความ ก็จะใช้เป็นดังนี้
$category = "learning"; $title = "ทดสอบ ข้อความ ภาษาไทย"; echo urldecode(base_url([$category, url_title($title, '-')])); // https://www.mysslweb.com/learning/ทดสอบ-ขอความ-ภาษาไทย
กรณีต้องการให้รองรับตัว accented characters (ตัวอักษรโรมันที่มีจุดมีขีด) ก็สามารถใช้เป็น mb_url_title()
มีรูปแบบการใช้งานเหมือนกัน
การใช้งาน URI Library
นอกจากเราจะสามารถใช้ฟังก์ชั่นจัดรูปแบบของ URL ได้แล้ว CI ยังรองรับรูปแบบการจัดการ URL แบบ Object ผ่าน
URI Library เพื่อให้มั่นใจว่ารูปแบบของ URL ที่ใช้งานมีความถูกต้องมากยิ่งขึ้น อีกทั้งยังใช้เป็นตัวกำหนดเงื่อน หรือการ
ทำงานบางอย่างได้อีกด้วย
การสร้าง URI Instance
เราสามารถสร้าง URI Instance เพื่อใช้งาน URL แบบ Object ได้ 2 รูปแบบคือ
// แบบกำหนดโดยตรงผ่าน class name $uri = new \CodeIgniter\HTTP\URI(); // แบบใช้งาน service ฟังก์ชั่น $uri = service('uri');
URI Instance ข้างต้น เราไม่ได้กำหนด URL ดังนั้น จะเป็นการอ้างอิงกับ URL ปัจจุบันที่ใช้งานอยู่ หากเราทำการ echo
จะเหมือนเป็นการแปลง URI Instance เป็น String ก็จะแสดงเป็น URL ของหน้าปัจจุบันแบบเต็มรูปแบบ รองรับทั้ง segment
และ query string
// สมมติเปิดหน้า https://www.mysslweb.com/helloworld/index?a=1&b=2 $uri = service('uri'); // URI Instance echo $uri; // คืนค่าเป็น String https://www.mysslweb.com/helloworld/index?a=1&b=2
แต่ถ้าเราต้องการระบุไปเลยว่า ต้องการจัดการกับ URL ไหนผ่าน URI Instance ก็สามารถระบุ URL เข้าไปด้วยได้ดังนี้
// แบบกำหนดโดยตรงผ่าน class name $uri = new \CodeIgniter\HTTP\URI('http://www.example.com/some/path'); // แบบใช้งาน service ฟังก์ชั่น $uri = service('uri', 'http://www.example.com/some/path');
การจัดการ URL หน้าปัจจุบัน
ปกติถ้าเราเรียกใช้งาน URI Instance โดยไม่ระบุ URL ก็จะหมายถึงกำลังจัดการกับ URL หน้าปัจจุบันที่เรียกใช้งานอยู่ ตามที่
อธิบายไปแล้วด้านบน
นอกจากนั้นเรายังสามารถเรียก URI instance ของหน้าปัจจุบันผ่าน request object ของ Controller ดังนี้ได้
$uri = $this->request->uri; // URI Instance หนัาปัจจุบัน
หรือจะใช้ฟังก์ชั่นจากหัวข้อ URL Helper ตามที่อธิบายไปแล้วก็ได้
$uri = current_url(true); // URI Instance หนัาปัจจุบัน
การแสดง URI String
เราสามารถแปลง URI Instance เป็น URL string หากต้องการแสดงค่าเลย โดยใช้คำสั่ง echo หรือหากต้องการ นำไปกำหนดใน
ตัวแปรอื่นๆ ก็สามารถใช้รูปแบบการแปลงเป็น string ได้ดังนี้
$uri = current_url(true); // URI Instance $page_url = (string)$uri; // URI String https://www.mysslweb.com/helloworld/index?a=1&b=2
ในกรณีที่เรารู้ค่า ส่วนต่างๆ ของ URL เราสามารถสร้าง URI String โดยใช้ URI Class ผ่าน static method ที่ชื่อ
createURIString() ได้ดังนี้
<?php namespace App\Controllers; use CodeIgniter\Controller; // เรียกใช้งาน Controller class use CodeIgniter\HTTP\URI; // ใช้งาน URI class class Helloworld extends Controller { public function index() { // รูปแบบการเรียกใช้งาน static method createURIString() : // $uriString = URI::createURIString($scheme, $authority, $path, $query, $fragment); echo URI::createURIString('http', 'example.com', 'some/path', 'foo=bar', 'first-heading'); // http://exmample.com/some/path?foo=bar#first-heading } }
การจัดการ URI Part
เราสามารถกำหนดและแสดงส่วนต่างๆ ของ URI ผ่าน URI Instance โดยรูปแบบการกำหนด และการอ่านค่าก็จะใช้คำว่า set
และ get ตามด้วยส่วนของ URL ที่จะจัดการ
เรามาดูแต่ละส่วนของ URI ตามลำดับดังนี้
Scheme
ปกติจะเป็นค่า 'http' หรือ 'https' แต่ก็รองรับทุกๆ scheme ด้วย เช่น 'mailto' 'file' เป็นต้น
ดูตัวอย่างการใช้งาน
// $uri = new \CodeIgniter\HTTP\URI('http://www.example.com/some/path'); $uri = service('uri', 'http://www.example.com/some/path'); echo $uri->getScheme(); // 'http' $uri->setScheme('https'); // เปลี่ยนเป็น 'https'
Authority
ในบางรูปแบบของ URL เช่่นการใช้งาน ftp จะมีส่วนของ Authority ที่ประกอบไปด้วยข้อมุลของผู้ใช้ UserInfo ,Host และ Port
เราสามารถแสดงข้อมูล Authority ด้วยคำสั่ง getAuthority() ดูตัวอย่าง
$uri = new \CodeIgniter\HTTP\URI('ftp://user:password@example.com:21/some/path'); echo $uri->getAuthority(); // user@example.com:21
โดยค่าเริ่มต้น จะไม่แสดง password แต่ถ้าต้องการแสดงรหัสผ่าน เราสามารถกำหนดคำสั่ง showPassword() ตามรุปแบบดังนี้
echo $uri->getAuthority(); // user@example.com:21 // ไม่แสดง password echo $uri->showPassword()->getAuthority(); // user:password@example.com:21 // แสดง password // ปิดการแสดง password $uri->showPassword(false);
หากไม่ต้องการแสดงเลข Port ให้กำหนด true เป็น parameter แรกเข้าไปดังนี้
echo $uri->getAuthority(true); // user@example.com
อย่างไรก็ตาม หากเป็น port มาตรฐานอยู่แล้ว จะไม่แสดงตัวเลข port เช่น 80 21 443 เหล่านี้เป็นต้น
Userinfo
เป็นส่วนข้อมูลของผู้ใช้ URL จะเป็นรูปแบบเดียวกันกับที่อธิบายด้านบน หรือที่เรียกว่า FTP URI แต่กรณีนี้ จะไม่แสดงค่า
Host และ Port จะแสดงเฉพาะค่า user และ password โดยค่า password ต้องกำหนดด้วยคำสั่ง showPassword() ก่อนถึงจะ
แสดง ดูตัวอย่างประกอบ
$uri = new \CodeIgniter\HTTP\URI('ftp://user:password@example.com:21/some/path'); echo $uri->getUserInfo(); // user echo $uri->showPassword()->getUserInfo(); // user:password $uri->showPassword(false);
Host
ปกติแล้วเป็นชื่อ domain ของ URI สามารถกำหนดค่า หรือแสดงค่าด้วยคำสั่ง setHost() และ getHost() ตามลำดับ
$uri = new \CodeIgniter\HTTP\URI('http://www.example.com/some/path'); echo $uri->getHost(); // www.example.com echo $uri->setHost('anotherexample.com')->getHost(); // anotherexample.com
Path
เป็นส่วนของ segment ทั้งหมด ของ URI สามารถกำหนดค่า หรือแสดงค่าด้วยคำสั่ง setPath() และ getPath() ตามลำดับ
$uri = new \CodeIgniter\HTTP\URI('http://www.example.com/some/path'); echo $uri->getPath(); // 'some/path' echo $uri->setPath('another/path')->getPath(); // 'another/path'
Query
เป็นส่วนของข้อมูล query string ทั้งหมด ดูตัวอย่าง
//$uri = new \CodeIgniter\HTTP\URI('https://www.mysslweb.com/helloworld/index?a=1&b=2'); $uri = service('uri','https://www.mysslweb.com/helloworld/index?a=1&b=2'); echo $uri->getQuery(); // a=1&b=2 $uri->setQuery('foo=bar&bar=baz'); echo $uri->getQuery(); // foo=bar&bar=baz
ค่าที่เป็น value จะไม่สามารถเป็น fregment ได้ หรือจะต้องไม่มี # หากมีค่าที่กำหนดด้วย # จะเกิด error ขึ้น
เราสามารถกำหนดค่า โดยใช้รูปแบบ array ดังนี้ได้
$uri->setQueryArray(['foo' => 'bar', 'bar' => 'baz']); // foo=bar&bar=baz
การกำหนดค่าด้วยคำสั่ง setQuery() และ setQueryArray() จะเป็นการเขียนทับค่าเดิม หรือ Override ค่าเก่า
แต่ถ้าเราต้องการเพิ่มค่าใหม่เข้าไป ต่อจากค่าเดิม และคงค่าเดิมไว้ ให้ใช้คำสั่งเป็น addQuery() ดังนี้
$uri = service('uri','https://www.mysslweb.com/helloworld/index?a=1&b=2'); echo $uri->getQuery();// a=1&b=2 $uri->addQuery('foo', 'bar'); $uri->addQuery('bar', 'baz'); echo $uri->getQuery(); // a=1&b=2&foo=bar&bar=baz
การกรองค่า Query Values
เราสามารถกรองค่า หรือทำการ filter ค่า query value โดยใช้คำสั่งเหล่านี้ได้
$uri = new \CodeIgniter\HTTP\URI('http://www.example.com?foo=bar&bar=baz&baz=foz'); // foo=bar echo $uri->getQuery(['only' => ['foo']); // แสดงเฉพาะที่กำหนด // foo=bar&baz=foz echo $uri->getQuery(['except' => ['bar']]); // แสดงทุกอันยกเว้นที่กำหนด ไม่ต้องแสดง // เหลือเฉพาะ 'baz' คืนค่าเป็น baz=foz $uri->stripQuery('foo', 'bar'); // ตัดค่าที่กำหนด แสดงค่าที่เหลือ // เหลือเฉพาะ 'foo' คืนค่าเป็น foo=bar $uri->keepQuery('foo'); // แสดงเฉพาะค่าที่กำหนด
Fragment
เป็นส่วนที่อยู่หลังสุดของ URL แบ่งหรือคั่นด้วยเครื่องหมาย # หากตัว # อยู่ตำแหน่งใด ส่วนหลังจากนี้คือ fregment ทั้งหมด
ดูตัวอย่างการกำหนด
$uri = new \CodeIgniter\HTTP\URI('http://www.example.com/some/path#first-heading'); echo $uri->getFragment(); // 'first-heading' echo $uri->setFragment('second-heading')->getFragment(); // 'second-heading'
การจัดการ URI Segments
segment คือส่วนของ path ที่แบ่งหรือคั่นด้วยเครื่องหมาย / เราสามารถอ่านค่าของแต่ละ segment โดยจัดการผ่าน URI Instance
ด้วยรูปแบบคำสั่งต่างๆ ตามตัวอย่างดังนี้
// URI = http://example.com/users/15/profile if ($uri->getSegment(1) == 'users') { echo $uri->getSegment(2); // '15' }
ตัวอย่างข้างต้น จำลองการใช้งานการตรวจสอบค่า segment เป็นเงื่อนไข และ แสดงค่า segment ที่ต้องการถ้าเข้าเงื่อนไข
URI ข้างต้นมีส่วนของ segment เป็น users/15/profile ลำดับของ segment จะเริ่มนับที่ 1 ดังนั้น จะได้แต่ละค่าขแง
segment แต่ละตำแหน่ง เป็น
1 = users 2 = 15 3 = profile
สามารถหาจำนวน segment ทั้งหมดผ่านคำสั่ง
$total = $uri->getTotalSegments(); echo $total; // 3
เราสามารถคืนค่า segment เป็น array ด้วยคำสั่ง
$segments = $uri->getSegments(); // $segments = [ 0 => 'users', 1 => '15', 2 => 'profile' ]
สำหรับเนื้อหาการจัดการ URI หรือ URL เพิ่มเติมก็มีเพียงเท่านี้ สามารถทำความเข้าไจ และนำไปปรับ
ประยุกต์ใช้งานต่อไปได้