PHP DOM UTF-8 问题

2023-12-21

首先,我的数据库使用 Windows-1250 作为本机字符集。我将数据输出为 UTF-8。我在我的网站上使用 iconv() 函数将 Windows-1250 字符串转换为 UTF-8 字符串,并且效果完美。

问题是当我使用 PHP DOM 解析数据库中存储的一些 HTML 时(HTML 是 WYSIWYG 编辑器的输出,并且无效,它没有 html、head、body 标签等)。

HTML 可能看起来像这样,例如:

<p>Hello</p>

这是我用来从数据库解析特定 HTML 的方法:

 private function ParseSlideContent($slideContent)
 {
        var_dump(iconv('Windows-1250', 'UTF-8', $slideContent)); // this outputs the HTML ok with all special characters

  $doc = new DOMDocument('1.0', 'UTF-8');

  // hack to preserve UTF-8 characters
  $html = iconv('Windows-1250', 'UTF-8', $slideContent);
  $doc->loadHTML('<?xml encoding="UTF-8">' . $html);
  $doc->preserveWhiteSpace = false;

  foreach($doc->getElementsByTagName('img') as $t) {
   $path = trim($t->getAttribute('src'));
   $t->setAttribute('src', '/clientarea/utils/locate-image?path=' . urlencode($path));
  }
  foreach ($doc->getElementsByTagName('object') as $o) {
   foreach ($o->getElementsByTagName('param') as $p) {
    $path = trim($p->getAttribute('value'));
    $p->setAttribute('value', '/clientarea/utils/locate-flash?path=' . urlencode($path));
   }
  }
  foreach ($doc->getElementsByTagName('embed') as $e) {
   if (true === $e->hasAttribute('pluginspage')) {
    $path = trim($e->getAttribute('src'));
    $e->setAttribute('src', '/clientarea/utils/locate-flash?path=' . urlencode($path));
   } else {
    $path = end(explode('data/media/video/', trim($e->getAttribute('src'))));
    $path = 'data/media/video/' . $path;
    $path = '/clientarea/utils/locate-video?path=' . urlencode($path);
    $width = $e->getAttribute('width') . 'px';
    $height = $e->getAttribute('height') . 'px';
    $a = $doc->createElement('a', '');
    $a->setAttribute('href', $path);
    $a->setAttribute('style', "display:block;width:$width;height:$height;");
    $a->setAttribute('class', 'player');
    $e->parentNode->replaceChild($a, $e);
    $this->slideContainsVideo = true;
   }
  }

  $html = trim($doc->saveHTML());

  $html = explode('<body>', $html);
  $html = explode('</body>', $html[1]);
  return $html[0];
 }

上面方法的输出是垃圾,所有特殊字符都被替换为奇怪的东西,例如 ê。

还有一件事。它确实有效在我的开发服务器上。

但它不适用于生产服务器。

有什么建议么?

生产服务器的PHP版本:PHP Version 5.2.0RC4-dev

开发服务器的PHP版本:PHP Version 5.2.13


UPDATE:

我自己正在研究解决方案。我从这个 PHP 错误报告中得到了灵感(虽然不是真正的错误):http://bugs.php.net/bug.php?id=32547 http://bugs.php.net/bug.php?id=32547

这是我提出的解决方案。我明天会尝试一下,让你知道它是否有效:

 private function ParseSlideContent($slideContent)
 {
        var_dump(iconv('Windows-1250', 'UTF-8', $slideContent)); // this outputs the HTML ok with all special characters

  $doc = new DOMDocument('1.0', 'UTF-8');

  // hack to preserve UTF-8 characters
  $html = iconv('Windows-1250', 'UTF-8', $slideContent);
  $doc->loadHTML('<?xml encoding="UTF-8">' . $html);
  $doc->preserveWhiteSpace = false;

  // this might work
  // it basically just adds head and meta tags to the document
  $html = $doc->getElementsByTagName('html')->item(0);
  $head = $doc->createElement('head', '');
  $meta = $doc->createElement('meta', '');
  $meta->setAttribute('http-equiv', 'Content-Type');
  $meta->setAttribute('content', 'text/html; charset=utf-8');
  $head->appendChild($meta);
  $body = $doc->getElementsByTagName('body')->item(0);
  $html->removeChild($body);
  $html->appendChild($head);
  $html->appendChild($body);

  foreach($doc->getElementsByTagName('img') as $t) {
   $path = trim($t->getAttribute('src'));
   $t->setAttribute('src', '/clientarea/utils/locate-image?path=' . urlencode($path));
  }
  foreach ($doc->getElementsByTagName('object') as $o) {
   foreach ($o->getElementsByTagName('param') as $p) {
    $path = trim($p->getAttribute('value'));
    $p->setAttribute('value', '/clientarea/utils/locate-flash?path=' . urlencode($path));
   }
  }
  foreach ($doc->getElementsByTagName('embed') as $e) {
   if (true === $e->hasAttribute('pluginspage')) {
    $path = trim($e->getAttribute('src'));
    $e->setAttribute('src', '/clientarea/utils/locate-flash?path=' . urlencode($path));
   } else {
    $path = end(explode('data/media/video/', trim($e->getAttribute('src'))));
    $path = 'data/media/video/' . $path;
    $path = '/clientarea/utils/locate-video?path=' . urlencode($path);
    $width = $e->getAttribute('width') . 'px';
    $height = $e->getAttribute('height') . 'px';
    $a = $doc->createElement('a', '');
    $a->setAttribute('href', $path);
    $a->setAttribute('style', "display:block;width:$width;height:$height;");
    $a->setAttribute('class', 'player');
    $e->parentNode->replaceChild($a, $e);
    $this->slideContainsVideo = true;
   }
  }

  $html = trim($doc->saveHTML());

  $html = explode('<body>', $html);
  $html = explode('</body>', $html[1]);
  return $html[0];
 }

