今天修補一個老項目中,使用的是TP框架,到視圖區發現對象沒法遍歷輸出。真夠鬱悶的,對於不喜歡數組喜歡變量的強迫症來講就得琢磨琢磨。搞了半天,搜了半天沒找到滿意的結果。以後順道去了下官網的手冊看了看,寥寥幾行說明,真是醉了。php
TP默認視圖循環代碼編程
<foreach name="apidatas" item="val"> {$val.sta_name} //這是默認輸出數組的方式 </foreach>
打開他生成後的緩存文件,裏面對應生成的代碼。(Rumtime/Cache/*****.php)api
<?php if(is_array($val->goods_list)): foreach($val->goods_list as $key=>$v): ?> //後面略
這孃的直接就跳過了。數組
搜索一下關鍵詞is_array 到T hinkPHP\Library\Think\Template\TagLib\Cx.class.php文件裏面的_foreach 方法緩存
給添加上對象的判斷,修改後代碼奉上。框架
/** * foreach標籤解析 循環輸出數據集 * @access public * @param array $tag 標籤屬性 * @param string $content 標籤內容 * @return string|void */ public function _foreach($tag,$content) { $name = $tag['name']; $item = $tag['item']; $key = !empty($tag['key'])?$tag['key']:'key'; $name = $this->autoBuildVar($name); //額外增修對象輸出方式 //author:編程大哥 $parseStr = '<?php if(is_array('.$name.') || is_object('.$name.')): foreach('.$name.' as $'.$key.'=>$'.$item.'): ?>'; $parseStr .= $this->tpl->parse($content); $parseStr .= '<?php endforeach; endif; ?>'; if(!empty($parseStr)) { return $parseStr; } return ; }
本想着是否是再增修下對象變量的引用方式函數
PHP對象的指向符是 -> 因爲右側是「>」符號會跟其餘標籤衝突,也就致使了不少人都常常報的一個ui
XML標籤語法錯誤this
研究後發現只須要更改視圖頁對象變量的引用方式便可 由 "->" 換到 ":"spa
此處是在內置的尖括號<>標籤內使用 : 代替-> 如果在 大括號{} 標籤內也可以使用->
<foreach name="apidatas" item="val"> {$val:sta_name} //這是默認對象的引用方式 </foreach>
TP視圖頁變量引入方式
{$user_name} 普通變量
{$user.user_name} 數組成員引用方式
{$user:user_name} 對象成員飲用方式
foreach 標籤修改見上文!
增長變量標籤解析支持數組對象混合制
譬如:{$store.goods_list:goods_info.goods_name}
解析爲:$store['goods_list']->goods_info['goods_name']
以上爲 數組 對象 數組 順序解析法 首個爲數組,數組對象混合變量通常狀況下不會出現這種情況,也不多去用,若是遇到了也比較奇葩,在此記錄解決方案。固然也能夠直接寫PHP代碼實現!
修改文件 \ThinkPHP\Library\Think\Template.class.php
方法:parseVar
修改後的方法以下
/** * 模板變量解析,支持使用函數 * 格式: {$varname|function1|function2=arg1,arg2} * @access public * @param string $varStr 變量數據 * @return string */ public function parseVar($varStr){ $varStr = trim($varStr); static $_varParseList = array(); //若是已經解析過該變量字串,則直接返回變量值 if(isset($_varParseList[$varStr])) return $_varParseList[$varStr]; $parseStr = ''; $varExists = true; if(!empty($varStr)){ $varArray = explode('|',$varStr); //取得變量名稱 $var = array_shift($varArray); if('Think.' == substr($var,0,6)){ // 全部以Think.打頭的以特殊變量對待 無需模板賦值就能夠輸出 $name = $this->parseThinkVar($var); }elseif( false !== strpos($var,'.')) { //支持 {$var.property} $vars = explode('.',$var); $var = array_shift($vars); switch(strtolower(C('TMPL_VAR_IDENTIFY'))) { case 'array': // 識別爲數組 $name = '$'.$var; //增修支持數組對象混合 @編程大哥 [start] foreach ($vars as $key=>$val){ $tmp = ''; if(strpos($val,':')){ $vars_obj = explode(':',$val); $val = $vars_obj[0]; unset($vars_obj[0]); foreach($vars_obj as $ov) $tmp .= '->'.$ov; } $name .= '["'.$val.'"]'.$tmp; } //增修支持數組對象混合 @編程大哥 [end] break; case 'obj': // 識別爲對象 $name = '$'.$var; foreach ($vars as $key=>$val) $name .= '->'.$val; break; default: // 自動判斷數組或對象 只支持二維 $name = 'is_array($'.$var.')?$'.$var.'["'.$vars[0].'"]:$'.$var.'->'.$vars[0]; } }elseif(false !== strpos($var,'[')) { //支持 {$var['key']} 方式輸出數組 $name = "$".$var; preg_match('/(.+?)\[(.+?)\]/is',$var,$match); $var = $match[1]; }elseif(false !==strpos($var,':') && false ===strpos($var,'(') && false ===strpos($var,'::') && false ===strpos($var,'?')){ //支持 {$var:property} 方式輸出對象的屬性 $vars = explode(':',$var); $var = str_replace(':','->',$var); $name = "$".$var; $var = $vars[0]; }else { $name = "$$var"; } //對變量使用函數 if(count($varArray)>0) $name = $this->parseVarFunction($name,$varArray); $parseStr = '<?php echo ('.$name.'); ?>'; } $_varParseList[$varStr] = $parseStr; return $parseStr; }
以上修改後方法只支持先數組後對象方式,想要更奇葩的能夠本身研究後發出來哦!