PHP in_array 只找到最后一个数组元素
PHP in_array is only finding the last array element
以下 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
函数找不到它们?
试试 preg_split
。它允许您使用正则表达式而不是精确的字符串匹配。
$multiline_string = 'First line
Second line
Third line';
$array = preg_split("/\r?\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.';
}
如果你使用双引号而不是单引号并添加回车 return \r ,它将打印出三行(注意我们没有将 \r 用于第三行)
<?php
$multiline_string = 'First line
Second line
Third line';
$array = explode("\n", $multiline_string);
dd($array);
if (in_array("First line\r", $array)){ //here we added a carriage return
echo 'First line exists.'.'<br>';
}
if (in_array("Second line\r", $array)){ //here we added a carriage return
echo 'Second line exists.'.'<br>';
}
if (in_array("Third line", $array)){ //here we did not
echo 'Third line exists.'.'<br>';
}
function dd($something){
echo '<pre>';
var_dump($something);
echo '</pre>';
}
输出将是:
array(3) {
[0]=>
string(11) "First line
"
[1]=>
string(12) "Second line
"
[2]=>
string(10) "Third line"
}
First line exists.
Second line exists.
Third line exists.
背景
要了解发生了什么,您需要了解关于如何在文本文件中表示行尾的约定。
- 在 Unix/Apple 机器上生成的文本文件通常使用单个换行符分隔行:
\n
.
- 在 Windows 机器上生成的文本文件通常用两个字符分隔行,carriage-return + line-feed:
\r\n
.
- 在非常老的 Apple 机器上生成的文本文件通常用回车 return 字符分隔行:
\r
。你可能不需要担心这个,因为它在实践中很少遇到。
维基百科有 a good summary that explains the history of these different standards.
你的问题
您的示例文件似乎是在 Windows 上创建的,因此每行之间有两个字符。这意味着当您在 \n
上 explode()
时,除了最后一行之外的每一行都将在末尾包含一个不可见的 \r
字符。这就是为什么在您的示例中只有最后一行匹配。
解决方案
根据您的多行字符串数据的来源,有几种解决方案。
如果您的情况如您的示例所示,其中字符串被定义为您控制的文件中的文字字符串,您有两个选择:
- 转换文件以使用 Unix 风格的行结尾。大多数文本 editors/IDEs 允许您通过菜单选项执行此操作。您只需为每个文件执行一次此操作(假设您在进行更改后保存它)。如果您进行此更改,您当前的代码将按原样工作。
- 更新您的代码以使用
$array = explode("\r\n", $multiline_string);
以便您根据 Windows 行结尾展开。
另一方面,如果您的数据来自用户输入,那么您应该对其进行编码以处理两种类型的行尾1。这里也有几个选项:
- 确保执行拆分的代码可以识别两种行结束样式。最简单的方法是用
$array = preg_split("/\r?\n/", $multiline_string)
替换 explode()
调用,这将在 \n
或 \r\n
. 的任何实例上爆炸
- 将一种行结束样式转换为另一种行结束样式,以便您了解正在使用的行结束样式,然后像以前一样使用
explode()
。例如,$multiline_string = str_replace("\r\n", "\n", $multiline_string);
。如果您稍后要对字符串执行其他操作,则此方法更可取,例如将其存储在数据库中,因为这意味着您只需处理一次,而不必在所有情况下都处理这两种可能性。
1 或者所有三种类型,如果你想彻底的话。这是 reader...
的练习
以下 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
函数找不到它们?
试试 preg_split
。它允许您使用正则表达式而不是精确的字符串匹配。
$multiline_string = 'First line
Second line
Third line';
$array = preg_split("/\r?\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.';
}
如果你使用双引号而不是单引号并添加回车 return \r ,它将打印出三行(注意我们没有将 \r 用于第三行)
<?php
$multiline_string = 'First line
Second line
Third line';
$array = explode("\n", $multiline_string);
dd($array);
if (in_array("First line\r", $array)){ //here we added a carriage return
echo 'First line exists.'.'<br>';
}
if (in_array("Second line\r", $array)){ //here we added a carriage return
echo 'Second line exists.'.'<br>';
}
if (in_array("Third line", $array)){ //here we did not
echo 'Third line exists.'.'<br>';
}
function dd($something){
echo '<pre>';
var_dump($something);
echo '</pre>';
}
输出将是:
array(3) {
[0]=>
string(11) "First line
"
[1]=>
string(12) "Second line
"
[2]=>
string(10) "Third line"
}
First line exists.
Second line exists.
Third line exists.
背景
要了解发生了什么,您需要了解关于如何在文本文件中表示行尾的约定。
- 在 Unix/Apple 机器上生成的文本文件通常使用单个换行符分隔行:
\n
. - 在 Windows 机器上生成的文本文件通常用两个字符分隔行,carriage-return + line-feed:
\r\n
. - 在非常老的 Apple 机器上生成的文本文件通常用回车 return 字符分隔行:
\r
。你可能不需要担心这个,因为它在实践中很少遇到。
维基百科有 a good summary that explains the history of these different standards.
你的问题
您的示例文件似乎是在 Windows 上创建的,因此每行之间有两个字符。这意味着当您在 \n
上 explode()
时,除了最后一行之外的每一行都将在末尾包含一个不可见的 \r
字符。这就是为什么在您的示例中只有最后一行匹配。
解决方案
根据您的多行字符串数据的来源,有几种解决方案。
如果您的情况如您的示例所示,其中字符串被定义为您控制的文件中的文字字符串,您有两个选择:
- 转换文件以使用 Unix 风格的行结尾。大多数文本 editors/IDEs 允许您通过菜单选项执行此操作。您只需为每个文件执行一次此操作(假设您在进行更改后保存它)。如果您进行此更改,您当前的代码将按原样工作。
- 更新您的代码以使用
$array = explode("\r\n", $multiline_string);
以便您根据 Windows 行结尾展开。
另一方面,如果您的数据来自用户输入,那么您应该对其进行编码以处理两种类型的行尾1。这里也有几个选项:
- 确保执行拆分的代码可以识别两种行结束样式。最简单的方法是用
$array = preg_split("/\r?\n/", $multiline_string)
替换explode()
调用,这将在\n
或\r\n
. 的任何实例上爆炸
- 将一种行结束样式转换为另一种行结束样式,以便您了解正在使用的行结束样式,然后像以前一样使用
explode()
。例如,$multiline_string = str_replace("\r\n", "\n", $multiline_string);
。如果您稍后要对字符串执行其他操作,则此方法更可取,例如将其存储在数据库中,因为这意味着您只需处理一次,而不必在所有情况下都处理这两种可能性。
1 或者所有三种类型,如果你想彻底的话。这是 reader...
的练习