PHP Add string to line 2 - php

I want to add a string (the value of a DOM element - $entry = stripslashes($_GET["nameofmytextarea"]);) to the second line of myfile.csv (so as not to delete the header).
I don't care about CSV stuff, everything is already formatted. Just treat it as a text string being added to a text file.
I don't want anything complicated, just skip the first line and "append" above the second line: under the header but above all the other CSV lines.
How hard can that be?

$contents = explode("\n", file_get_contents('myfile.csv'), 2);
file_put_contents('myfile.csv', $contents[0]."\n".$entry."\n".$contents[1]);
This should work if the lines are separated by unix-lineendings.
If the file first looks like this:
header
content
content2
and the code is run with $entry = 'test'; it will look like this afterwards:
header
test
content
content2

A combination of file() and array_splice() is what you need here:
function prepend_to_csv ($file, $line) {
if (!$data = file($file)) {
return FALSE;
}
array_splice($data, 1, 0, $line.PHP_EOL);
return (bool) file_put_contents($file, $data);
}
if (prepend_to_csv('myfile.csv', "this,is,some,data")) {
echo 'Success';
} else {
echo 'Fail';
}
Because of the way this method works, you need to ensure that you manually add the EOL to the new line yourself.

Related

how to use php to read one specific line from a text file that occurs after a tag

