天天看點

【ThinkPHP】自定義标簽

自定義标簽在一般情況下建議不要亂用,畢竟後面維護起來要找到很深的位置才能發現代碼的真正位置,别人看不懂你寫的标簽是非常困惑的一件事。除非這行屬于你自己的代碼出現了多次,比如UEditor富文本編輯器等,同時所有參與開發都明白這個自定義标簽的意義,然而,即使你不用,也要明白ThinkPHP的自定義标簽機制,不然遇到看不懂就呵呵了。

ThinkPHP中所謂的自定義标簽原理與《【Jsp】JSP自定義标簽與MODEL1、MODEL2标準》(點選打開連結)同樣,都是寫一大段php代碼,接受标簽内的參數,進行處理。

如下圖:

【ThinkPHP】自定義标簽

根據Lib\Action\TagDefineAction.class.php:

<?php
class TagDefineAction extends Action{
	public function index(){		
		$this->display();
	}
}
?>
           

所跳轉的Tpl\TagDefine\index.html:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>無标題文檔</title>
</head>

<body>
    <output text="Helloworld" /><br/>
    <output_no_close text="Helloworld">呵呵</output_no_close>
</body>
</html>
           

就根據output這個閉合标簽與output_no_close這個不閉合的标簽的,輸出了如下的參數。所謂的“閉合标簽”與“不閉合标簽”就是這個标簽中間能不能夾東西,也就是HTML裡面的雙節點标簽與單節點标簽。

【ThinkPHP】自定義标簽

顯然,ThinkPHP根本沒有output與output_no_close如此腦殘的标簽。

其真正輸出語句在Lib\TagLib的php檔案中,皆是TagLibXX.class.php的形式,其中XX為你定義的标簽名,這裡是output與output_no_close,必須遵循這樣的規則。

具體制作過程如下:

1、首先在(ThinkPHP的根目錄)\Conf\config.php中定義你要設定的自定義标簽:

<?php
return array(
	'URL_MODEL'=>2,//設定url重寫
	'URL_HTML_SUFFIX'=>'html',//設定URL字尾,用于搜尋引擎的收錄
	'URL_CASE_INSENSITIVE'=>true,//實作URL通路不再區分大小寫了
	//資料庫設定
	'DB_TYPE'=>'mysql',//資料庫類型
	'DB_HOST'=>'localhost',//伺服器位址
	'DB_NAME'=>'test',//資料庫名
	'DB_USER'=>'root',//使用者名
	'DB_PWD'=>'root',//密碼
	'DB_PORT'=>3306,//端口
	'DB_PREFIX'=>'',//資料庫表字首,這裡沒有,留白
	//開啟自定義标簽
	'TAGLIB_LOAD'=>true,
	'APP_AUTOLOAD_PATH'=>'@.TagLib',
	'TAGLIB_BUILD_IN'=>'Cx,Output,Output_no_close',
);
?>
           

真正有用的是這裡的後三行内容,上面的内容,與此專題無關,有興趣可以看《【ThinkPHP】ThinkPHP對Mysql資料庫的增删改查,volist标簽附帶條件判斷的用法》( 點選打開連結)與《【ThinkPHP】關于URL的設定、僞靜态》( 點選打開連結),反正這個(ThinkPHP的根目錄)\Conf\config.php是整個工程的根,相當于Java中的xml。

【ThinkPHP】自定義标簽

如上圖,這就定義了兩個自定義标簽,一個output,一個output_no_close。

此時,必須在Lib\TagLib下,Lib下沒有TagLib目錄的話請自己建立,必須有TagLibOutput.class.php與TagLibOutput_no_close.class.php與其相對應,否則工程運作就報錯。

對于閉包的标簽TagLibOutput.class.php,裡面的内容如下:

<?php
class TagLibOutput extends TagLib{
	protected $tags=array("output"=>array("attr"=>"text","close"=>0));
	//這裡,"output"就是自定義标簽名,與其他部分形成對應關系,該是什麼寫什麼。
	//"attr"=>"text"代表接受text這個參數
	//"close"=>0代表這個标簽為閉包标簽
	public function _output($attr,$content){//這裡的函數名也是指定動作,_output中"output"就是自定義标簽名
		$attr=$this->parseXmlAttr($attr);//解釋傳過來的參數,指定動作。
		$text=$attr["text"];//賦予給text這個變量
		$str=//然後在這個要傳回的字元串中,盡情構造,你要實作的功能。當然,在一個$str變量中寫php代碼與寫ajax一樣有點惡心,提供一個用.連接配接的寫作方法。如下所示。
		"<?php ".//唯一值得注意的是,這裡的<?php後面注意留一個空格!
			"echo '輸出:".$text."';".
		"?>";
       return $str;
       }
 }
 ?>
           

這個檔案,傳回的php代碼将傳遞過來的$text變量輸出出來。整個_output函數沒有使用到$content變量,是因為這個變量就是非閉包标簽中間夾着的内容啊!閉包标簽沒有這項,是以$content對于閉包标簽是沒有意義,故對于非閉合的output_no_close标簽的TagLibOutput_no_close.class.php的代碼如下:

<?php
class TagLibOutput_no_close extends TagLib{
	protected $tags=array("output_no_close"=>array("attr"=>"text","close"=>1));
	//這裡,"output_no_close"就是自定義标簽名,與其他部分形成對應關系,該是什麼寫什麼。
	//"attr"=>"text"代表接受text這個參數
	//"close"=>1代表這個标簽為非閉包标簽
	public function _output_no_close($attr,$content){
		$attr=$this->parseXmlAttr($attr);
		$text=$attr["text"];
		$str=
		"<?php ".
			"echo '參數text的值為:".$text.",标簽中間的内容為:".$content."';".//輸出傳遞過來的$text變量的同時輸出标簽中間夾着的内容
		"?>";
       return $str;
       }
 }
 ?>
           

閉合标簽的TagLibXX.class.php與非閉合标簽的TagLibXX.class.php結構基本一樣,就是改幾個參數而已。