PHP Codeigniter กับการใช้งาน Template Parser Class แล้วไม่สามารถเรียกใช้ตัวแปรด้านนอก Variable Pairs ที่กำหนดไว้ได้
มาดัดแปลงฟังก์ชั่น Template Engine ใน CodeIgniter กัน
โค้ดด้านล่างนี้เป็นส่วนของ View ที่มาจากเว็บไซต์ CodeIgniter
https://www.codeigniter.com/userguide3/libraries/parser.htmlโดยจะมี Controller ที่ทำหน้าที่รับส่งค่าดังนี้
เมื่อลองรันทดสอบบนหน้าเว็บบราวเซอร์ จะเห็นว่าข้อมูลในอาร์เรย์จะแทรกลงไปในตำแหน่งวงเล็บที่ตรงกับ Key ของข้อมูลแต่ละตัว และในส่วนของ {blog_entries} .......... {/blog_entries} จะพิเศษตรงที่ มีการวนลูปตามจำนวนอาร์เรย์ให้เราเรียบร้อย โดยที่เราไม่ต้องเขียนคำสั่งวนลูปอีกเลย
แต่ปัญหามีอยู่ว่า ในบล็อก {blog_entries} .......... {/blog_entries} ไม่สามารถเรียกใช้ {site_url} ซึ่งเราได้สร้างอาร์เรย์รับค่าเอาไว้แล้ว
หน้า controllers/Welcome.php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Welcome extends CI_Controller {
public function index()
{
$this->load->helper('url');
$this->load->library('parser');
$data = array(
'site_url' => site_url(),
'blog_title' => 'My Blog Title',
'blog_heading' => 'My Blog Heading',
'blog_entries' => array(
array('title' => 'Title 1', 'body' => 'Body 1'),
array('title' => 'Title 2', 'body' => 'Body 2'),
array('title' => 'Title 3', 'body' => 'Body 3'),
array('title' => 'Title 4', 'body' => 'Body 4'),
array('title' => 'Title 5', 'body' => 'Body 5')
)
);
$this->parser->parse('welcome_message', $data);
}
}
?>
ไฟล์ views/welcome_message.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{blog_title}</title>
<style type="text/css">
body {
background-color: #fff;
margin: 40px;
font: 13px/20px normal Helvetica, Arial, sans-serif;
color: #4F5155;
}
</style>
</head>
<body>
<h3>H3 : {blog_heading}</h3>
<p>ลิงค์ : {site_url}</p>
{blog_entries}
<h5>H5 : {title}</h5>
<p>P : {body}</p>
<p>Link : {site_url}</p>
{/blog_entries}
</body>
</html>
เมื่อรันบนหน้าเว็บบราวเซอร์ผลลัพธ์จะแสดงเฉพาะส่วนที่อยู่ด้านนอก {blog_entries} .......... {/blog_entries} เท่านั้น ส่วนที่อยู่ในบล็อก จะเป็นแค่ {site_url} ธรรมดา
ดังนั้นเพื่อเติมเต็มความต้องการที่ขาดหายไป ผมก็เลยจัดการเขียนทับฟังก์ชั่น parse() ไปซะเลย
โดยแทนที่ข้อความในวงเล็บที่มี 2 ตัวซ้อนกันแทนการใช้วงเล็บตัวเดียว เพื่อไม่ให้ทับซ้อนกับการทำงานเดิมของโค้ดที่อยู่ในบล็อกสร้างไฟล์ MY_Parser.php เอาไว้ที่ application/libraries/MY_Parser.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Overrides the CI Template Parser to allow for multiple occurrences of the
* same variable pair
*
*/
class MY_Parser extends CI_Parser {
// --------------------------------------------------------------------
/**
* Parse a template
*
* Parses pseudo-variables contained in the specified template view,
* replacing them with the data in the second param
*
* @param string
* @param array
* @param bool
* @return string
*/
public function parse($template, $data, $return = FALSE)
{
$template = $this->CI->load->view($template, $data, TRUE);
$results = $this->_parse_double($template, $data);
$results = $this->_parse($results, $data, TRUE);
if ($return === FALSE)
{
$this->CI->output->append_output($results);
}
return $results;
}
// --------------------------------------------------------------------
/**
* Parse a single key/value
*
* @param string
* @param string
* @param string
* @return string
*/
protected function _parse_double($results, $data)
{
$replace = array();
preg_match_all("/\{\{(.*?)\}\}/si", $results, $matches);
foreach ($matches[1] as $match)
{
$key = '{{'.$match.'}}';
$replace[$key] = isset($data[$match]) ? $data[$match] : $key;
}
$results = strtr($results, $replace);
return $results;
}
}
// END Parser Class
/* End of file MY_Parser.php */
/* Location: ./application/libraries/MY_Parser.php */
และแก้ไขในส่วนของ View ให้ใช้วงเล็บซ้อนกัน 2 ตัว เมื่อต้องการเรียกใช้ข้อมูลจากตัวแปรที่อยู่ด้านนอกของบล็อกที่เป็น Variable Pairs นั้นๆ
จะสังเกตว่า ผมเปลี่ยนมาใช้ {{site_url}} แทนวงเล็บชั้นเดียว
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{blog_title}</title>
<style type="text/css">
body {
background-color: #fff;
margin: 40px;
font: 13px/20px normal Helvetica, Arial, sans-serif;
color: #4F5155;
}
</style>
</head>
<body>
<h3>H3 : {blog_heading}</h3>
<p>ลิงค์ : {site_url}</p>
{blog_entries}
<h5>H5 : {title}</h5>
<p>P : {body}</p>
<p>Link : {{site_url}}</p>
{/blog_entries}
</body>
</html>
เมื่อไปรันบนหน้าเว็บเบราเซอร์จะได้ผลลัพธ์ตามที่ต้องการดังนี้
ยังไงก็ลองเอาไปปรับใช้กันดูนะครับ
ขอให้ทุกท่านสนุกกับการฝึกเขียน PHP แบบ MVC ด้วย CodeIgniter Framework นะครับ :)
ข้อมูลอ้างอิง
สร้าง Pattern เพื่อค้นหาคำในวงเล็บ {{something1}} something2 {{something3}} something4https://stackoverflow.com/questions/5897478/how-to-get-the-shortest-rather-than-longest-possible-regex-match-with-preg-match
ฟังก์ชั่นแทนที่ข้อความ strtr()
http://php.net/manual/en/function.strtr.php
ความคิดเห็น
แสดงความคิดเห็น