【问题标题】:PHP: how to remove the last line break from the text file?PHP:如何从文本文件中删除最后一个换行符?
【发布时间】:2015-05-04 23:49:58
【问题描述】:

在一次学校作业中,我使用 PHP 为我所在城市的一个虚构的太空博物馆建立了一个网站。它有一个数据包含和数据咨询系统,但是我有一个咨询问题我想知道如何解决:如何从文件中删除最后一个换行符?

数据包含

在站点的限制区域,我有一个 HTML5 表单,其中包含 5 个字段(姓名、地址、电话号码、性别和参观过的展览),它通过 POST 方法将数据发送到 PHP 中的一个函数,该函数将其写入使用fwrite命令给定txt文件:

fwrite ($pointer, "$name | $addres | $telephone | $sex | $exhibitions " .PHP_EOL);

如您所见,它将表单中输入的数据以及换行符写入一个 txt 文件。指针是fopen用来打开我需要工作的文件的变量。输出示例:

马尔西奥·阿吉亚尔 |贝尔米罗布拉加街 | 1234-5678 |中号 |太阳系的行星
乔安娜托拜厄斯 |桑托斯杜蒙大道 | 8765-4321 | F |黑洞,卫星

资料咨询

还有一个咨询系统。它有一个循环,一直运行到文件结束。在这个循环中,有一个名为$buffer 的变量,每次获取一行txt 文件。然后是exploded 创建一个名为$lines[$counter] 的数组。为了很好地打印它,我使用array_combine 将另一个数组($keys)上的字段名称连接到$lines[$counter] 中写入的值,并将其归因于$combined[$counter]。然后循环结束,我在<pre></pre> 中使用print_r 来查看写入$combined 的数据,同时保留HTML 否则会忽略的空格和中断。代码如下:

$keys = array ("Name", "Address", "Telephone", "Sex", "Visited exhibition");
for ($counter=0;!feof($reader);$counter++){
    $buffer = fgets($reader);
    $lines[$counter] = explode(" | ", $buffer);
    $combined[$counter] = array_combine($keys, $lines[$counter]);
}
echo "<pre>";
print_r($combined);
echo "</pre>";

输出示例:

    Array
    (
    [0] => Array
        (
            [Name] => Márcio Aguiar
            [Address] => Belmiro Braga Street
            [Telephone] => 1234-5678
            [Sex] => M
            [Visited exhibitions] => Planets of Solar System 

        )

    [1] => Array
        (
            [Name] => Joana Tobias
            [Address] => Santos Dummont Avenue
            [Telephone] => 8765-4321
            [Sex] => F
            [Visited exhibitions] => Black Holes, Satellites 

        )

    [2] => 
    )

在这里您可以看到2 数组被创建为空白。这是由最后一行引起的,该行仅包含由上面的表单插入的换行符。我需要删除最后一个换行符,只有那个,但不知道如何。我想知道!不知道会导致执行到达array_combine 时出现错误,因为需要两个数组具有相同数量的元素,而2 为空白。这里的错误:

警告:array_combine():两个参数在第 60 行的 E:\Aluno\Documents\Wamp\www\trab_1\area_restrita\consulta.php 中的元素数量应相同

