使用子串时会出现稀有字符。

时间:2019-02-03 19:36:19

标签: php

我知道这似乎是一个编码问题,我不这么认为。 我有一个网站,当用户保存工作时,人们使用ckeditor发布一些长文本(故事),一些HTML进入数据库,该数据库为所有表的utf8编码做好了准备。

对于所有帖子,我都会生成一个“文本缩略图”,该文本是全文的一部分,在使用utf-8的所有页面中,全文看起来都不错。

我用来获取“文本缩略图”的代码:

     <?php
     $str = trim(strip_tags(nl2br($historia['texto']))); //get only text
     echo substr($str, 0, 99) . (strlen($str) > 100 ? '...' : ''); //get part of string, if original string was longer than 100 characters add 3 dots at the end
     ?>

到目前为止,我已经在该网站上运行了一个多月,问题出在下一个要处理的特定字符串上

<p>Foto artística<br>Mi esposo invito uno de sus viejos amigos a casa, un
   hombre muy impresionante, llegó en un auto de lujo, vistiendo finas ropas, 
   reloj de plata, cadenas de oro y cosas impresionantes, el nos platico de 
   muchas de las cosas a las que se dedico desde que perdió la comunicación 
   con mi esposo, desde ayudante de cocina hasta productor de películas 
   independientes que había logrado vender por sumas importantes de dinero,
   el motivo de su visita era porque necesitaba a alguien como mi esposo 
   para salir en una de sus filmaciones, a cambio recibiría una buena 
   cantidad de dinero, clases de actuación y otros beneficios, claro que 
   aceptamos sin pensarlo.</p>

当我用上面的php代码处理它时,得到以下结果:

  

在维萨斯山上的阿维哥街上的艺术之家,一个不合法的人,...

最后一个单词的重音为llegó,同一字符串中的其他单词和诸如artística之类的“文本缩略图”没有相同的问题,看来结尾的重音字母是一个问题,在使用substring之前,我尝试使用一些php函数来尝试对字符串进行编码/解码,但是我没有得到任何结果,请您以某种方式指导我解决该问题,请这样做。 / p>

这是在线编辑器中以相同方式显示的php代码 https://ideone.com/m6OjUN

2 个答案:

答案 0 :(得分:3)

substr对字节进行操作。您为它提供了一个多字节字符串,这不是一个好主意。字符ó有1个以上的字节,您在该字符的字节之间的位置精确地分割了字符串,这会破坏字符。请尝试使用mb_substr

https://3v4l.org/jkAnv

<?php
$input = '<p>Foto artística<br>Mi esposo invito uno de sus viejos amigos a casa, un hombre muy impresionante, llegó en un auto de lujo, vistiendo finas ropas, reloj de plata, cadenas de oro y cosas impresionantes, el nos platico de muchas de las cosas a las que se dedico desde que perdió la comunicación con mi esposo, desde ayudante de cocina hasta productor de películas independientes que había logrado vender por sumas importantes de dinero, el motivo de su visita era porque necesitaba a alguien como mi esposo para salir en una de sus filmaciones, a cambio recibiría una buena cantidad de dinero, clases de actuación y otros beneficios, claro que aceptamos sin pensarlo.</p>';
     $str = trim(strip_tags(nl2br($input))); //get only text

     echo mb_substr($str, 0, 99) . (mb_strlen($str) > 100 ? '...' : ''); //get part of string, if original string was longer than 100 characters add 3 dots at the end
     ?>

如果要找出一个字符/字符串有多少个字节,请使用strlen

https://3v4l.org/AKHid

<?php
var_dump(strlen('ó'));

参考文献:

http://php.net/manual/en/function.substr.php

http://php.net/manual/en/function.mb-substr.php

答案 1 :(得分:1)

Xatenev's answer是正确的。但是,我 还想补充一点,应该向人们展示如何更充分地解决该问题。

::首先执行

  • Install PHP多字节“ mbstring”模块。

您现在有三个选择;

i)在整个PHP中设置正确的编码

  • php.ini settings file中设置PHP内部编码(您也可以使用类似的功能,同样设置HTML和REGEX编码)。

ii)在整个页面上设置正确的编码

iii)仅在特定功能上设置正确的编码:

奖励积分:

这些不是直接适用于这个问题,而是可以关联的,值得再次重申。

  • 注意,在 UTF-8一直到问题上的this answer明确表明您的MySQL(如果使用)需要_utf8mb4 不是 _utf8,因为某些4字节字符仍无法由MySQL正确保存。

    您的字符ó为2个字节。

  • 也请注意this answer还表明您需要正确编码HTML输出以正确显示复数(即2个字节以上的UTF-8字符)