你的“黑客”没有意义。

您正在将 Windows-1250 HTML 文件转换为 UTF-8,然后在前面添加<?xml encoding="UTF-8">。这行不通。 HTML 文件的 DOM 扩展名:

  • 采用元 http-equiv 中为“内容类型”指定的字符集。
  • 否则假设为 ISO-8859-1

我建议您从 Windows-1250 转换为 ISO-8859-1 并且不添加任何内容。

EDIT该建议不是很好,因为 Windows-1250 包含 ISO-8859-1 中没有的字符。由于您正在处理没有metacontent-type 的元素,您可以添加自己的元素以强制解释为 UTF-8:

<?php
//script and output are in UTF-8

/* Simulate HTML fragment in Windows-1250 */
$html = <<<XML
<p>ĄĽź ‰ ‡ … á (some exist on win-1250, but not LATIN1 or even win-1252)</p>
XML;
$htmlInterm = iconv("UTF-8", "Windows-1250", $html); //convert

/* Append meta header to force UTF-8 interpretation and convert into UTF-8 */
$htmlInterm =
    "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />" .
    iconv("Windows-1250", "UTF-8", $htmlInterm);

/* Omit libxml warnings */
libxml_use_internal_errors(true);

/* Build DOM */
$d = new domdocument;
$d->loadHTML($htmlInterm);
var_dump($d->getElementsByTagName("body")->item(0)->textContent); //correct UTF-8

gives:



