我有一个 php 脚本,它访问 MSSQL2005 数据库,从中读取一些数据并通过邮件发送结果。

某些列名称和字段本身都包含特殊字符。

当我通过浏览器(Web 服务器 iis)访问脚本时,查询会正确执行,并且邮件内容会正确编码(对于我的受众而言)。但是,当我从控制台执行 php 时,查询失败(由于列名称中的特殊字符)。如果我用对 chr() 的调用和 latin-1 中的字符代码替换查询中的特殊字符,查询将正确执行,但结果也以 latin-1 编码,因此无法在邮件中正确显示。为什么 PHP/MSSQL 驱动程序/...在两种情况下使用不同的编码?有办法解决吗?

如果您想知道,我需要控制台,因为我想使用 SQLAgent(或任务管理器或其他)来安排脚本。

有帮助吗?

解决方案

根据您在数据库中有字符的类型,它可能是一个控制台限制,我猜。如果您在控制台输入chcp,你会看到什么是活动代码页,这可能会像 CP437 也被称为扩展ASCII。如果你有出这个代码页,就像在UTF8的字符,你可能会遇到问题。可以通过键入chcp 65001切换到UTF8改变当前活动代码页。

您也可能会根据因为不是所有的字体支持扩展字符(右键单击命令提示符窗口的标题,属性,字体)所需的字符默认光栅字体更改为Lucida Console。

前面已经说过,PHP的Unicode支持不理想,但你可以设法做到这一点在与PHP5的 utf8_decode 。字符编码的秘诀是了解清楚什么是全部:您使用的工具当前编码:数据库,数据库连接,在你的PHP变量当前字节,你的输出到控制台屏幕,电子邮件的机身编码,电子邮件客户端,等等...

对于有特殊字符的一切,在现代社会里,像UTF8通常建议。确保一切沿途设置为UTF8并转换只有在必要的。

其他提示

PHP对非英语世界的支持比较差是众所周知的。我从来没有使用数据库的基本ASCII范围之外的字符,但显然你已经有了一个解决办法,似乎你不得不忍受它。

如果你想采取这一步,你可以: 1.写一个包含所有特殊字符和它们的等同物CHR的阵列 2. foreach所查询的阵列和str_replace函数

但是,如果查询是硬编码的,我想你有什么是好的。此外,请确保您使用的是最新的PHP,至少4.4.x到,总会有这样固定的改变,但我掠过4.x.x发行说明,我没有看到任何关于你的问题。

关于 PHP 字符串需要记住的一点是它们是字节流。如果您想以正确的字符集获取数据(无论您正在做什么),您必须通过某种函数或过滤器显式地执行此操作。这一切都是相当低级的。

根据您的设置,您可能需要知道数据库中字符串的内部字符集,但至少您需要知道数据库发送到 PHP 的字符集(因为,记住,对于 PHP 它只是一个流字节)。

然后你必须知道目标字符集(并且可能指定它,无论如何你确实应该这样做)。例如,假设您从数据库获取 utf-8,但希望发送 latin-1(因此使用 base64 或 q-printable 编码为“Content-transfer-encoding”):

$send_string = base64_encode(utf8_decode($database_string));

当然,在这种情况下,您必须知道所有 utf-8 字符都存在于 latin-1 字符集中,并且您可能并不真正需要 base64(不幸的是,PHP 没有良好的 q-printable 编码功能) ,虽然奇怪的是,它确实用于解码),如果你不是在谈论 utf-8 <=> latin-1 你会想要拿出 mbstring 函数来代替。

就控制台而言,您必须知道当您从控制台输入特殊字符时 PHP 会得到什么,这可能取决于 shell 和/或 PHP 设置。但请记住,PHP 只将字符串理解为字节字节,您应该能够计算出来。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top