Can you write line by line to a PHP variable? - php

I have a script that generates Javascript based on user form inputs. At present the code is outputted to a txt file on the server, but I'd like to put it into a MySql database.
Writing line by line to a txt file is easy with fopen, and helpful with my script due to the way the code is generated and wrapped around user inputs (various loops etc).
However, I'd really like to write the output to a variable, and then send that to the database. However, I can't see any way of accomplishing this?
Im sure it is possible, but the information I've found online only deals with quite basic variable creation.
A dirty solution would be to write to the txt file as I currently do, and then load the text file into a variable and then delete the text file. But this seems silly and clearly a waste of processing time.
Very new to Php so sorry if the above seems dumb.

It's not too difficult, you can declare the variable with the first line and then incrementally write to it, with the \n escape sequence (representing a new line) separating each line. You can size use the PHP_EOL built-in inserted, as commented. The=` assignment operator appends the string following the operator to the variable's value prior to the operation.
$lines = "my first line";
while (condition) {
$lines .= PHP_EOL . "my next line";
}
A derivative way of doing this would be to insert all the lines inside the loop and start with just declaring an empty string.
$lines = "";
while (condition) {
$lines .= "my next line" . PHP_EOL;
}
Note that this method will add an empty newline at the end, which you can trim off of needed.
Alternatively, another way would be to create an array, push to it, and then use the implode function to glue together the array into a string using a newline.
$lines = array();
while (condition) {
array_push($lines, "my next line");
}
$lines = implode(PHP_EOL, $lines);

Related

I'm having an issue with PHP and Append File

I'm trying to use file_put_contents to manage bans in a .txt
However, I'm having trouble adding text or a new line amidst the text I'm adding.
I'm using $_GET to grab the reason and information of the banned person, i.e "loser,127.0.0.1" (simple example) and then add them to the txt. Thing is I can't figure out how to add a new line. When I try adding text
<?php
file_put_contents("banned.txt", $_GET["r"], + "for example here", FILE_APPEND);
The code fails to run, I'm not sure whether or not to actually have a comma either.
This is the code I'm trying to use as of now, and it does add a line, but it doesn't go to the next line.
<?php
file_put_contents("banned.txt", $_GET["r"], FILE_APPEND);
What I'm trying to achieve is that it adds a new line, so if I said "loser,127.0.0.1" it adds that text to the txt, and goes to the next line for the next ban.
Try this
get your ban data and explicitly add the new line:
$banData = $_GET["r"] . PHP_EOL;
If you want to write csv data in the file (in a very simple way) you can do so like this:
$banData = $_GET["ban_data"] . ";" . $_GET["ban_reason"] . PHP_EOL;
then simply write to the file
file_put_contents("banned.txt", $banData, FILE_APPEND);
instead of "banned.txt" save to "banned.csv" and you're set
First code is invalid as you should not have , between your GET reference and concatenated string. Once that is fixed, just add \n (\r\n on Windows) at the end of your string that you append and you should have new lines (or to stay platform agnostic, use PHP_EOL instead).

The proper use of PHP_EOL and how to get rid of character count when reading a file

I am trying to write a function in which a string of text is written with timestamps to the file "text2.txt", I want each entry to be on a new line, but PHP_EOL does not seem to work for me.The strings simply write on the same line and does not write to a new line for each string.
Could anyone give me some pointers or ideas as to how to force the script to write to a new line every time the function is activated?
Some sort of example would be highly appreciated.
Thank you in advance.
<?php
if($_SERVER['REQUEST_METHOD'] == "POST" and isset($_POST['sendmsg']))
{
writemsg();
}
function writemsg()
{
$txt = $_POST['tbox'];
$file = 'text2.txt';
$str = date("Y/m/d H:i:s",time()) . ":" . $txt;
file_put_contents($file, $str . PHP_EOL , FILE_APPEND );
header("Refresh:0");
}
?>
Also, I want to get rid of the character count on the end of the string when using the below code :
<?php
echo readfile("text2.txt");
?>
Is there any way for the character count to be disabled or another way to read the text file so it does not show the character count?
Could anyone give me some pointers or ideas as to how to force the script to write to a new line every time the function is activated? Some sort of example would be highly appreciated.
Given the code you posted I'm pretty sure newlines are properly appended to the text lines you are writing to the file.
Try opening the file text2.txt on a text editor to have a definitive confirmation.
Note that if you insert text2.txt as part of a HTML document newlines won't cause a line break in the rendered HTML by the browser.
You have to turn them into line break tags <br/>.
In order to do that simply
<?php
echo nl2br( file_get_contents( "text2.txt" ) );
?>
Using file_get_contents will also solve your issue with the characters count display.
A note about readfile you (mis)used in the code in your answer.
Accordind to the documentation
Reads a file and writes it to the output buffer.
[...]
Returns the number of bytes read from the file. If an error occurs, FALSE is returned and unless the function was called as #readfile(), an error message is printed.
As readfile reads a file and sends the contents to the output buffer you would have:
$bytes_read = readfile( "text2.txt" );
Without the echo.
But in your case you need to operate on the contents of the file (replacing line breaks with their equivalent html tags) so using file_get_contents is more suitable.
To put new line in text simply put "\r\n" (must be in double quotes).
Please note that if you try to read this file and output to HTML, all new line (no matter what combination) will be replaced to simple space, because new line in HTML is <br/>. Use nl2br($text) to convert new lines to <br/>'s.
For reading file use file_get_contents($file);