I am trying to read data from a plain text file from an industrial machine recipe. The file is generated automatically by the tool. I want to access a specific parameter in a specific section of the file.
The parameter is called "LightSrcRef_NominalGL" The problem is that there are some number of parameters named as such in the file. I specifically want the first one, and only the one, that occurs after the tag "[Scan2d]"
Note that the parameter I need does not always show on the same line number and that [Scan2d] does not always show up in the same place, but I need the parameter in the Scan2d section. It also appears that the LightSrcRef_NominalGL parameter is not always the same number of lines after [Scan2d].
What I had hoped was to read the file line by line. When I get to [Scan2d], set a flag, then when I get to the parameter, set my variable, then get out.
This is not happening. Instead, it is taking the first LightSrcRef_NominalGL in the file.
We have similar recipe analyzers, but this is the first one with this unique recipe structure. I have looked for a way to read the file in differently, but none produce different results.
When I print the actual line, it shows that the text file is reading it line by line. I do not understand why it is not behaving as expected.
Here is example of text file. In this case it is at the end of the file. In others, there will be another section after. I had to add an extra carriage return in the text file because this was not displaying them as separate lines. They are being read in by lines because if I have it print $line, it shows exactly one line.
[Scan2d]
CameraTypeName=2D
FocusPosAboveChuck=-2.59084174217116
Mag=5
CameraName=HighMag
DifRingPos=2
Gamma=-1
LightSrcDif_ColorFilter=Gray
LightSrcDif_NominalGL=0
LightSrcRef_ColorFilter=Cyan
LightSrcRef_NominalGL=195.424629214628
$catcher = 0; //used to verify the parameter only in scan2d section
$lines = file($dir.$default_directory."/".$current_recipe_file);
foreach($lines as $line)
{ $line_count ++;
if(preg_match("/[Scan2d]\b/i", $line))
{
$catcher = $line_count; //used to only catch the parameter in the Scan2D section
}
if(preg_match("/\bLightSrcRef_NominalGL=\b/i", $line))
{
$illumination_split_temp1 = preg_split("/\=/", $line);
$recipe_illum = $illumination_split_temp1[1];
if ($catcher >0)
{print $line . " ". $catcher . "<br>";
$Tool_Ins150_Stats->Add_Recipe_Tag("Illumination Level", $recipe_illum);
$catcher= 0;
break;
}
}
}
It is taking the first LightSrcRef_NominalGL in the file, not the one after Scan2d.
If the tags you are looking for are at the start of the lines in the file this can be made even simpler. I changed what you had slightly so that when the section you are interested in is found the foreach goes to the next record.
$catcher = 0;
foreach($lines as $line) {
if(preg_match("/[Scan2d]\b/i", $line)) {
$catcher = 1;
continue;
}
if(preg_match("/\bLightSrcRef_NominalGL=\b/i", $line)) {
if (!$catcher) {
continue; // we haven't found the right section yet
}
$illumination_split_temp1 = preg_split("/\=/", $line);
$recipe_illum = $illumination_split_temp1[1];
print $line . " ". $catcher . "<br>";
$Tool_Ins150_Stats->Add_Recipe_Tag("Illumination Level", $recipe_illum);
$catcher= 0;
break;
}
}
$lines = file($dir.$default_directory."/".$current_recipe_file);
$catcher = 0; //used to verify the parameter only in scan2d section
foreach($lines as $line)
{
if(preg_match("/\[Scan2d]/", $line))
{
$catcher = 1; //used to only catch the parameter in the Scan2D section
}
if (!$catcher)
{
continue; // haven't found the right one yet, skip the rest
}
else
{
if(preg_match("/LightSrcRef_NominalGL=/", $line))
{
$illumination_split_temp1 = preg_split("/\=/", $line);
$recipe_illum = $illumination_split_temp1[1];
$Tool_Ins150_Stats->Add_Recipe_Tag("Illumination Level", $recipe_illum);
$catcher = 0;
continue;
}
}
}
This worked, but many thanks to Dave who certainly put me on the right track!! The use of Else worked when I still do not fully understand why the second preg_match was executing if $catcher was not set (and it wasn't, I printed it to be sure).
The sample your provided seems to be a file in ini format. If this is really the case, there is a very simple solution using the parse_ini_file function
<?php
$values = parse_ini_file('sample.txt', true, INI_SCANNER_TYPED);
echo "The value is " . $values["Scan2d"]["LightSrcRef_NominalGL"] . "\n";
I tried against this sample.txt file
[test]
LightSrcRef_NominalGL=0
[Scan2d]
CameraTypeName=2D
FocusPosAboveChuck=-2.59084174217116
Mag=5
CameraName=HighMag
DifRingPos=2
Gamma=-1
LightSrcDif_ColorFilter=Gray
LightSrcDif_NominalGL=0
LightSrcRef_ColorFilter=Cyan
LightSrcRef_NominalGL=195.424629214628
[test2]
LightSrcRef_NominalGL=1
And the result is:
The value is 195.42462921463
Of course, this will work only if your entire file respects the ini format as in your sample data.

how to skip empty lines from a txt file with php

I am using this code to delete an email address form a txt file named database-email.txt:
// unsubscribe
if (isset($_POST['email-unsubscribe'])) {
$emailToRemove = $_POST['email-unsubscribe'] . ',';
$content = file_get_contents('database-email.txt');
if($content = str_replace($emailToRemove, '', $content)) {
echo "$emailToRemove successfully removed!";
}
else {
echo "$emailToRemove could not be removed!";
}
file_put_contents('database-email.txt', $content);
}
?>
My txt file looks like this:
annelore#mail.ru,
francien#live.nl,
frans#moonen.nl,
harry#hotmail.com,
jannie#live.nl,
jeanette.schmitz#live.nl,
johnny.doe#live.nl,
I tried this to skip all the empty lines in the txt file but without success:
file_put_contents('database-email.txt', implode(PHP_EOL, file($content, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)));
How can i skip the empty lines from database-email.txt ?
Use the file() function with FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES options to read the file as an array. Then use the array_search() function to search for the element and remove it if it's present. You can then implode the array and write it back to file.
Don't use your str_replace approach, it's buggy. Imagine this is your file:
abdc#domain.com
If you remove dc#domain.com you will get:
ab
You are not checking that you are replacing an entire email.
I would also suggest that you remove the commas, you don't need them if you have only one email per line.
You could try something like this :
file_put_contents('database-email.txt',
str_replace("\n\n", "\n", file_get_contents('database-email.txt'))
);
NB \n depends of how you inserts lines in your file. It could be \r\n or PHP_EOL.
This should do the trick:
file_put_contents('database-email.txt', implode('', file($content, FILE_SKIP_EMPTY_LINES)));
Alternatively:
file_put_contents('database-email.txt',preg_replace('~[\r\n]+~',"\r\n",trim($content)));

How to format I/O data from script

I was using a script to exclude a list of words from another list of keywords. I would like to change the format of the output. (I found the script on this website and I have made some modification.)
Example:
Phrase from outcome: my word
I would like to add quotes: "my word"
I was thinking that I should put the outcome in new-file.txt and after to rewrite it, but I do not understand how to capture the result. Please, kindly give me some tips. It's my first script :)
Here is the code:
<?php
$myfile = fopen("newfile1.txt", "w") or die("Unable to open file!");
// Open a file to write the changes - test
$file = file_get_contents("test-action-write-a-doc-small.txt");
// In small.txt there are words that will be excluded from the big list
$searchstrings = file_get_contents("test-action-write-a-doc-full.txt");
// From this list the script is excluding the words that are in small.txt
$breakstrings = explode(',',$searchstrings);
foreach ($breakstrings as $values){
if(!strpos($file, $values)) {
echo $values." = Not found;\n";
}
else {
echo $values." = Found; \n";
}
}
echo "<h1>Outcome:</h1>";
foreach ($breakstrings as $values){
if(!strpos($file, $values)) {
echo $values."\n";
}
}
fwrite($myfile, $values); // write the result in newfile1.txt - test
// a loop is missing?
fclose($myfile); // close newfile1.txt - test
?>
There is also a little mistake in the script. It works fine however before entering the list of words in test-action-write-a-doc-full.txt and in test-action-write-a-doc-small.txt I have to put a break for the first line otherwise it does not find the first word.
Example:
In test-action-write-a-doc-small.txt words:
pick, lol, file, cool,
In test-action-write-a-doc-full.txt wwords:
pick, bad, computer, lol, break, file.
Outcome:
Pick = Not found -- here is the mistake.
It happens if I do not put a break for the first line in .txt
lol = Found
file = Found
Thanks in advance for any help! :)
You can collect the accepted words in an array, and then glue all those array elements into one text, which you then write to the file. Like this:
echo "<h1>Outcome:</h1>";
// Build an array with accepted words
$keepWords = array();
foreach ($breakstrings as $values){
// remove white space surrounding word
$values = trim($values);
// compare with false, and skip empty strings
if ($values !== "" and false === strpos($file, $values)) {
// Add word to end of array, you can add quotes if you want
$keepWords[] = '"' . $values . '"';
}
}
// Glue all words together with commas
$keepText = implode(",", $keepWords);
// Write that to file
fwrite($myfile, $keepText);
Note that you should not write !strpos(..) but false === strpos(..) as explained in the docs.
Note also that this method of searching in $file will maybe give unexpected results. For instance, if you have "misery" in your $file string then the word "is" (if separated by commas in the original file) will be refused, as it is found in $file. You might want to review this.
Concerning the second problem
The fact that it does not work without first adding a line-break in your file leads me to think it is related to the Byte-Order Mark (BOM) that appears in the beginning of many UTF-8 encoded files. The problem and possible solutions are discussed here and elsewhere.
If indeed it is this problem, there are two solutions I would propose:
Use your text editor to save the file as UTF-8, but without BOM. For instance, notepad++ has this possibility in the encoding menu.
Or, add this to your code:
function removeBOM($str = "") {
if (substr($str, 0,3) == pack("CCC",0xef,0xbb,0xbf)) {
$str = substr($str, 3);
}
return $str;
}
and then wrap all your file_get_contents calls with that function, like this:
$file = removeBOM(file_get_contents("test-action-write-a-doc-small.txt"));
// In small.txt there are words that will be excluded from the big list
$searchstrings = removeBOM(file_get_contents("test-action-write-a-doc-full.txt"));
// From this list the script is excluding the words that are in small.txt
This will strip these funny bytes from the start of the string taken from the file.

