首页 > 解决方案 > PHP in_array 只找到最后一个数组元素

问题描述

下面的 PHP 代码将一个多行字符串分解为一个数组。然后使用三个if语句检查数组中是否存在特定的行,如果存在则回显相应的文本。

$multiline_string = 'First line
Second line
Third line';

$array = explode("\n", $multiline_string);

if (in_array('First line', $array))
{
    echo 'First line exists.';
}

if (in_array('Second line', $array))
{
    echo 'Second line exists.';
}

if (in_array('Third line', $array))
{
    echo 'Third line exists.';
}

问题是只有Third line exists.回显,这意味着在数组中找不到第一行和第二行。

但是我通过使用进行了调试print_r($array)并得到了这个输出:

Array
(
    [0] => First line
    [1] => Second line
    [2] => Third line
)

所以第一行和第二行确实存在于数组中。为什么in_array函数没有找到它们?

标签: phparraysexplodemultiline

解决方案


背景

要了解发生了什么,您需要了解关于如何在文本文件中表示行尾的多种约定。

  • 在 Unix/Apple 机器上生成的文本文件通常用一个换行符分隔行:\n.
  • 在 Windows 机器上生成的文本文件通常用两个字符分隔行,回车 + 换行:\r\n
  • 在非常旧的 Apple 机器上生成的文本文件通常用回车符分隔行:\r. 您可能不需要担心这一点,因为它在实践中很少遇到。

维基百科有一个很好的总结,解释了这些不同标准的历史

你的问题

看起来您的示例文件是在 Windows 上创建的,因此每行之间有两个字符。这意味着当您explode()\n除最后一行之外的每一行时,最后都会包含一个不可见\r字符。这就是为什么在您的示例中只有最后一行匹配。

解决方案

对此有几个解决方案,具体取决于您的多行字符串数据的来源。

如果您的情况如示例中所示,其中字符串在您控制的文件中定义为文字字符串,您有两个选择:

  1. 将文件转换为使用 Unix 样式的行尾。大多数文本编辑器/IDE 允许您通过菜单选项执行此操作。您只需为每个文件执行一次(假设您在进行更改后保存它)。如果您进行此更改,您当前的代码将按原样工作。
  2. 更新要使用的代码,$array = explode("\r\n", $multiline_string);以便基于 Windows 行尾进行爆炸。

另一方面,如果您的数据来自用户输入,那么您应该对其进行编码以处理两种类型的行尾1。这里也有几个选项:

  1. 确保执行拆分的代码能够识别两种行尾样式。最简单的方法是将explode()调用替换为 ,这将在or$array = preg_split("/\r?\n/", $multiline_string)的任何实例上爆炸。\n\r\n
  2. 将一种行尾样式转换为另一种行尾样式,以便您知道正在使用的行尾样式,然后explode()像以前一样使用 。例如,$multiline_string = str_replace("\r\n", "\n", $multiline_string);。如果您稍后要对字符串执行其他操作,例如将其存储在数据库中,则此方法更可取,因为这意味着您只需要处理一次,而不必在所有情况下都处理这两种可能性。

1或所有三种类型,如果你想彻底。这留给读者作为练习......


推荐阅读