writing to text file - layout messed up - PHP

ive got the following fwrite code, with , separating the data and it ending in ))
$shapeType = $_POST['shapeType'].','.$_POST['triangleSide1'].','.$_POST['triangleSide2']
.','.$_POST['triangleSide3'].','.$_POST['triangleColour'].'))';
fwrite($handle, $shapeType);
but this is how it saves in the text file...
,,,,))Triangle,180,120,80,Red))
why have the first set of
,,,,,))
appeared in front of what it should look like?
You need to add a new line character to the end of each line. Otherwise your lines will all run into each other.
Use PHP_EOL for this as it will automatically use the Operating System appropriate new line character sequence.
PHP_EOL (string)
The correct 'End Of Line' symbol for this platform.
Available since PHP 4.3.10 and PHP 5.0.2
$shapeType = $_POST['shapeType'].','.$_POST['triangleSide1'].','.$_POST['triangleSide2']
.','.$_POST['triangleSide3'].','.$_POST['triangleColour'].'))'.PHP_EOL;
FYI, this might be a little cleaner to do using sprintf():
$shapeType = sprintf("%s,%s,%s,%s,%s))%s",
$_POST['shapeType'],
$_POST['triangleSide1'],
$_POST['triangleSide2'],
$_POST['triangleSide3'],
$_POST['triangleColour'],
PHP_EOL
);
Without seeing more of the code I would guess that you post to the same file and you do not check if a POST request was made before you write your file. So probably you write to your file on a GET request as well, causing empty entries to appear.
You would need something like:
if ($_SERVER['REQUEST_METHOD'] === 'POST')
{
// ...
$shapeType = $_POST['shapeType'].','.$_POST['triangleSide1'].','.$_POST['triangleSide2']
.','.$_POST['triangleSide3'].','.$_POST['triangleColour'].'))';
fwrite($handle, $shapeType);
// ...
}
Edit: By the way, you should probably use fputcsv as that takes care of escaping quotes, should you change something in the future that adds for example a description field.

Replace strings in a file from an array in PHP

This is a tricky one...I am trying to replace some strings in a file that i hold in array.
Because there are a lot of files...i've been trying to find the fastest way possible.
I tried this (which worked) but it was slow.
First parsed all the files and got an array of the values i want to
change (lets say 500).
Then I wrote a foreach loop to parse through the files one by one.
Then inside that, another foreach loop to go through the values one by one
preg_replacing the file for any occurrences of the array value.
This takes forever though cause not all files need to be parsed with 500 array elements.
So i am changing the code now like this:
Parse every file and make an array of the values i want to replace.
Search the file again for all the occurrences for each array value and replace it.
Save the file
I think this will be much faster that the old way...The problem i am having though now is with the read/write loop, and the array loop...
I want to do this as fast as possible...cause there will be a lot of files to parse and some have 100+ values.
So far i got this in a function.
function openFileSearchAndReplace($file)
{
$holdcontents = file_get_contents($file);
$newarray = makeArrayOfValuesToReplace($holdcontents);
foreach ($newarray as $key => $value) {
$replaceWith = getNewValueFor($value);
$holdcontent = preg_replace('/\\b'.$value.'\\b/', $replaceWith, $holdcontents);
}
file_put_contents($file, $holdcontent, LOCK_EX); //Save and close
}
Now, this doesnt work...it just changes 1 value only because i have file_put_contents and file_get_contents outside of the foreach. (Not to mention that it replaces values that it shouldnt replace. Probably cause the read/write are outside of the loop.) I have to put them inside to work..but thats gonna be slow..cause it take 3-4seconds per file to do the change since there are a lot of elements in the array.
How can i "Open the file", "Read it", "Change ALL values first", "Then save close the file", so i can move to the next.
EDIT:
Maybe i am not explaining it well i dont know...or is this too complicated....I have to parse the array of values...there is no way i can avoid that...but instead of (In every loop), i open the file search and replace 1 value, close the file.....I want to do this:
Open the file, get the content in an array or string or whatever. For all the values i have keep replacing the text with the equivalent value, and when all the values are done...that array or string write to the file. So i am only opening/closing the file once. Instead of waiting for php to read/write/close all the time.
-Thanks
How about just using str_replace(mixed $search , mixed $replace , mixed $subject)?
You can have an array of search strings which will be replaced by their corresponding item in the replace array and as the PHP manual says:
If you don't need fancy replacing rules (like regular expressions), you should always use this function instead of preg_replace().
Also just close the file and reopen it with mode 'w'. File will be truncated to 0 length
Added Edit
$fileContents = file_get_contents("theFile");
$search = array('apples', 'oranges');
$replace = array('pears', 'lemons');
$newContents = str_replace($search, $replace, $fileContents);
$handle = fopen("theFile","w");
fwrite($handle, $newContents);
fclose($handle);
That's it your file has all the old strings replaced with new ones.
There is no solution to the problem. file_get_contents and file_put_contents simply doesnt work like that.
I appreciate everyone's attention to the problem.

