PHP输出显示带有问号的黑色小钻石


Answers:


74

如果看到该字符(U + FFFD“ REPLACEMENT CHARACTER”),通常意味着文本本身以某种形式的单字节编码进行编码,但以一种unicode编码(UTF8或UTF16)进行解释。

如果相反,它通常会看起来像这样:¤。

原始编码可能是ISO-8859-1,也称为Latin-1。您可以在不更改脚本的情况下进行检查:浏览器为您提供了以不同编码重新解释页面的选项-在Firefox中,使用“查看”->“字符编码”。

为了使浏览器使用正确的编码,请添加一个HTTP标头,如下所示:

header("Content-Type: text/html; charset=ISO-8859-1");

或将编码放入meta标签中:

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

或者,您可以尝试以其他编码方式(最好是UTF-8)从数据库中读取数据,或使用转换文本iconv()


到目前为止,这是最接近的解决方案。但是,现在我有了一个meta:<meta http-equiv =“ Content-Type” content =“ text / html; charset = UTF-8”>并且我正在使用iconv从iso-8859-1转换为utf- 8,字符现在显示为带有0096和0092的pectoralivley special('或-)其他任何想法的框。

是的,我还有一个想法:做一些功课...您可能使用了错误的源编码。0x92和0x96在Windows-1252中是“弯曲的单引号”和“破折号”。那可能是正确的吗?您是否尝试过浏览器技巧?

使用PDF2Text类时,PHP标头为我解决了一些问题。
James P.

header("Content-Type: text/plain; charset=ISO-8859-1");应该header("Content-Type: text/html; charset=ISO-8859-1");吗?
j08691 2015年

@ j08691:好吧,这取决于现在的内容类型,不是吗?

41

这是一个字符集问题。这样,它在许多不同的级别上都可能出错,但是很可能数据库中的字符串是utf-8编码的,并且将它们表示为iso-8859-1。或相反。

解决此问题的正确方法是使字符集整齐。由于使用的是PHP,最简单的策略是在整个应用程序中使用iso-8859-1。为此,您必须确保:

  • 所有PHP源文件都保存为iso-8859-1(不要与cp-1252混淆)。
  • 您的网络服务器配置为通过以下方式提供文件 charset=iso-8859-1
  • 或者,您可以使用来从PHP文档中覆盖Web服务器设置header
  • 此外,您可以在HTML中插入一个指定相同内容的元标记,但这并不是严格要求的。
  • 可以accept-charset<form>元素上指定属性。
  • 数据库表定义为编码为latin1
  • PHP和数据库之间的数据库连接设置为latin1

如果您的数据库中已经有数据,则应注意它们可能已经被弄乱了。如果您还没有进入生产阶段,只需擦除所有内容并重新开始。否则,您将不得不进行一些数据清理。

关于元标记的注释,因为每个人都会误解它们是什么:

当网络服务器提供文件(HTML文档)时,它会发送一些信息,这些信息不会直接显示在浏览器中。这称为HTTP标头。其中一种标头是Content-Type标头,它指定文件的模仿类型(例如text/html)以及编码(也称为字符集)。虽然大多数网络服务器都会发送Content-Type带有charset信息的标头,但这是可选的。如果不存在,浏览器将改为使用解释任何元标记http-equiv="Content-Type"。重要的是要意识到只有在Web服务器不发送标头的情况下才对元标记进行解释。实际上,这意味着仅在页面保存到磁盘然后从那里打开时才使用它。

此页面对这些事情有很好的解释。


37

我也面临这个问题。同时,我遇到了三种情况:

  1. substr()

    substr()在用于剪切UTF8字符的UTF8字符串上使用,因此剪切的字符无法正确显示。使用mb_substr($utfstring, 0, 10, 'utf-8');代替。学分

  2. htmlspecialchars()

    另一个问题是htmlspecialchars()在UTF8字符串上使用。解决方法是使用:htmlspecialchars($utfstring, ENT_QUOTES, 'UTF-8');

  3. preg_replace()

    最后,我发现这preg_replace()可能导致UTF出现问题。该代码$string = preg_replace('/[^A-Za-z0-9ÄäÜüÖöß]/', ' ', $string);例如将UTF字符串“ F(×)= 2×-3”转换为“ F 2”。解决方法是mb_ereg_replace()改用。

我希望这些额外的信息将有助于消除此类问题。


2
那正是我面临的问题。不知道mb字符串函数。

1
strtolower功能也发生了。PHP手册中
micaball '18

13

正如前面的答案中提到的,之所以发生这种情况,是因为您的文本已以iso-8859-1编码或任何其他格式写入数据库。

因此,您只需要utf8在输出数据之前将其转换为。

$text = “string from database”;
$text = utf8_encode($text);
echo $text;

11

为了确保您的MYSQL连接设置为UTF-8(或latin1,取决于您使用的是什么),您可以执行以下操作:

$con = mysql_connect("localhost","username","password");    
mysql_set_charset('utf8',$con);

或使用它来检查您正在使用什么字符集:

$con = mysql_connect("localhost","username","password");   
$charset = mysql_client_encoding($con);
echo "The current character set is: $charset\n"; 

此处提供更多信息:http : //php.net/manual/zh/function.mysql-set-charset.php


这非常有用,它解决了来自远程MySQL数据库的数据中的引号编码问题,谢谢!
2015年

@ptwiggerl这很有帮助。
unixmiah

我将网站迁移到另一台服务器,然后遇到了这个问题mysql_set_charset('utf8',$ con); 解决了!
拉斐尔·莫尼

5

根据对问题的描述,数据库中的数据几乎可以肯定被编码为Windows-1252,而页面也可以肯定被用作ISO-8859-1。这两个字符集是等效的,只不过Windows-1252具有16个多余的字符,这些字符在ISO-8859-1中不存在,包括左右大括号。

假设我的分析是正确的,最简单的解决方案是将您的页面用作Windows-1252。这将起作用,因为ISO-8859-1中的所有字符也在Windows-1252中。在PHP中,您可以更改编码,如下所示:

header('Content-Type: text/html; charset=Windows-1252');

但是,您确实应该检查HTML文件中使用的字符编码以及数据库的内容,并注意保持一致,或者在不可能的地方正确转换。


该建议的问题在于,此时数据很可能是不同字符集的混合。如果您不知道到底出了什么问题,如果您只是在此处和此处随意抛出一些错误,它将变得更加混乱。
troelskn

我同意。我对帖子进行了一些编辑以反映该解决方案不能替代您知道自己在做什么。但是,我得出的结论是,大多数开发人员要么无法理解此问题,要么根本不在乎。我工作的地方似乎每月至少出现一次。
丹尼尔·卡西迪

我的观察也差不多。对于我所关心的,他们在播种时收获了。但是你可能是对的。很有可能他的数据确实是cp-1252 ..至少有一些是。
troelskn

我尝试了很多解决同一问题的方法。这是一种最省力的方法,即立即生效
十六弦琴

4

我选择这样做,将这些字符从字符串中删除-

ini_set('mbstring.substitute_character', "none"); 
$text= mb_convert_encoding($text, 'UTF-8', 'UTF-8');

1
这太棒了,它对我有用,尝试过utf8_encode和ut8_decode也不起作用。但是这种解决方案在我的情况下有效。谢谢。
Sanjeev Shetty

4

将此函数添加到变量utf8_encode($ your variable);中。


请详细说明此答案。
ppovoski

1
此功能可让您删除特殊字符并返回字符google.com/…
rk_programmer

这适用于未正确显示的分数。
罗格

我认为这些应该是一个可以接受的答案。这是唯一对我有用的方法,我尝试了所有方法。
凌晨




1

这可能是由Unicode或其他字符集不匹配引起的。尝试在浏览器中更改字符集,在这些设置中,文本将看起来不错。然后是有关如何将数据库内容转换为用于显示的字符集的问题。(实际上可以只将utf-8 charset语句添加到您的输出中。)


1

最后,我修复表后最终要做的是备份它,并将设置更改回utf-8,然后我更改了转储文件,以便DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci是我的字符集条目

现在,我不再有字符集问题,因为数据库和浏览器均为utf8。

我知道是什么原因造成的。这是数据库上的网页和浏览器效果。在linux(ubuntu + firefox)终端上,它在latin1中对数据库进行编码,这就是设置选项卡的方式。但是在Windows 10 + edge终端上,条目被强制编码为utf8。我也注意到windows 10在latin1上存在问题,所以我决定顺风而行,将其全部转换为utf8。

我认为这是Windows 10的问题,因为我们开始使用Win 10终端。因此,Microsoft bug再次引起了问题。我仍然不知道为什么表单上的编码会更改,因为Windows 10中的浏览器显示了latin1字符集,但是当它以utf8编码时,我得到了数据异常。但是在linux + firefox中,它不会这样做。


1

在我的情况下,这确实起作用了:

$text = utf8_decode($text)

我将黑色菱形字符变成一个问号,因此您可以:

$text = str_replace('?', '', utf8_decode($text));

1
关于该$text = 部分的警告:这将更改字符串中的所有问号,而不仅仅是钻石
treyBake

1

只需在标题之前添加这些行。

准确的.doc/docx文件格式将被检索:

 if(ini_get('zlib.output_compression'))

   ini_set('zlib.output_compression', 'Off');
 ob_clean();

0

您还可以在浏览器中更改角色集。仅出于调试原因。


0

在数据库和HTML中都使用相同的字符集(如此处建议)对我不起作用...因此,请记住代码是作为HTML生成的,因此我选择使用&quot;(HTML代码)或&#34;(ISO Latin-1代码)在使用引号的数据库文本中。这解决了问题,同时提供了引号。奇怪的是,在此解决方案之前,只有一些引号和撇号不能正确显示,而其他引号和撇号则不能正确显示,但是,特殊代码在所有情况下都有效。


0

在phpmyadmin中进行排序规则更改后,我运行了“检测编码”代码,现在显示为Latin_1。

但是在我的应用程序中,我遇到了一些不同的数据异常以及如何解决它:

我刚刚导入了一个表,该表具有混合编码(在某些行中带有菱形问号,并且全部都在同一列中。)所以这是我的修复代码。我使用了utf8_decode进程,该进程使用未定义的占位符并在“钻石问号”的位置分配一个普通的问号,然后使用str_replace将问号替换为引号之间的空格。这是[代码]

    include 'dbconnectfile.php';

  //// the variable $db comes from my db connect file
   /// inx is my auto increment column
   /// broke_column is the column I need to fix

      $qwy = "select inx,broke_column from Table ";
      $res = $db->query($qwy); 

      while ($data = $res->fetch_row()) {
      for ($m=0; $m<$res->field_count; $m++) {
           if ($m==0){ 
           $id=0;
           $id=$data[$m];
       echo $id;
           }else if ($m==1){ 
             $fix=0;
             $fix=$data[$m];


             $fix = utf8_decode($fix);
             $fixx =str_replace("?"," ",$fix);

        echo $fixx;

        ////I echoed the data to the screen because I like to see something as I execute it :)
            }
            }
         $insert= "UPDATE Table SET broke_column='".$fixx."'  where inx='".$id."'";
          $insresult= $db->query($insert);
      echo"<br>";
        }

        ?>        

上面的代码修复了我的表。但我建议评论更新语句,以便您首先查看它是否可以解决该问题。
drtechno

0

为了全球目的。

与其转换,编码,反编码每个文本,我不如让它们保持原样,而是更改服务器php设置。所以,

  1. 让钻石

  2. 在浏览器的视图菜单上,选择“文本编码”,然后找到一种可以正确查看文本的文本。

  3. 编辑您的php.ini并添加:

    default_charset = "ISO-8859-1"

或代替适合您的文本编码的ISO-8859。


0

从任何地方提取数据时,都应使用带前缀的函数md_FUNC_NAME

有同样的问题,它帮助了我。

或者,您可以找到该符号的代码,然后使用regexp删除这些符号。


-2

转到phpmyadmin并选择您的数据库,只需将该表字段的长度/值增加到500或1000,就可以解决您的问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.