我有一个表单元素,名为 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);
每当此表单加载时,我都会使用从数据库中提取的默认值对其进行初始化:
$form->setDefault('metaDescription', $oldPage->getMetaDescription());
这工作得很好。
但是,我现在想在有人发送表单时对任何输入描述进行
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);
....
我现在像这样设置默认值:
$form->setDefault('metaDescription', html_entity_decode($oldPage->getMetaDescription()));
起初,这似乎也能正常工作。例如,当我发送
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_decode
时,setDefault 再次正常工作并且该值显示在表单中,但没有解码的 html 实体。为什么这个 html 实体解码导致表单值对于这些奇怪的字符为空?
回复 vstm
出于调试目的,我像这样取消设置编码:
$this->view->setEscape(array($this, 'myEscape'));
public function myEscape($inputString)
{
return $inputString;
}
不幸的是,问题仍然与前面解释的一样。为了澄清起见,我在将值放入数据库之前对其进行编码,如下所示:
'metaDescription' => htmlentities($form->getValue('metaDescription'), ENT_COMPAT, 'UTF-8')
我将值从数据库中取出后解码,如下所示:
$form->setDefault('metaDescription', html_entity_decode($oldPage->getMetaDescription(), ENT_COMPAT, 'UTF-8'));
然而,非常有趣的是,它似乎与 UTF8 编码有关,因为当我将编码更改为
'metaDescription' => htmlentities($form->getValue('metaDescription'), ENT_COMPAT 'ISO-8859-1')
在保持 UTF8 解码的同时,输入
tést
将导致输入框显示 tést
而不是空值,这是将两种方法都设置为 UTF8 时的情况。这对你有帮助吗?
最佳答案
我知道它与 Zend 框架使用 htmlspecialchars 和 utf-8 做自己的 escaping 有关系(除非你用 View setEscape
/setEncoding
方法改变它)。事实上,当你这样做时:
$test = "wóórd1";
$test = html_entity_decode($test, ENT_COMPAT, "iso-8859-1");
$test = htmlspecialchars($test, ENT_COMPAT, "utf-8");
$test
最后为空。因此,您必须使用“utf-8”调用 html_entity_decode 或将 View 编码更改为“iso-8859-1”(或任何您的编码)。我认为提供“utf-8”是更好的选择。
反对编码的 war
Whoever invented character encodings was either an evil genius or a stupid caveman.
为了完成这项工作,您还需要注意浏览器正在使用什么编码,否则您要么在数据库中写入垃圾,要么在输出中呈现垃圾或两者兼而有之(或者什么都不做,如果您将错误的字符集交给某些 PHP 函数) . (忍耐着我)
所以首先你必须确保浏览器使用的是什么编码。这可以通过以下方式实现:
因此,请查看 HTML 输出中的内容类型元标记以及它建议的编码。如果没有内容类型元信息或者它不包含字符集信息,那么你应该在你的布局中添加一个,最好是 utf-8(如果你现在不使用布局,现在是开始使用它的好时机)。这很重要,否则您不确定您的输入是什么编码或您必须向浏览器提供什么编码。这意味着在您打开应用程序返回的每个页面的
<head>
-Tag 之后:<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
在以下示例中,我们假设您选择 utf-8,但您可以使用任何合适的 - 如果您相应地更改值(这意味着 s/UTF-8/您的编码/g)。
现在,当从浏览器检索数据时,您知道必须为
htmlentities
调用 (utf-8) 提供什么字符集:'metaDescription' =>
htmlentities($form->getValue('metaDescription'), ENT_COMPAT, 'UTF-8')
所以这意味着
$form->getValue('metaDescription')
返回一个 utf-8 编码的字符串,该字符串必须转换为 HTML-entities 字符串,这正是我们想要的。因此,数据库中现在是没有变音、重音或其他任何内容的非威胁字符串。
现在我们来看看编辑部分。在那里你必须解码 HTML 实体,这样用户就不能处理它们。输出字符串必须使用我们想要的字符集进行编码(是的,正确的是:utf-8):
$form->setDefault('metaDescription',
html_entity_decode($oldPage->getMetaDescription(), ENT_COMPAT, 'UTF-8'));
所以现在你已经将
html_entity_decode
返回的 utf-8 编码字符串分配给 metaDescription
现在我们只需要通过 htmlspecialchars
调用,如果有人使用 $view->escape()
则默认调用该调用。最后一步是确保
Zend_View
的 encode
知道我们的编码(如果您使用的是 utf-8,这是可选的,因为这已经是默认值)。使用 $this->view->setEncoding('UTF-8')
为 Controller 中的特定 View 或 bootstrap.php
中的所有 View 设置它:protected function _initView()
{
$view = new Zend_View();
$view->setEncoding('UTF-8');
$viewRenderer =
Zend_Controller_Action_HelperBroker::getStaticHelper(
'ViewRenderer'
);
$viewRenderer->setView($view);
return $view;
}
如果现在有人调用
$view->escape()
,它也需要一个 utf-8 字符串作为输入。您应该能够使用“null”转义删除 setEscape
调用。如果您遵循所有这些步骤,您现在应该可以根据需要恢复所有带有变音、重音和坟墓的特殊字符(或者我现在已经丢脸了)。
所以每个函数都会收到它期望的编码,否则它会返回臭名昭著的空字符串(伪流程图):
htmlentities($browserData, ,'UTF-8')
-> 期望 UTF-8 返回 ASCII 没有变音或其他花哨的东西 html_entity_decode($dbData, ,'UTF-8')
-> 需要 ASCII,返回 UTF-8 编码的 $view->escape()
: htmlspecialchars
-> 期望 UTF-8,返回 UTF-8 tl;博士/回顾
关于php - Zend在表单输入元素中解码html实体导致空值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6829820/