【问题标题】:strings in PHP really an array of characters or something else?PHP中的字符串真的是一个字符数组还是其他什么?
【发布时间】:2011-09-10 12:52:33
【问题描述】:

考虑

$foo = "abcdefg";

echo $foo[0]; //outputs a

所以看起来字符串就像字符数组,但是为什么

foreach($foo as $char)
{
echo $char;
}

不起作用并给出以下警告??

Warning: Invalid argument supplied for foreach() 

【问题讨论】:

  • 旧的符号(仍在使用但已弃用)是 echo $foo{0}; 我不明白他们为什么要更改它。
  • @Jacco:它没有被弃用;)
  • @NikiC:你确定吗?我也有同样的印象。
  • @Jon: 我是 ;) codepad.viper-7.com/X0lgFz (在 5.3 开发期间它被弃用了很短的时间。我不知道他们为什么恢复它,可能只是一个意外。)
  • @jacco 我刚刚检查了它及其工作,我更喜欢 {} 而不是带有字符串的 [] 因为它让我认为它是一个数组:)

标签: php arrays string foreach character


【解决方案1】:

foreach 添加字符串迭代支持是discussed but declined。做出这个决定主要有两个原因:

  • 它使应用程序更难调试。通常你不想遍历字符串的字符。你只需要很少。所以如果你对一个字符串进行迭代,你可能只是犯了一个编程错误——PHP 会告诉你的。如果引入字符串迭代,这种错误将很难被发现。
  • 什么是“字符”? PHP 应该遍历每个字节吗?它应该遍历字符(可以是多个字节)吗?如果是这样,如果遇到格式错误的多字节序列应该怎么办?它从哪里获取字符集?

为了解决这两个问题,有人提议引入TextIterator,您将传递一个字符串和一个字符集。这样你就不会意外地迭代一个字符串,并且不存在字节与字符的问题。我不确定TextIterator 目前的状态是什么。

【讨论】:

  • TextIterator 听起来是个好主意。 :)
  • 如果 PHP 解释器可以在 foreach 中为我们处理这个问题,那就太好了
  • 您经常需要通过 graphemes(用户可见字符)进行交互,而不是仅仅通过 code point(程序员可见字符)更不用说通过无用的愚蠢代码单元(计算机可见字符)。您可以使用正则表达式通过 \X 一次遍历一个字形字符串。
  • @tchrist:请注意 PHP 不是 Perl。在 PCRE 中,\X 仅匹配扩展的 unicode 序列(即,非标记字符后跟任意数量的标记字符),而 Perl 则一直匹配扩展的字素簇。
【解决方案2】:

NikiC 的回答涵盖了为什么不能直接这样做。

如果您想像数组一样迭代字符串,您可以使用str_split 来明确:

foreach(str_split($foo) as $char) 
{ 
    echo $char; 
} 

警告:str_split 无法识别编码,因此您最终将迭代 字节 而不是 字符。迭代字符有点复杂,因为没有等效的多字节拆分函数。您可以使用启用正则表达式的mb_split 自行推出,请查看comments from PHP.net 以获取想法。

这里还有其他答案建议您将字符串转换为数组,但我不明白为什么会这样。 documentation 非常明确:

对于任何类型:整数、浮点数、字符串、布尔值和资源, 将值转换为数组会生成一个包含单个 索引为零的元素和标量的值 转换。换句话说, (array)$scalarValue 与 数组($scalarValue)。

确实,这样做does not work as suggested

【讨论】:

    【解决方案3】:

    即使它们的字符可以使用方括号来寻址,strings aren't arrays。强调我的:

    可以通过使用方数组括号指定字符串后所需字符的从零开始的偏移量来访问和修改字符串中的字符,如 $str[42]。出于此目的,将字符串视为字符数组

    【讨论】:

      【解决方案4】:

      它被称为“语法糖”。

      例如,在 5.4 中,您将能够这样做echo func()[0];
      并不意味着函数实际上是一个字符数组。
      这只是一种语法。

      【讨论】:

        猜你喜欢
        • 2015-01-01
        • 1970-01-01
        • 2015-05-16
        • 1970-01-01
        • 2013-11-21
        • 2019-08-04
        • 2020-08-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多