【问题讨论】:

    标签: php arrays text explode


    【解决方案1】:

    原答案:

    要从任何文本中删除尾随换行符,您可以使用trim(),但是在您的情况下,您只需在append mode中使用fopen

    $handle = fopen("/path/to/file", "a");
    

    然后摆脱PHP_EOL

    fwrite ($pointer, "$name | $addres | $telephone | $sex | $exhibitions");
    

    编辑:你说得对,追加不会追加到新行。我误解了。所以你可以像我之前提到的那样使用 trim() 。我使用file_get_contents()file_put_contents() 创建了一个快速示例,它似乎可以满足您的需求:

    <?php
    
    $file = 'test.txt';
    
    // Set existing contents (for testing sake)
    $orig_contents = "bob | 123 fake street | 1234567890 | yes, please | no\n";
    $orig_contents .= "bob | 123 fake street | 1234567890 | yes, please | no\n";
    $orig_contents .= "bob | 123 fake street | 1234567890 | yes, please | no\n";
    $orig_contents .= "bob | 123 fake street | 1234567890 | yes, please | no\n";
    file_put_contents($file, $orig_contents);
    
    // Here is how you could add a single new line with append mode
    // Notice the trailing \n
    file_put_contents($file, "billy | 456 fake street | 2345678901 | no | yes\n", FILE_APPEND);
    
    // Get contents from the file and remove any trailing line breaks
    $contents = trim(file_get_contents($file));
    
    $keys = array ("Name", "Address", "Telephone", "Sex", "Visited exhibition");
    
    // Explode based on the new line character
    $lines = explode("\n", $contents);
    
    foreach ($lines as $line) {
        $values = explode(" | ", $line);
        $combined[] = array_combine($keys, $values);
    }
    
    print_r($combined);
    

    打印出来:

    Array
    (
        [0] => Array
            (
                [Name] => bob
                [Address] => 123 fake street
                [Telephone] => 1234567890
                [Sex] => yes, please
                [Visited exhibition] => no
            )
    
        [1] => Array
            (
                [Name] => bob
                [Address] => 123 fake street
                [Telephone] => 1234567890
                [Sex] => yes, please
                [Visited exhibition] => no
            )
    
        [2] => Array
            (
                [Name] => bob
                [Address] => 123 fake street
                [Telephone] => 1234567890
                [Sex] => yes, please
                [Visited exhibition] => no
            )
    
        [3] => Array
            (
                [Name] => bob
                [Address] => 123 fake street
                [Telephone] => 1234567890
                [Sex] => yes, please
                [Visited exhibition] => no
            )
    
        [4] => Array
            (
                [Name] => billy
                [Address] => 456 fake street
                [Telephone] => 2345678901
                [Sex] => no
                [Visited exhibition] => yes
            )
    
    )
    

    【讨论】:

    • 我不知道在哪里使用trim,你能解释一下吗?
    • 你不要把trim放在任何地方。正如答案的其余部分所解释的那样,只需使用附加模式打开文件即可。
    • 我已经在fopen 上使用a。删除PHP_EOL 会使不同人的数据全部插入一行,但我需要将信息分布在多行中,每个人一份。
    • 我看到了,但无法完全理解...当您使用$contents = trim(file_get_contents($file)); 行时,您通过使用file_get_contents() 获得了文件的全部内容,通过使用删除了所有\ns trim() 并将结果归因于 $contents,对吗?那为什么你后来使用$lines = explode("\n", $contents);?我知道这条线将$contents划分为子字符串除以\ns,并通过使用explode()将此字符串矩阵归因于$lines......但是如果你在explode()上使用参数\n已经使用trim() 删除了所有\ns?
    • @Anders 原因是trim() 只删除了第一个和最后一个空白字符。因此,如果您有{tab}line one{line break}line two{space}{line break},它会将其转换为line one{line break}line two。它不会删除 every 换行符,只有在开头或结尾有一个换行符。我做了explode() 将字符串拆分为一个数组,每一行都是数组中的一个值,这样我就可以遍历它。
    【解决方案2】:

    问题在于您读取文件的方式。在从文件中读取之前,您正在测试 EOF。但是feof() 直到您在文件末尾尝试阅读时才会为真。

    相反,您应该测试fgets() 是否返回一行。

    for ($counter = 0; $buffer = fgets($reader); $counter++) {
        $lines[$counter] = explode(" | ", $buffer);
        $combined[$counter] = array_combine($keys, $lines[$counter]);
    }
    

    DEMO

    为了进一步解释,假设您有一个包含一行的文件。当$counter0 时,调用feof(),它返回false。然后,您阅读第一行,并将其添加到$lines$combined。然后增加$counter 并返回到循环的开头。

    $counter1 时,您调用feof()。这仍然不是真的,因为您还没有尝试在文件末尾读取。然后您尝试阅读下一行,但那里没有行,fgets 返回false,然后将其分配给$buffer。这被explode() 视为一个空字符串,因此您将一个空数组添加到$lines$combined。然后增加$counter 并返回到循环的开头。

    然后你调用feof(),这一次它返回true,因为你试图在上一次迭代的文件末尾读取。这样循环就结束了。

    从上面可以看出,即使文件只有 1 行,您的数组中也会有 2 个条目,因为您在阅读太多之前没有测试 EOF。

    【讨论】:

    • 我现在明白了。但是像你建议的那样改变循环使它工作起来非常奇怪......有了这三个项目:>a |乙 | c |中号 |定义 >1 | 2 | 3 |中号 | 456 >56 | 78 | 91 |中号 | 23 > 我得到这个输出: Array ( [0] => Array ( [Name] => 1 [Address] => 2 [Telephone] => 3 [Sex] => M [Visited Exhibitions] => 456 ) [1] =>)
    • 错字:$lines[counter] 应该是 $lines[$counter]
    • 您还缺少array_combine 的右括号。代码甚至是如何运行的?
    • 代码中不存在拼写错误和缺少的括号。它们是在我将代码翻译到此处发布时引入的。
    • cmets 中没有格式,所以我不知道你的输入和输出是什么。请使用您的实际代码、测试输入和输出更新问题。
    【解决方案3】:

    如果您想删除从数据库 ($res) 中提取的数据中的最后一个换行符,您可以使用以下 sn-p

    for ($i=0; $i <count($res); $i++) {
    
        // If this is not last item then add items separated by line break
        if($i+1 < count($res)) {
            file_put_contents("file.txt", $res[$i].PHP_EOL, FILE_APPEND);
        }
        // If this is the last item, then don't append the final line break
        else {
            file_put_contents("file.txt", $res[$i], FILE_APPEND);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-22
      • 2019-06-08
      • 1970-01-01
      • 2011-03-09
      • 1970-01-01
      相关资源
      最近更新 更多