PHP,str_pad unicode问题

11 php string unicode

我只是想修复$str5个字符,但不能.

$str = "nü";
echo str_pad($str, 5, "ü"); // give nüü
Run Code Online (Sandbox Code Playgroud)

我知道这是一个unicode问题并且搜索了很多但没有运气.我试过像这样的事情;

echo str_pad($str, 4 + mb_strlen($s), $s);
echo str_pad($str, 5 + mb_strlen($s), $s);
Run Code Online (Sandbox Code Playgroud)

我也尝试了这个http://www.php.net/manual/de/function.str-pad.php#89754并看到了这个/sf/answers/831036391/.

有关这个问题的经验吗?

谢谢.

Wes*_*Wes 16

一个更简单,更有效的方法.http://3v4l.org/UnXTF

<?php

function mb_str_pad($str, $pad_len, $pad_str = ' ', $dir = STR_PAD_RIGHT, $encoding = NULL)
{
    $encoding = $encoding === NULL ? mb_internal_encoding() : $encoding;
    $padBefore = $dir === STR_PAD_BOTH || $dir === STR_PAD_LEFT;
    $padAfter = $dir === STR_PAD_BOTH || $dir === STR_PAD_RIGHT;
    $pad_len -= mb_strlen($str, $encoding);
    $targetLen = $padBefore && $padAfter ? $pad_len / 2 : $pad_len;
    $strToRepeatLen = mb_strlen($pad_str, $encoding);
    $repeatTimes = ceil($targetLen / $strToRepeatLen);
    $repeatedString = str_repeat($pad_str, max(0, $repeatTimes)); // safe if used with valid unicode sequences (any charset)
    $before = $padBefore ? mb_substr($repeatedString, 0, (int)floor($targetLen), $encoding) : '';
    $after = $padAfter ? mb_substr($repeatedString, 0, (int)ceil($targetLen), $encoding) : '';
    return $before . $str . $after;
}

// same random testing...

foreach([STR_PAD_BOTH, STR_PAD_LEFT, STR_PAD_RIGHT] as $padType)
{
    echo str_pad("FOO", 11, "aeo", $padType) . "\n";
    echo mb_str_pad("FOO", 11, "àèò", $padType, "UTF-8") . "\n";
    echo str_pad("FOO", 10, "aeo", $padType) . "\n";
    echo mb_str_pad("FOO", 10, "àèò", $padType, "UTF-8") . "\n";
    echo str_pad("BAAZ", 11, "aeo", $padType) . "\n";
    echo mb_str_pad("BAAZ", 11, "àèò", $padType, "UTF-8") . "\n";
    echo str_pad("BAAZ", 10, "aeo", $padType) . "\n";
    echo mb_str_pad("BAAZ", 10, "àèò", $padType, "UTF-8") . "\n";
    echo str_pad("FOOBAR", 6, "aeo", $padType) . "\n";
    echo mb_str_pad("FOOBAR", 6, "àèò", $padType, "UTF-8") . "\n";
    echo str_pad("FOOBAR", 1, "aeo", $padType) . "\n";
    echo mb_str_pad("FOOBAR", 1, "àèò", $padType, "UTF-8") . "\n";
    echo str_pad("FOOBAR", 0, "aeo", $padType) . "\n";
    echo mb_str_pad("FOOBAR", 0, "àèò", $padType, "UTF-8") . "\n";
    echo str_pad("FOOBAR", -10, "aeo", $padType) . "\n";
    echo mb_str_pad("FOOBAR", -10, "àèò", $padType, "UTF-8") . "\n";
    echo "--\n";
}

?>
Run Code Online (Sandbox Code Playgroud)


hol*_*321 6

您也可以使用str_repeat.

function mb_str_pad($string, $length, $pad_string = " ")
{
    return $string . str_repeat($pad_string, $length - mb_strlen($string));
}
Run Code Online (Sandbox Code Playgroud)

您可以通过添加STR_PAD_RIGHT,STR_PAD_LEFTSTR_PAD_BOTH;来升级此功能。


Ja͢*_*͢ck 5