Handling text file with unknown newline positions

My problem is simple: I have a text file, which i handle and insert all the data in a database and also do stuff with it for each new line. The problem is that the text file is a log for sms'es received in my gateway and depending on the text that is being sent I would have a line corresponding to each sms. If an SMS does not have any new lines in its body, everything is alright, on the other hand, if and SMS is sent like this:
"Test
TestOnANewLine"
I get a log file that breaks and with a new line everytime. A sample follows:
2012-01-01 10:10:10,4C64DCD6.req,192.168.999.999,+12223334444,OK -- SMPP - 999.999.999.999:9999,SubmitUser=user;Sender=sender;SMSCMsgId=999999999;Text="Test1
NewLineTest
AnotherNEwLineTEst"
The log file is interpreted like this:
date time, smsid, ip that processed it, number that is being sent to, status --connection type - ip that is sent from, user that submitted; sender name that is displayed; sms connection id; body of the sms
As for the language I am using PHP and for the functions used its a simple
foreach($lines as $line)
{ explode and do stuff }
How do I handle this situation? At this point any help is appreciated
Thanks in advance!!
fgetcsv could handle the linebreaks enclosed in '"' but with an additional '"' character in the body it would fail...
So what about some unresponsible regexp usage?
preg_match_all(#^(\d{4}-\d{2}-\d{2}[^,]+),([^,]+),([^,]+),([^,]+),([^,]+),SubmitUser=([^;])+;Sender=([^;])+;SMSCMsgId=([^;])+;Text="([\w\d\s\.\-,:;'"]+)"$#im', $file, $matches);
should do the job, for not too crazy texts, maybe you should adpot the \w\d\s.-,:;'" expression more to your needs
Couldn't you loop through the newlines until you can parse a date from it?
Maybe take into account that the previous line ended with a double quote ?
I know its not fool proof but without some recognisable "end of message" character(s). This is the best i could think of :P
First of all, thank you for all the feedback, it was really precious and it helped me on solving this issue. Also, for all the other people that will look through this post and would want a solution here is mine:
I changed the way I would interpret the end of line /r/n from the regular one to /r/n2 which means that ill consider a new line in my file reading if and only if there is a regular new line /r/n and on the new physical line there is a 2 (which is the beginning of the year)
The actual solved part is:
$data = file_get_contents($backup_file);
$lines=explode("\r\n2",$data);
foreach($lines as $line)
{
//explode and do stuff
}
Try this to get all the log entries normalized into a single array item per log entry (i.e. combine entries across multiple line breaks into a single item)
$line_array = file('/path/to/file');
$log_array = array();
$i = -1;
$date_pattern = '/^[0-9]{4}-[0-9]{2}-[0-9]{2}\s[0-9]{2}:[0-9]{2}:[0-9]{2}/';
foreach ($line_array as $line) {
if (1 === preg_match($date_pattern, $line)) {
// this is a new log entry
// let's trim the whitespace from the end of the last log array entry since we are done with it
if(isset($log_array[$i])) {
$log_array[$i] = rtrim($log_array[$i]);
}
// start a new log array entry
$i++;
$log_array[$i] = $line;
} else {
// this is not a new log entry
$log_array[$i] .= $line;
}
}
After that you should be able to work with $log_array to extract the data you need. By the way I should note that when you loop through the $log_array. It would probably be helpful to extract the msg text first. If you do a greedy preg_match on the double quotes, you shouldn't have any problems with messages that have quotes within them as the greedy match will find the largest possible matching string, which in your case would be everything between the quotes bounding the message content.

Categories