今天在解决一个模板替换的问题的时候用到了PHP缓冲,遇到了非常蛋疼的问题。
原源代码是这样写的:
1 $array = array( 2 'name' => '张三', 3 'gift' => 'xphone' 4 ); 5 $template = '你好 {name}, 你中了大奖 {gift}.'; 6 7 function callback($buffer) { 8 global $array; 9 foreach($array as $key=>$value) {10 $buffer = str_ireplace('{'.$key.'}', $value, $buffer);11 }12 return $buffer;13 }14 15 ob_start("callback");16 echo $template;17 $new_tpl = ob_get_contents();18 ob_clean();19 echo $new_tpl;
通过这样的方式来实现一个简单的模板替换功能。
但是这样的代码并没有像我想的那样顺利的执行。
将代码剥离出来,直接运行完全没问题。
考虑是否是框架问题,或者是php结束符后多余行的问题,一一排除。
一阵蛋疼,后来google了一番,总算是找到了原因和解决方法。
global is evil!
重新修改如下:
1 $array = array( 2 'name' => '张三', 3 'gift' => 'xphone' 4 ); 5 $template = '你好 {name}, 你中了大奖 {gift}.'; 6 7 ob_start(function($buffer) use ($array) { 8 foreach($user as $key=>$value) { 9 $buffer = str_ireplace('{'.$key.'}', $value, $buffer);10 }11 return $buffer;12 });13 echo $template;14 $new_tpl = ob_get_contents();15 ob_clean();16 echo $new_tpl;
主要的原因就是,从php5.2开始 任何object都会在ob_start之前被摧毁。
所以此处$array在实际code中其实是object中的variable。
这里使用use ($array)替代 global $array 来keep this variable alive 一直到脚本执行结束。
这样的话$array就不会在ob_start的时候被内存回收机制干掉了。