string(79) "ĄĽź ‰ ‡ … á (some exist on win-1250, but not LATIN1 or even win-1252)"
  
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PHP DOM UTF-8 问题 的相关文章

  • 为什么这评估为 true

    为什么这评估结果为真
  • 使用 MYSQL 将 h:mm pm/am 时间格式插入数据库

    我正在尝试将以 h mm am pm 格式写入的时间插入到存储为标准 DATETIME 格式 hh mm ss 的数据库中 但我不知道如何将发布的时间转换为标准格式所以数据库会接受它 这是我到目前为止一直在尝试的 title POST in
  • 点击 %40 变为 %2540

    当单击包含 符号的链接时 该网址给我 40 这就是我想要的 但是一旦我点击它 一秒钟后它就在我点击后变成了 2540 单击是在电子邮件内 然后定向到网站 其中 40 更改为 2540 我怎样才能让它停止变化 它现在得到这样的参数 email
  • 如何将图像从 Android 应用程序上传到网络服务器的特定文件夹中

    如何将图像从 android 移动到 Web 服务器上的指定文件夹 这是我的安卓代码 package com example bitmaptest import java io ByteArrayOutputStream import ja
  • 如何将变量插入 PHP 数组?

    我在网上查了一些答案 但都不是很准确 我希望能够做到这一点 id result id info array id Example echo info 0 这有可能吗 您需要的是 不推荐 info array id Example varia
  • Laravel Auth:attempt() 不会持久登录

    我在网上找到了许多有类似问题的资源 但似乎没有一个解决方案可以解决我的问题 当我使用以下代码登录用户时 一切看起来都很好 email Input get email password Input get password if Auth a
  • 简单的 PHP 回显代码不起作用

    这是我的 html 和 php 脚本 h1 Bob s Auto Parts h1 table width 100 tr tr table 为什么这个输出会出现一个 gt 我希望它是 这有效 仅有的 这是输出 鲍勃的汽车零件 鲍勃
  • 如何让Apache服务index.php而不是index.html?

    如果我将以下行放入index html文件 使 Apache 包含index php file 参观index html页面向我显示了这个 这是为什么 为什么它实际上不包含 PHP 文件 正如其他人指出的那样 您很可能没有 html设置为处
  • 尝试使用 php 发送 POST 请求,无论我做什么,我都会收到“HTTP ERROR 500”

    为了发出 HTTP 请求 有人建议我尝试使用 PHP 并给了我一段代码 url https example com dashboard api data array to gt PHONE NUMBER from gt SENDER ID
  • php源代码到PO文件生成器

    我必须将我的所有回显 打印字符串转换为PHP源代码代码文件到PO file 为了语言翻译 有批次吗对流器可用于相同的 我如何做到这一点 make gettext在您的服务器上运行 setup a 翻译适配器 例如带有 gettext 适配器
  • PHP 无法打开流:是一个目录

    非常简单的 PHP 脚本 我在我亲自设置的 Ubuntu Web 服务器上的 EE 模板中运行 我知道这与权限有关 并且我已经将我尝试写入的目录的所有者更改为 Apache 用户 我得到的错误是 遇到 PHP 错误 严重性 警告 消息 fi
  • 如何检测字符串中的非 ASCII 字符?

    如果我有一个 PHP 字符串 如何以有效的方式确定它是否至少包含一个非 ASCII 字符 我所说的非 ASCII 字符是指不属于该表的任何字符 http www asciitable com http www asciitable com
  • 如何对 SQL 进行多次查询

    我正在尝试创建一个表 并在 PHP 脚本的帮助下在数据库中插入一些值 虽然只插入 1 行 但效果很好 当我尝试输入更多行数时 出现错误 我需要为每个查询编写完整的插入语句 因为我正在使用在线 Excel 到 SQL 查询转换器
  • 如何关闭未关闭的 HTML 标签?

    每当我们从数据库或类似来源获取一些经过编辑的用户输入内容时 我们可能会检索仅包含开始标记但不包含结束标记的部分 这可能会妨碍网站当前的布局 有客户端或服务器端的方法来解决这个问题吗 找到了一个很好的答案 使用 PHP 5 并使用 DOMDo
  • 如何防止在 PHP 中使用超出“使用”范围的特征方法

    我想知道是否有任何方法可以防止在 PHP 的任何类上下文之外使用特征方法 让我用一个简短的例子来解释我想要什么 这是我当前的代码 File MyFunctions php trait MyFunctions function hello w
  • 如何纠正这个非法字符串偏移?

    我收到此错误 警告 第 32 行 home mysite public html wp content themes evento lib php extra class php 中的非法字符串偏移 type 我意识到文件中的这部分代码是错
  • Mysqli 更新抛出 Call to a member function bind_param() 错误[重复]

    这个问题在这里已经有答案了 我有一个 70 80 字段表单 需要插入到表中 因此我首先根据表单中的输入名称在数据库中创建了一个表 而不是手动创建一个巨大的插入语句 这是我使用的代码创建 更改表 function createTable ar
  • 从所有会话中注销

    我有一个注销选项 这是我的代码 session start session destroy setcookie key time 60 60 24 setcookie username time 60 60 24 我想添加另一个选项来注销所
  • PHP递归遍历对象树[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 使用 crypt() 加密

    我目前正在做一个非常安全的登录系统 但我是 crypt 函数的新手 需要一些快速帮助 我在注册过程中使用 crypt 加密密码字符串并将其保存到数据库中 但是 我如何在登录过程中解密密钥 或者我应该怎么做 或者是否可以对提交的密码字符串进行

随机推荐

  • 在快速枚举期间将对象设置为零[重复]

    这个问题在这里已经有答案了 我想在枚举数组时将对象设置为 nil 如下所示 for Object object in array object nil 然后 Xcode 告诉我 默认情况下 无法在 ARC 中修改快速枚举变量 声明变量 st
  • 多对多关系桥表困境

    salesman uId salesGroupLinked uId groupId add performacesScore field here group groupId 我上面有 3 个表 形成了多对多关系 我会添加一个字段 perf
  • 如果@EnvironmentObject如何创建通用?

    我最近遇到需要编写一个 MockClass 因为它会导致 SwiftUIpreview从工作中 不幸的是 我收到错误 Property type T does not match that of the wrappedValue prope
  • React 中基于当前状态的 setState

    在 React 中更新有状态组件时 组件使用当前状态来更新新状态被认为是一种不好的做法 例如 如果我有一个类存储过滤器在其状态中是否打开 那么在性能方面 用于更新状态的这些选项之一是否比另一个更可取 选项1 class Container
  • 遍历页面上的所有

    我想使用 Javascript 浏览页面上的所有元素 看看它们是否设置了属性 有没有一种简单的方法可以做到这一点 或者我是否必须使用递归解决方案 您可以使用 var divs document getElementsByTagName di
  • 在 Gmaps Api 中使用一个航点作为目的地

    我正在使用 gmaps Api 为必须访问市场列表 我的路径点 以记录其股票的人制定一条路线 我使用用户的房屋位置作为路线的起点 使用市场的位置作为我的路径点 问题是我不知道哪个航路点是路线的目的地 因为我设置了属性optimization
  • Sharepoint、计算列、IF 函数和日期

    我正在尝试添加一个计算列 我有一个日期列 其中包含安排会议的日期 在本专栏中 我需要一个代码 如果会议安排在第一季度 第二季度 第三季度或第四季度 则可以返回该代码 我有一个静态代码 如下所示 IF Date lt 40269 Q1 Q2
  • _spark_metadata 导致问题

    我将 Spark 与 Scala 一起使用 并且我有一个目录 其中有多个文件 在这个目录中 我有 Spark 生成的 Parquet 文件和 Spark Streaming 生成的其他文件 并且Spark Streaming生成一个目录 s
  • 如何让 Wintersmith 中的文章不在其自己的子目录中?

    在 Wintersmith 中 默认博客模板从 content articles index md 生成帖子 这很好 因为它允许将图像等关联文件包含在文章中 但实际上 大多数 博客文章 只是与模板关联的文本内容 必须创建子目录是一个小烦恼
  • iPhone,“尝试注册的过滤专辑列表超过最多 5 个。这将失败。”错误

    当我尝试从照片库中读取图像时 出现错误 尝试注册的过滤相册列表超过最多 5 个 这将失败 图像未读取 知道如何解决这个问题吗 我认为您没有检查源类型 你可能正在做 self sourceType UIImagePickerControlle
  • Unix Shell编程:打印时添加空行

    我试图列出目录中的所有文件 但是如何用空行分隔每个文件 基本上每个文件都用空行分隔显示 我正在尝试使用 for 循环 我确实尝试了几个例子 但没有一个真正通过在之间间隔空行来起作用 for i in ls do echo n ls l do
  • 在所有视图中创建 Telerik Sidedrawer

    我已经成功地让 Telerik Side drawer 在一个视图中工作 但我坚持将其制作成一个可以全局使用的组件 我想避免将其复制并粘贴到每个视图中 所以我的问题是如何将其变成可重用的组件 所以当你使用page router outlet
  • MySQL - 如果尚不存在则插入

    我想执行这个 MySQL 查询 INSERT INTO cron stats user VALUES int d by user 每当此类用户尚不存在时 如下所示 SELECT 1 FROM cron stats WHERE user in
  • git log 中带有 tformat 的额外换行符

    当我使用git log pretty oneline shortstat 我得到了我的日志的紧凑表示 git log pretty oneline shortstat 73c6eecd930c2f66d5c1e87fcca7ca9b0e35
  • 需要一些有关使用 PERL 的 IRC BOTS 的信息

    有谁知道有一款用 Perl 编写的好 irc 机器人吗 我只需要一个简单的登录到该频道 然后根据用户所说的内容进行回复 e g 用户
  • 只让实例访问标签本身?

    看着这个帖子 https serverfault com questions 686526 how do you tag and name the ec2 instance that was launched by an ec2 spot
  • AppStore iOS 应用新版本提交问题

    您好 提前致谢 在尝试使用应用程序加载器向 AppStore 提交新版本的 iOS 应用程序时 我收到了以下消息 ITC apps validation prerelease build missing 并停止提交 我在使用以前版本的 iT
  • GRPC:用Java/Scala制作高吞吐量客户端

    我有一项以相当高的速率传输消息的服务 目前它由 akka tcp 提供服务 每分钟生成 350 万条消息 我决定尝试一下 grpc 不幸的是 它导致吞吐量小得多 每分钟约 500k 条消息 甚至更少 您能推荐一下如何优化吗 My setup
  • 错误:我的 Prolog 代码中超出本地堆栈

    我无法弄清楚为什么给定 Prolog 代码的以下查询会生成错误Out of local stack 序言代码 likes g c likes c a likes c b likes b a likes b d likes X Z likes
  • PHP DOM UTF-8 问题

    首先 我的数据库使用 Windows 1250 作为本机字符集 我将数据输出为 UTF 8 我在我的网站上使用 iconv 函数将 Windows 1250 字符串转换为 UTF 8 字符串 并且效果完美 问题是当我使用 PHP DOM 解