Check for header in csv and ignore header in php

I would like to check if csv file contain a header and ignore the header.
I have to do a check if the first column is not a character
csv file has format : avgTemperature, minTemperature, maxTemperature
$f = fopen("./uploads/" .$filename, "r");
$string = "avgTemperature";
if (fgetcsv($f)==$string){
// read the first line and ignore it
fgets($f);
}
I assume your complete code uses a loop (while or for).
As such, you have a few options.
Simply skip the first row always.
Use logic to test for the header row then skip.
Either way, continue is the key piece.
PHP pseudo code:
while (…) {
if ($row == $header_row) {
continue;
}
// data rows
}
UPDATE
The logic for determining if the first row is a header row seems like a better solution in your case. You could use the following to test for that.
if ($row[0] == 'avgTemperature') {
// header row
}
Note: This makes the assumption that the first column of data is avgTemperature and it's header is avgTemperature. Adjust as necessary.
Going from your comment, and from the idea that the actual data is temperatures (i.e. numeric data), if you do have headers, then they will be text strings and not numbers. Therefore you can do something like this:
$f = fopen("./uploads/" .$filename, "r");
if(!($data = fgetcsv($f))) {
return; //most likely empty file
}
if(!is_numeric($data[0])) {
//this is your header line - skip it - and read the next line
$data = fgetcsv($f);
}
while($data) {
//process a line of data
...
//and read the next line
$data = fgetcsv($f);
}
EDIT: An alternative version of the last loop would look like this:
do {
//process a line of data
...
}
while ($data = fgetcsv($f));

Script to read in line, select from value, and print to file

So I have a php script, I want to read in a file line by line, each line only contains one id. I want to select using sql for each id in the file, then print the result for each selection in the same file.
so far i have:
while (!feof($file))
{
// Get the current line that the file is reading
$currentLine = fgets($file) ;
//explodes integers by amount of sequential spaces
//$currentLine = preg_split('/[\s,]+/', $currentLine);
echo $currentLine; //this echo statement prints each line correctly
selectQuery($currentLine) ;
}
fclose($file) ;
as a test so far i only have
function selectQuery($currentLine){
echo $currentLine; //this is undefined?
}
The result of fgets is never undefined. However, your approach is way too low-level. Use file and array_filter:
$results = array_filter(file('input.filename'), function(line) {
return strpos($line, '4') !== false; // Add filter here
});
var_export($results); // Do something with the results here

Categories