In a school work, I built a site for a fictional space museum in my city using PHP. It has a Data Inclusion and Data Consultation systems, but I have a problem with the consultation that I want to know how to solve: how to delete the last line break from the file?
在学校工作中,我使用PHP为我所在城市的虚构太空博物馆建造了一个网站。它有一个数据包含和数据咨询系统,但我有一个问题,我想知道如何解决咨询:如何从文件中删除最后一个换行符?
Data Inclusion
In the restricted area of the site, I have a HTML5 form with 5 fields (name, addres, telephone number, sex and visited exhibitions) that sends the data by the method POST to a function in PHP that writes it on a given txt file by using the fwrite
command:
在网站的限制区域,我有一个HTML5表单,其中包含5个字段(名称,地址,电话号码,性别和访问过的展览),它们通过方法POST将数据发送到PHP中的函数,该函数将其写入给定的txt文件通过使用fwrite命令:
fwrite ($pointer, "$name | $addres | $telephone | $sex | $exhibitions " .PHP_EOL);
As you can see, it writes in a txt file the data entered on the form, plus a line break. The pointer is the variable used by fopen
to open the file that I need to work. Example of output:
如您所见,它在txt文件中写入在表单上输入的数据,以及换行符。指针是fopen用来打开我需要工作的文件的变量。输出示例:
Márcio Aguiar | Belmiro Braga Street | 1234-5678 | M | Planets of Solar System
Joana Tobias | Santos Dummont Avenue | 8765-4321 | F | Black Holes, SatellitesMárcioAguiar| Belmiro Braga Street | 1234-5678 | M |太阳系行星Joana Tobias | Santos Dummont Avenue | 8765-4321 | F |黑洞,卫星
Data Consultation
Then there is a consultation system. It has a loop that runs until the file ends. Inside this loop there is a variable named $buffer
that gets one line of the txt file each time. It is then explode
d to create a array named $lines[$counter]
. To print it nicely, I use a array_combine
where I join the names of the fields on another array ($keys
) to the values written in $lines[$counter]
, and attibutes that to $combined[$counter]
. Then the loop ends and I use a print_r
inside <pre></pre>
to see the data written in $combined
, while mantaining the spaces and breaks that HTML would otherwise ignore. Here is the code:
然后是咨询系统。它有一个循环,一直运行直到文件结束。在这个循环中有一个名为$ buffer的变量,每次都获取一行txt文件。然后展开它以创建一个名为$ lines [$ counter]的数组。为了很好地打印它,我使用array_combine,其中我将另一个数组($ keys)上的字段名称连接到$ lines [$ counter]中写入的值,并将其归结为$ combined [$ counter]。然后循环结束,我在
中使用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>";
Example of output:
输出示例:
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] => )
Here you can see that a 2
Array was created blank. It's caused by the last line, that contains only a line break inserted by the form above. I need to remove this last line break, and only that one, but don't know how. I want to know! Not knowing causes the exhibition of an error when the execution arrive at the array_combine
, because it's needed that the two arrays have the same number of elements, and 2
is blank. Here the error:
在这里你可以看到一个2数组被创建为空白。它是由最后一行引起的,它只包含上面表格插入的换行符。我需要删除最后一个换行符,只有那个,但不知道如何。我想知道!当执行到达array_combine时,不知道导致错误的展示,因为需要两个数组具有相同数量的元素,并且2是空白的。这里的错误:
Warning: array_combine(): Both parameters should have an equal number of elements in E:\Aluno\Documents\Wamp\www\trab_1\area_restrita\consulta.php on line 60
警告:array_combine():这两个参数在第60行的E:\ Aluno \ Documents \ Wamp \ www \ trab_1 \ area_restrita \ consulta.php中应具有相同数量的元素
3 个解决方案
#1
Original answer:
To remove a trailing line break from any text, you can use trim(), however in your case,
you just need to use
:fopen
in
append mode
要从任何文本中删除尾部换行符,可以使用trim(),但在您的情况下,您只需要在追加模式下使用fopen:
$handle = fopen("/path/to/file", "a");
Then get rid of the PHP_EOL
:
然后摆脱PHP_EOL:
fwrite ($pointer, "$name | $addres | $telephone | $sex | $exhibitions");
Edit: You're right that appending doesn't append to a new line. I was mistaken. So you could use trim() like I mentioned earlier. I created a quick example using file_get_contents()
and file_put_contents()
and it appears to do what you want:
编辑:你是对的,追加不会附加到新行。我误解了。所以你可以像我之前提到的那样使用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);
This prints:
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
)
)
#2
The problem is with the way you're reading the file. You're testing for EOF before reading from the file. But feof()
won't be true until you try to read while you're at the end of the file.
问题在于您正在阅读文件的方式。在从文件中读取之前,您正在测试EOF。但是,当你在文件末尾尝试阅读时,feof()将不会成立。
Instead, you should test whether fgets()
returns a line.
相反,您应该测试fgets()是否返回一行。
for ($counter = 0; $buffer = fgets($reader); $counter++) {
$lines[$counter] = explode(" | ", $buffer);
$combined[$counter] = array_combine($keys, $lines[$counter]);
}
To explain further, suppose you have a file with one line in it. When $counter
is 0
, you call feof()
, and it returns false
. So you then read the first line, and add it to $lines
and $combined
. Then you increment $counter
and go back to the beginning of the loop.
为了进一步解释,假设您有一个包含一行的文件。当$ counter为0时,你调用feof(),它返回false。然后你读取第一行,并将其添加到$ lines和$ combined。然后你增加$ counter并返回循环的开头。
When $counter
is 1
, you call feof()
. It's still not true, because you haven't tried to read at the end of the file yet. Then you try to read the next line, but there is no line there, fgets
returns false
and you assign this to $buffer
. This is treated as an empty string by explode()
, so you add an empty array to $lines
and $combined
. Then you increment $counter
and go back to the beginning of the loop.
当$ counter为1时,你调用feof()。它仍然不是真的,因为你还没有尝试在文件的末尾阅读。然后你尝试读取下一行,但是那里没有行,fgets返回false并将其分配给$ buffer。通过explode()将其视为空字符串,因此您向$ lines和$ combined添加一个空数组。然后你增加$ counter并返回循环的开头。
Then you call feof()
, and this time it returns true
because you tried to read at the end of the file on the previous iteration. So the loop ends.
然后你调用feof(),这次它返回true,因为你试图在上一次迭代的文件末尾读取。所以循环结束了。
As you can see from the above, even though the file only has 1 line, you end up with 2 entries in your arrays, because you didn't test for EOF until after you read too far.
正如您从上面所看到的,即使文件只有1行,您最终会在数组中输入2个条目,因为直到您读得太多之后才测试EOF。
#3
In case you want to get rid of the last line break in data you pulled from the db ($res) you can use the following snippet
如果你想摆脱从db($ res)中提取的数据中的最后一个换行符,你可以使用以下代码片段
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);
}
}
#1
Original answer:
To remove a trailing line break from any text, you can use trim(), however in your case,
you just need to use
:fopen
in
append mode
要从任何文本中删除尾部换行符,可以使用trim(),但在您的情况下,您只需要在追加模式下使用fopen:
$handle = fopen("/path/to/file", "a");
Then get rid of the PHP_EOL
:
然后摆脱PHP_EOL:
fwrite ($pointer, "$name | $addres | $telephone | $sex | $exhibitions");
Edit: You're right that appending doesn't append to a new line. I was mistaken. So you could use trim() like I mentioned earlier. I created a quick example using file_get_contents()
and file_put_contents()
and it appears to do what you want:
编辑:你是对的,追加不会附加到新行。我误解了。所以你可以像我之前提到的那样使用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);
This prints:
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
)
)
#2
The problem is with the way you're reading the file. You're testing for EOF before reading from the file. But feof()
won't be true until you try to read while you're at the end of the file.
问题在于您正在阅读文件的方式。在从文件中读取之前,您正在测试EOF。但是,当你在文件末尾尝试阅读时,feof()将不会成立。
Instead, you should test whether fgets()
returns a line.
相反,您应该测试fgets()是否返回一行。
for ($counter = 0; $buffer = fgets($reader); $counter++) {
$lines[$counter] = explode(" | ", $buffer);
$combined[$counter] = array_combine($keys, $lines[$counter]);
}
To explain further, suppose you have a file with one line in it. When $counter
is 0
, you call feof()
, and it returns false
. So you then read the first line, and add it to $lines
and $combined
. Then you increment $counter
and go back to the beginning of the loop.
为了进一步解释,假设您有一个包含一行的文件。当$ counter为0时,你调用feof(),它返回false。然后你读取第一行,并将其添加到$ lines和$ combined。然后你增加$ counter并返回循环的开头。
When $counter
is 1
, you call feof()
. It's still not true, because you haven't tried to read at the end of the file yet. Then you try to read the next line, but there is no line there, fgets
returns false
and you assign this to $buffer
. This is treated as an empty string by explode()
, so you add an empty array to $lines
and $combined
. Then you increment $counter
and go back to the beginning of the loop.
当$ counter为1时,你调用feof()。它仍然不是真的,因为你还没有尝试在文件的末尾阅读。然后你尝试读取下一行,但是那里没有行,fgets返回false并将其分配给$ buffer。通过explode()将其视为空字符串,因此您向$ lines和$ combined添加一个空数组。然后你增加$ counter并返回循环的开头。
Then you call feof()
, and this time it returns true
because you tried to read at the end of the file on the previous iteration. So the loop ends.
然后你调用feof(),这次它返回true,因为你试图在上一次迭代的文件末尾读取。所以循环结束了。
As you can see from the above, even though the file only has 1 line, you end up with 2 entries in your arrays, because you didn't test for EOF until after you read too far.
正如您从上面所看到的,即使文件只有1行,您最终会在数组中输入2个条目,因为直到您读得太多之后才测试EOF。
#3
In case you want to get rid of the last line break in data you pulled from the db ($res) you can use the following snippet
如果你想摆脱从db($ res)中提取的数据中的最后一个换行符,你可以使用以下代码片段
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);
}
}