Tom*_*Tom 2 php forms encoding zend-framework zend-form
我有一个表单元素,称为metaDescription:
//inside the form
$description = $this -> createElement('text', 'metaDescription')
-> setLabel('Description:')
-> setRequired(false)
-> addFilter('StringTrim')
-> addValidator('StringLength', array(0, 300))
-> addErrorMessage('Invalid description.');
$this->addElement($description);
Run Code Online (Sandbox Code Playgroud)
无论何时加载此表单,我都会使用从数据库中提取的默认值对其进行初始化:
$form->setDefault('metaDescription', $oldPage->getMetaDescription());
Run Code Online (Sandbox Code Playgroud)
这完全没问题.
但是,htmlencode当有人发送表单和html_entity_decode从数据库中提取的默认值时,我现在想要任何输入描述,以便字符再次以其原始形状显示.
我在处理表单输入时这样做:
//handle post
if ($request->isPost()) {
if ($form->isValid($request->getPost())) {
$page = new Application_Model_PagePainter(array(
'metaDescription' => htmlentities($form->getValue('metaDescription'))
));
$pageMapper->save($page);
....
Run Code Online (Sandbox Code Playgroud)
我现在设置默认值,如下所示:
$form->setDefault('metaDescription', html_entity_decode($oldPage->getMetaDescription()));
Run Code Online (Sandbox Code Playgroud)
起初,这似乎也很好.当我发送例如woord1, woord2, me&you描述时,这正确地保存woord1, woord2, me&you在数据库中并再次正确显示为woord1, woord2, me&you.但是,当我设置一个像ó这样的奇怪角色时,例如.wóórd1这被正确地保存在数据库中,wóórd1但随后发生了一些奇怪的事情:当再次显示表单时,默认值为空.当我看到来源时,它确实是空的:<input type="text" name="metaDescription" id="metaDescription" value="" />.
这会让我相信由于某种原因html_entity_decode($oldPage->getMetaKeywords())返回一个空字符串.但是,当我回显它时它返回正确的结果:wóórd1但是setDefault没有效果.当我删除html_entity_decodesetDefault再次正确工作并且值显示在表单中,但没有解码的html实体.
为什么这个html实体解码会导致这些奇怪字符的表单值为空?
回复vstm
出于调试目的,我取消了编码,如下所示:
$this->view->setEscape(array($this, 'myEscape'));
public function myEscape($inputString)
{
return $inputString;
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,问题仍然与前面解释的相同.只是为了澄清,我在将值放入数据库之前对其进行编码,如下所示:
'metaDescription' => htmlentities($form->getValue('metaDescription'), ENT_COMPAT, 'UTF-8')
Run Code Online (Sandbox Code Playgroud)
我从数据库中取出后将其解码,如下所示:
$form->setDefault('metaDescription', html_entity_decode($oldPage->getMetaDescription(), ENT_COMPAT, 'UTF-8'));
Run Code Online (Sandbox Code Playgroud)
然而,非常有趣的是,它似乎与UTF8编码有关,因为当我将编码更改为
'metaDescription' => htmlentities($form->getValue('metaDescription'), ENT_COMPAT 'ISO-8859-1')
Run Code Online (Sandbox Code Playgroud)
在以UTF8保持解码的同时,输入tést将导致输入框显示tést而不是空值,这是将两种方法都设置为UTF8时的情况.
这对你有帮助吗?
我知道它与Zend框架有关,它使用htmlspecialchars和utf-8 进行自己的转义(除非你用视图setEscape/ setEncoding方法改变它).确实当你这样做时:
$test = "wóórd1";
$test = html_entity_decode($test, ENT_COMPAT, "iso-8859-1");
$test = htmlspecialchars($test, ENT_COMPAT, "utf-8");
Run Code Online (Sandbox Code Playgroud)
$test 最后是空的.
因此,您必须使用"utf-8"调用html_entity_decode或将视图编码更改为"iso-8859-1"(或任何编码).我认为提供"utf-8"是更好的选择.
发明角色编码的人要么是邪恶的天才,要么是愚蠢的穴居人.
为了完成这项工作,你还要注意浏览器正在使用的编码,否则你要么在数据库中写入垃圾,在输出中渲染垃圾,要么两者兼而有之(或者如果你将错误的字符集交给某些PHP函数则没有) .(忍受我)
首先,您必须确保浏览器使用的编码.这可以通过以下方式实现:
因此,请查看HTML输出中的内容类型元标记及其建议的编码.如果没有内容类型元信息或者它不包含字符集信息,那么你应该在你的布局中添加一个,最好是utf-8(如果你现在不使用布局,那么现在就开始使用它了. ).这很重要,否则你不确定输入的编码是什么,或者你必须向浏览器提供什么编码.这意味着类似的东西是在你<head>的应用程序返回的每个页面的打开之后:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
Run Code Online (Sandbox Code Playgroud)
在下面的示例中,我们假设您选择utf-8,但您可以使用任何合适的 - 如果您相应地更改值(即s/UTF-8 /您的编码/ g).
现在,从浏览器中检索数据时,您知道必须为htmlentities呼叫提供哪些字符集(utf-8):
'metaDescription' =>
htmlentities($form->getValue('metaDescription'), ENT_COMPAT, 'UTF-8')
Run Code Online (Sandbox Code Playgroud)
这意味着$form->getValue('metaDescription')返回一个utf-8编码的字符串,该字符串必须转换为HTML实体字符串,这正是我们想要的.
所以在数据库中现在是非威胁字符串,没有变音符号,重音符号等等.
现在我们来看看编辑部分.在那里你必须解码HTML实体,这样用户就不能处理它们.输出字符串必须使用我们想要的字符集进行编码(是的,右:utf-8):
$form->setDefault('metaDescription',
html_entity_decode($oldPage->getMetaDescription(), ENT_COMPAT, 'UTF-8'));
Run Code Online (Sandbox Code Playgroud)
所以现在你已经分配了返回的utf-8编码字符串html_entity_decode,metaDescription现在我们只需要通过那个htmlspecialchars默认调用的调用,如果有人使用的话$view->escape().
最后一步是要确保Zend_View的encode是知道我们的编码(这是可选的,如果你使用的是UTF-8,因为这已经是默认值).为控制器中的特定视图设置它,$this->view->setEncoding('UTF-8')或者为:中的所有视图设置它bootstrap.php:
protected function _initView()
{
$view = new Zend_View();
$view->setEncoding('UTF-8');
$viewRenderer =
Zend_Controller_Action_HelperBroker::getStaticHelper(
'ViewRenderer'
);
$viewRenderer->setView($view);
return $view;
}
Run Code Online (Sandbox Code Playgroud)
如果有人现在调用$view->escape()它也需要一个utf-8字符串作为输入.您应该能够setEscape使用"null"转义删除该调用.
如果您按照所有这些步骤操作,您现在应该拥有所有特殊字符,其中根据需要恢复变音符号,重音符号和坟墓(或者我现在已经使自己蒙羞).
所以每个函数都接收它期望的编码,否则它返回臭名昭着的空字符串(伪流程图):
htmlentities($browserData, ,'UTF-8') - >期望UTF-8返回没有变音符号或其他花哨东西的ASCIIhtml_entity_decode($dbData, ,'UTF-8') - >要求ASCII,返回UTF-8编码$view->escape():htmlspecialchars- >期望UTF-8,返回UTF-8| 归档时间: |
|
| 查看次数: |
7213 次 |
| 最近记录: |