您需要一个多字节版本的str_pad(),如下所示。它受的源代码str_pad()启发。

function mb_str_pad($input, $pad_length, $pad_string = ' ', $pad_type = STR_PAD_RIGHT, $encoding = 'UTF-8')
{
    $input_length = mb_strlen($input, $encoding);
    $pad_string_length = mb_strlen($pad_string, $encoding);

    if ($pad_length <= 0 || ($pad_length - $input_length) <= 0) {
        return $input;
    }

    $num_pad_chars = $pad_length - $input_length;

    switch ($pad_type) {
        case STR_PAD_RIGHT:
            $left_pad = 0;
            $right_pad = $num_pad_chars;
            break;

        case STR_PAD_LEFT:
            $left_pad = $num_pad_chars;
            $right_pad = 0;
            break;

        case STR_PAD_BOTH:
            $left_pad = floor($num_pad_chars / 2);
            $right_pad = $num_pad_chars - $left_pad;
            break;
    }

    $result = '';
    for ($i = 0; $i < $left_pad; ++$i) {
        $result .= mb_substr($pad_string, $i % $pad_string_length, 1, $encoding);
    }
    $result .= $input;
    for ($i = 0; $i < $right_pad; ++$i) {
        $result .= mb_substr($pad_string, $i % $pad_string_length, 1, $encoding);
    }

    return $result;
}


$str = "nü";
$pad = "ü";

echo mb_str_pad($str, 5, $pad);
Run Code Online (Sandbox Code Playgroud)


K-G*_*Gun 4

我认为您需要了解更多 php.net (此处:http: //php.net/str_pad#111147)。但我改变了一点。

\n\n

注意:不要忘记在 之前调用它mb_internal_encoding("utf-8");

\n\n
mb_internal_encoding("utf-8");\n\nfunction str_pad_unicode($str, $pad_len, $pad_str = \' \', $dir = STR_PAD_RIGHT) {\n    $str_len = mb_strlen($str);\n    $pad_str_len = mb_strlen($pad_str);\n    if (!$str_len && ($dir == STR_PAD_RIGHT || $dir == STR_PAD_LEFT)) {\n        $str_len = 1; // @debug\n    }\n    if (!$pad_len || !$pad_str_len || $pad_len <= $str_len) {\n        return $str;\n    }\n\n    $result = null;\n    if ($dir == STR_PAD_BOTH) {\n        $length = ($pad_len - $str_len) / 2;\n        $repeat = ceil($length / $pad_str_len);\n        $result = mb_substr(str_repeat($pad_str, $repeat), 0, floor($length))\n                . $str\n                . mb_substr(str_repeat($pad_str, $repeat), 0, ceil($length));\n    } else {\n        $repeat = ceil($str_len - $pad_str_len + $pad_len);\n        if ($dir == STR_PAD_RIGHT) {\n            $result = $str . str_repeat($pad_str, $repeat);\n            $result = mb_substr($result, 0, $pad_len);\n        } else if ($dir == STR_PAD_LEFT) {\n            $result = str_repeat($pad_str, $repeat);\n            $result = mb_substr($result, 0, \n                        $pad_len - (($str_len - $pad_str_len) + $pad_str_len))\n                    . $str;\n        }\n    }\n\n    return $result;\n}\n\n$t = STR_PAD_LEFT;\n$s = \'...\';\n$as = \'AO\';\n$ms = \'\xc3\x84\xc3\x96\';\necho "<pre>\\n";\nfor ($i = 3; $i <= 1000; $i++) {\n    $s1 = str_pad($s, $i, $as, $t); // can not inculde unicode char!!!\n    $s2 = str_pad_unicode($s, $i, $ms, $t);\n    $l1 = strlen($s1);\n    $l2 = mb_strlen($s2);\n    echo "len $l1: $s1 \\n";\n    echo "len $l2: $s2 \\n";\n    echo "\\n";\n    if ($l1 != $l2) die("Fail!");\n}\necho "</pre>";\n
Run Code Online (Sandbox Code Playgroud)\n\n

在这里测试: http: //codepad.viper-7.com/3jTEgt

\n