当我在PHP中使用str_shuffle()时,为什么有些字符会丢失?

时间:2013-09-10 12:35:38

标签: 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++) {

            $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);
?>

这个程序获取一个字符串和你想要随机播放的数字, 然后创建一个表并返回每行中的数字,混洗字符串和shuffle字符串的长度。

如果我将变量$string设置为'Stack Overflow',例如它将正常工作(它随机地将此单词洗牌100次,返回所有长度14和 ALL 改组的字符串真的是14。)

但是...

如果我在变量$string中添加一些特殊字符(例如Stack Overflow+_)(*&^%$#{}[]<>@!~./=-),它将无法正常工作。这意味着它返回长度37但它们没有37个字符!(例如,它打印nothing并打印它的长度38。 我觉得这有点奇怪。 :(

为什么?!哪个角色会导致这种情况以及如何解决?

2 个答案:

答案 0 :(得分:1)

您的代码存在多个问题。

1。 getRow()问题:

问题出在getRow(),您可以使用,将参数连接到一个字符串,然后按,进行展开。如果您的字符串中包含,,那么您将遇到问题,例如:Stack ,test

2。多字节问题:

此代码不适用于多字节字符。要完成此操作,您需要使用str_shuffle()下的函数更改函数mb_str_shuffle(),并使用strlen()更改mb_strlen()

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

或者您在http://php.net/manual/en/function.str-shuffle.php

的评论中找到的其他一些unicode函数

3。长度没问题,但缺少字符串问题:

这是因为您的字符串中包含HTML特殊字符,例如<>。如果对字符串Stack Overflow+_)(*&^%$#{}[]<>@!~./=-进行了随机播放,那么您会得到类似a#^&/c-_O.而不是a#^&/c-_O.< ~*>)$wevS+{(%}klr[]f=to!@的内容。输出字符串时,应该使用htmlspecialchars()转义特殊字符。

答案 1 :(得分:0)

听起来像编码问题。

您是否尝试使用处理编码的函数?

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

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;
}