为什么在PHP中使用str_shuffle()时会丢失一些字符?

为什么在PHP中使用str_shuffle()时会丢失一些字符?,php,string,special-characters,shuffle,Php,String,Special Characters,Shuffle,这是lib.php中的代码: <?php class table { function __construct($string, $time) { $out = '<table cellpadding="5">'; $out .= $this->getRow('th', 'Nom., Shuffled String, Lenght'); for ($x = 1; $x <= $time; $x++) {

这是lib.php中的代码:

<?php

class table {

    function __construct($string, $time) {

        $out = '<table cellpadding="5">';
        $out .= $this->getRow('th', 'Nom., Shuffled String, Lenght');

        for ($x = 1; $x <= $time; $x++) {

            $shuffledStr = str_shuffle($string); //Maybe this causes the problem
            $shuffledStr_len = strlen($shuffledStr);
            $out .= $this->getRow('td', $x . ', ' . $shuffledStr . ', ' . $shuffledStr_len);
        }

        $out .= '</table>';

        echo $out;
    }

    public function getRow($tagName, $contents_list) {

        //Variables:
        $out = '';
        $contents_array = explode(', ', $contents_list);
        $contents_number = count($contents_array);
        $start_tag = '<' .  $tagName . '>';
        $end_tag = '</' .   $tagName . '>';

        // Build
        $out .= '<tr>';

        for ($i = 0; $i < $contents_number; $i++) {
            $out .= $start_tag . $contents_array[$i] . $end_tag;
        }

        $out .= '</tr>';

        return $out;
    }

}
?>

下面是index.php:

    <?php
require_once 'lib.php';
$string = ''; //My string
$shuffleTimes = 100;
$table = new table($string, $shuffleTimes);
?>

这个程序得到一个字符串和一个你想洗牌的数字, 然后创建一个表并返回数字、无序字符串和每行无序字符串的长度

例如,如果我将变量
$string
设置为“Stack Overflow”,它将正常工作(它将这个单词随机洗牌100次,返回所有长度14,所有洗牌字符串的长度实际上是14。)

但是

如果我向变量
$string
(例如
堆栈溢出+)(*&^%${}[]@./=-
)添加一些特殊字符,它将无法正常工作。这意味着它返回的长度为37,但它们没有37个字符!(例如,它打印的是
nothing
,打印的是长度
38
)。 我觉得有点奇怪(


为什么会这样?!是哪个字符引起的,以及如何修复它?

听起来编码有问题

您是否尝试过使用正确处理编码的函数

试试这个:(从PHP手册中复制)

函数unicode\u shuffle($string,$chars,$format='UTF-8')
{

对于($i=0;$i听起来像是编码问题

您是否尝试过使用正确处理编码的函数

试试这个:(从PHP手册中复制)

函数unicode\u shuffle($string,$chars,$format='UTF-8')
{

对于($i=0;$i),您的代码存在多个问题

1.getRow()问题: 问题出现在
getRow()
中,您使用
将参数合并成一个字符串,然后按
分解。如果字符串中有
,则会出现问题,例如:
堆栈,测试

2.多字节问题: 此代码不适用于多字节字符。为此,您需要使用以下函数更改函数
str_shuffle()
,并使用
mb_shuffle()
更改函数
strlen()

或者在上的注释中找到的其他unicode函数

3.长度正常,但缺少字符串问题:
这是因为您的字符串中有HTML特殊字符,如
。如果字符串
堆栈溢出+(*&^%$${}[]@./=-
被洗牌,您会得到类似
a^&/c-\O.
的内容,而不是
a^&/c-\O.<~*>)$wevS+{%}klr[]f=to!@
。输出字符串时应使用特殊字符进行转义。

您的代码存在多个问题

1.getRow()问题: 问题出现在
getRow()
中,您使用
将参数合并成一个字符串,然后按
分解。如果字符串中有
,则会出现问题,例如:
堆栈,测试

2.多字节问题: 此代码不适用于多字节字符。为此,您需要使用以下函数更改函数
str_shuffle()
,并使用
mb_shuffle()
更改函数
strlen()

或者在上的注释中找到的其他unicode函数

3.长度正常,但缺少字符串问题:
这是因为您的字符串中有HTML特殊字符,如
。如果字符串
堆栈溢出+(*&^%$${}[]@./=-
被洗牌,您会得到类似
a^&/c-\O.
的内容,而不是
a^&/c-\O.<~*>)$wevS+{%}klr[]f=to!@
。在输出字符串时,应使用转义特殊字符。

堆栈溢出+)(*&^%${}[]@!~./=-
是37个字符的长度…?是的,是的。不是吗?你说的是
但他们没有37个字符!
。现在怎么办?它有37个字符吗?顺便说一下。你的代码对我有效。它只对多字节字符无效。它返回
什么都没有
,还返回37个字符。什么是“多字节”字符?你能解释或给出一个链接吗?
堆栈溢出+(*&^%$#{}[]@!~./=-
是37个字符的长度…?是的,是的。不是吗?你说的是
但他们没有37个字符!
。现在怎么办?它有37个字符吗?顺便说一下。你的代码对我有效。它只对多字节字符无效。它返回
什么都没有
,还返回37个字符。什么是“多字节”字符?您能解释一下或提供一个链接吗?谢谢您提醒我有关
htmlspecialchars()
。字符串应该不转义处理,因为转义会增加字符串的长度。字符串必须在显示之前转义。(问题出现在lib.php的第14行,它应该改为“$out.=$this->getRow。)('td'、$x.'、'.htmlspecialchars($shuffledStr.'、'.$shuffledStr_len);`SOLVED:)感谢您提醒您有关
htmlspecialchars()
。字符串应在不转义的情况下处理,因为转义会增加字符串的长度。字符串必须在显示之前转义。(问题出现在lib.php的第14行,它应该改为“$out.=$this->getRow('td',$x.”,'.htmlspecialchars($shuffledStr.),“$shuffledStr_len);`SOLVED:”)不,这不起作用。如果你想这样做,可以这样做:函数unicode_shuffle($string,$chars,$format='UTF-8'){返回mb substr(str_shuffle_unicode($string),0,$chars,$format);}不,这不起作用。如果需要,请执行以下操作:函数unicode_shuffle($string,$chars,$format='UTF-8'){return mb_substr(str_shuffle_unicode($string),0,$chars,$format);}
function unicode_shuffle($string, $chars, $format = 'UTF-8')
{
    for($i=0; $i<$chars; $i++)
        $rands[$i] = rand(0, mb_strlen($string, $format));

        $s = NULL;

    foreach($rands as $r)
        $s.= mb_substr($string, $r, 1, $format);

    return $s;
}
function mb_str_shuffle($str) {
    $tmp = preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY);
    shuffle($tmp);
    return join("", $tmp);
}