为什么PHP将MySQL之类的字符存储在支持utf8的MySQL表中,但又成功地从MySQL读取的值作为原始字符串呢?
例如。
$db = new mysqli("localhost","user","pwd","test");
$sql ="INSERT INTO testtable(name) VALUES ('ボーナスエリア');
从工作台将其作为?????£??·??§??3插入表中
我不知道编码/映射如何或在什么级别上发生。
用PHP读回它会在网页上显示正确的字符串ボーナスエリア。
为什么以及如何运作?
更新
感谢到目前为止的所有评论。
不仅仅是好奇,它实际上还导致了我想要从其他来源插入字符的问题,即Java,它通过jdbc正确插入了CJK字符。这在PHP中导致读取它们并显示为??????的问题。
谁能证明哪种编码将给定的字符转换为db viewer中出现的字符?
更新2
我的浏览器(与该问题无关,因为在显示之前值是????)与Firefox结合使用,编码设置为Western ISO-8859-1。我可以看到日语字符正确显示在?????旁边字符。矛盾的是,显示为????的字符正确显示在数据库查看器中。
浏览器设定
网页摘要
我想将其他来源的Java字符输入日语表,并将它们显示为原始utf8编码,这会破坏PHP读取它们的能力
@PLB Workbench可以显示utf-8字符,没有问题。
@PeterKelly在浏览器中以什么编码查看页面?工具->在Chrome中编码
如果使用phpMyAdmin,请确保phpMyAdmin文件的格式为UTF-8(不带UTF-8 BOM的ASCII)。
@Esailija网页显示从数据库读取的值。它可以正确显示PHP输入的字符(以ASCII编码?),但显示用utf8输入的字符为??????
@DavidBlanger谢谢,我不使用phpMyAdmin
@PeterKelly我不认为你理解。计算机以字节为单位存储所有内容。您在屏幕上看到的内容仅取决于该程序如何解释这些字节。您的数据库不保存字符,而是保存字节。字节序列0x20AC,可能显示为€,也可能显示为,这完全取决于其解释方式。查看页面时,请在浏览器中查找编码。
@Esailija我想在您的评论中添加它:charset就像计算机的翻译器一样……它可以将0x20AC转换为任何语言!如果是UTF-8,则可能是,但是对于ASCII,可能是# ...
@Esailija感谢您光顾的计算机科学101。计算机将所有内容存储为令人震惊的字节数!如果这只是应用程序显示的问题,那么为什么PHP会试图从mysql与ascii(或其他)编码值中读取实际值,如果它们代表相同的值呢?
@Esailija可以满足您的问题,西方ISO-8859-1。您不了解的是,该值在显示在网页上之前是错误的,因此浏览器的编码无关紧要。
您的浏览器不能使用ISO-8859-1,并且不能显示日语字符。
@Esailija是的,现在可以。
不,它无法htmlhelp.com/reference/charset
我一定在看东西-查看我的更新。
@rlemon是有关该编码提供的字符集的页面。它没有说明浏览器设置以及查看该设置之外的字符。
如果您的html meta标记定义了字符集,则浏览器设置无关紧要。
此外,它出现在网页之前,这不是应用程序问题!
default character encoding是与我所想到的不同的设置。在Web Developer -> Character Encoding中,您不仅可以强制以不同的编码方式解释页面,还可以查看浏览器当前用于查看页面的内容-它将不会是ISO-8859-1。
嗯,还可以。我没有意识到那是你在说什么。它必须是编码问题。 PHP插入必须编码为latin1,并且为该集合之外的字符进行了一些映射/猜测。 utf8插入与utf8一样,因此php无法处理它。
@PeterKelly如果您一直使用utf-8,那么应该没有问题。在某些时候,您正在转换字符集。例如,utf8_decode转换为Latin-1(ISO-8859-1)。检查您是否正在执行所有操作:stackoverflow.com/questions/279170/utf-8-all-the-way-through
PHP主要将文本视为任意二进制数据。这意味着在这些情况下,两个错误相互抵消是很常见的。
例如,如果您在源文件中写入ボーナスエリア并将其保存在UTF-8中,则PHP看到的是字节\xe3\x83\x9c\xe3\x83\xbc...,这将与之一起使用。您可以将该字符串传递给数据库客户端库,如mysqli所示,如果幸运的话,以后从数据库取回文本时,客户端库将向PHP返回完全相同的字节。与数据库实际存储数据的方式无关。
这里似乎正在发生的事情是,数据库客户端库配置为根据latin1解释PHP传递给它的数据,这意味着它将字节\xe3\x83\x9c...解释为字符???...,这就是数据库将存储的内容。当您读取数据时,也会发生同样的事情:客户端从数据库中获取字符???...,并且由于将其设置为在latin1中对其进行编码,因此它将向PHP返回\xe3\x83\x9c...。这说明了如何在数据库中添加mojibake,但是PHP应用程序似乎仍然可以正常工作。
当然,最好让数据库以可读格式存储文本。为此,您必须将客户端编码(请参见mysqli_set_charset)和数据库列编码(请参见MySQL文档)设置为utf8。
谢谢乔尼,乐于助人的答案。 不幸的是,我现在无法更改mysqli中的字符集,因此这意味着我必须先获取Java才能将字符串转换为latin1,然后再存储在mysql中,因此php可以正确读取它