I'm trying to grab a specific value out of a file and turn it into a variable. I've manged to figure this out, but there is a catch. I need to get the variable even if the file changes so I can't depend getting this value by reading a certain line from the file as it will change on a regular basis. Here is my file and code:
# the file.props contents:
color=red
height=tall
length=short
weight=heavy
size=small
shape-name=round
Php code:
<?php
$file = "/home/user/files/file.props";
$contents = file($file, FILE_SKIP_EMPTY_LINES);
$shape_name = substr(trim($contents[5]), 11);
?>
<?php echo "$shape_name"; ?>
The above works but only if "shape-name=round" is on line 6 of the file as I am using $contents[5] to get it. Is it possible to do this if the line the "shape-name=round" is constantly being altered? IE: tomorrow it will be on line 9, the next day it could be on line 4 etc... Basically I can't depend on what line "shape-name=round" is on but I need to grab it. Not sure I am describing this correctly so please let me know if I need to clarify anything.
Maybe you mean something like this?
foreach($contents as $line) {
list($option, $value) = explode('=', $line);
if ($option == 'shape-name') {
$shape_name = $value;
} elseif ($option == 'size') {
$size = $value;
}
// you can include as many option as possible here
}
you need to loop your data. like this:
$row = 0;////get the row number.
foreach ($contents as $cs){
$row++;
if($row >= 6){
////do something
}
}
HAPPY CODING!
Related
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.
i have a problem i couldn't figure out since im self-taught and still exploring the php world
so i have a text file that looks like this:
951753159
456787541
123156488
748651651
and i got an url with a variable
http://example.com/mypage.php?variable=951753159
what i want is to check if the url variable matches one of the txt file lines in order to execute a code
i already tried this
$search = $_GET["variable"];
$file = "variables.txt";
if (preg_match('/^' . $search . '$/m', file_get_contents($file))) {
THE CODE THAT I WANT TO EXECUTE
}
but for some reason it matches the whole content of the file
any help is highly appreciated
Thanks in advance :)
Try with an array from file():
$lines = file("variables.txt", FILE_IGNORE_NEW_LINES);
if(in_array($_GET["variable"], $lines)) {
// YES FOUND
} else {
// NOT FOUND
}
From the documentation on `file_get_contents', the entire contents of the file are read as a string. So that is why it is matching against the entire file.
The command that you want to use is file, this reads the file into an array of each line.
I would
Use file to read the file into an array.
Then array_flip the array so that it's values are now the keys
Which allows me to isset($array[$key])
You can do this.
<?php
#$search = $_GET["variable"];
$search = '123156488';
$file_txt = "content.txt";
$file = file($file_txt);//convert the txt in array
foreach ($file as $key => $value) {
if (trim($search) == trim($value)) {
print "DO something! " . $value;
}
}?>
Regards.
Nelson.
Go to UPDATE to read what's the actual problem now. Old question was already resolved with the first answer submitted by Bert Peters.
OLD QUESTION:
I have few files named as file.1.txt, file.2.txt, file.3.txt, ... I'm reading first file with SplFileObject and using foreach loop to iterate through its content:
$file = new SplFileObject("file.1.txt");
foreach ($file as $row) {
// ...
}
Other files may be or may not be read, depending on the contents of the first file I'm reading. In all cases there should be only one file of others (file.2.txt or file.3.txt) which may be used in the next step. So somewhere inside foreach loop there is if statement which handles this.
All files have the same structure, so there comes the problem. I wouldn't like to create new foreach for reading next file - as I wrote it may not be needed at all, so I would like to use existing foreach instead of writing new one. Is there any possibility to overwrite $file variable with the contents of other file and iterate over it with using only one foreach or any other loop? For example:
foreach ($file as $row) {
// ...
if ($contentContainsSomething) {
$file = new SplFileObject("file.2.txt");
// somehow reset foreach to read file.2.txt from start
}
}
I wouldn't like to use goto statement to solve this problem. The recursion seems to be appropriate solution, but if there's a way to change object in loop on the fly, I would prefer this solution.
UPDATE:
As mentioned in "old question" all used files (file.1.txt, file.2.txt, ...) have the same structure, so that's why I wouldn't like to write more same loops and copy code. Instead I used code from #Danack (suggested by him on SO chat) which is already a part of solution. Here's the basic code for reading more files without any upgrade I need:
$path = "file.1.txt";
$whileCounter = 0;
while ($path != null) {
$file = new SplFileObject($path);
$file->setFlags(SplFileObject::READ_CSV);
$file->setCsvControl("\t");
$path = null;
foreach ($file as $rowKey => $row) {
// echo row }
$path = "file.2.txt";
if ($whileCounter > 0) {
break; // solution to stop loop, just for now
}
$whileCounter++;
}
So this code is working without any problem and outputs the file's lines as expected. The problem is when I would like to read next line of file with seek() method, because I would like to make decision on some information which is appended to each next line. So if I use seek($rowKey + 1) which helps me to get next line data (I use $file->current() when line is changed) and after that I call seek($rowKey) to get to previous line, then next file will output first line twice and second line will be missed. The third line and all after then are printed well. This is the problem achieved with the code below:
$path = "file.1.txt";
$whileCounter = 0;
while ($path != null) {
$file = new SplFileObject($path);
$file->setFlags(SplFileObject::READ_CSV);
$file->setCsvControl("\t");
$path = null;
foreach ($file as $rowKey => $row) {
if ($whileCounter > 0) {
var_dump($row);
echo "<br>";
}
$file->seek($rowKey + 1);
if ($file->valid()) {
$file->seek($rowKey);
} else {
var_dump($row);
echo "<br>";
$path = "file.2.txt";
}
}
$whileCounter++;
}
If you apply custom .csv files (with at least five non-empty lines) instead of file.1.txt and file.2.txt, you will see that second and third output are the same (second and third output are first and "second" lines of file.2.txt). What could be wrong here?
There is not. Foreach uses an iterator over your $file variable, and that iterator continues to be valid even though you changed the value of $file.
Or, to put this in another way, foreach will continue to look at the previous contents of $file, regardless of what you do with it afterwards. This is because $file is not actually the SplFileObject, but rather a reference to it, and the reference is used by foreach.
I would like an advice on best approach on this task.
I have a text log file holding data from a gps, this is the format:
time,lat,lon,elevation,accuracy,bearing,speed
2014-07-08T12:56:52Z,56.187344,10.192660,116.400024,5.000000,285.000000,1.063350
2014-07-08T12:56:58Z,56.187299,10.192754,113.799988,5.000000,161.000000,3.753000
2014-07-08T12:57:07Z,56.186922,10.193048,129.200012,5.000000,159.000000,5.254200
2014-07-08T12:57:13Z,56.186694,10.193133,109.799988,5.000000,152.000000,3.878100
2014-07-08T12:57:16Z,56.186745,10.193304,142.900024,5.000000,149.000000,3.940650
2014-07-08T12:57:20Z,56.186448,10.193417,118.700012,5.000000,154.000000,2.376900
2014-07-08T12:57:27Z,56.186492,10.193820,131.299988,5.000000,65.000000,5.379300
I need to find the line where the speed exceeds a certain value, then get the time from that line, then scroll trough the lines and find the line where the speed is below this value, get the time and write these 2 time values into my database.
This has to be an automated task, so I assume that a cron PHP script could do the job.
Best regards Thomas
Despite the fact that there is no special advice needed but wanting someone to code your problem - I will try to put you in the right direction. I've written easy to understand code where you can build on (untested)...
<?php
// Setup.
$pathGpsFile = 'gps.log';
$speedThreshold = 5;
//
// Execution.
//
if(!file_exists($pathGpsFile)) {
die('File "'. $pathGpsFile .'" does not exist.');
}
// Read entries into array.
$gpsEntries = file($pathGpsFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
// Loop through entries.
$lineCount = 0;
$currentDifferences = array();
$currentDifference = array();
foreach($gpsEntries as $gpsEntry) {
// Skip head.
if($lineCount == 0) {
$lineCount++;
continue;
}
// Extract values from gps entry.
list($time, $lat, $lon, $elevation, $accuracy, $bearing, $speed) = explode(',', $gpsEntry);
// Check if there is currently a difference monitored.
if(count($currentDifference) == 1) {
if($speed < $speedThreshold) {
$currentDifference[] = $gpsEntry;
}
// Add to differences list.
$currentDifferences[] = $currentDifference;
// Reset current difference.
$currentDifference = array();
} else {
if($speed > $speedThreshold) {
$currentDifference[] = $gpsEntry;
}
}
// Increase line count.
$lineCount++;
}
// Check output.
var_dump($currentDifferences);
?>
I have a script im writing. Here is whats happening. There is a while loop. In the while loop is a variable which is constant to X. How do i make X change from line one, line two, etc for each cycle of the while loop and pull X from a .txt file. Everything is in root. Thanks
$f = fopen("some.txt", "r");
while (!feof($f) && $some_condition) {
$x = fgets($f);
// do something
}
fclose($f);
Would this be sufficient?
Here is the pseudo code captain Kirk:
//we assume current working directory is root
fileHandle = openFile("Read","some.txt");
X = pull("X",fileHandle);
while( X is constant )
{
XFactor = factor(X);
}
I can refine and improve this with more details about what universe you are from, the programming language you intend to use, and more specifics about what you want to happen.
//get the lines of the file into an array
$file_array = file($file_name);
//go through the array line by line
foreach ($file_array as $line_number => $line)
{
//you didn't tell us what you are doing with each line
//so you will need to change this to your liking
$X = $line; // Handle the line
}
Edit: Note for very large files this may not be a good approach because this will load the entire file into memory at one time.