So I have a PHP program that a line from a text file. Then it uses that line of text it read to point to another text file
$posts = "posts/posts.txt";
$postsLines = file($posts);
$fetchingPost = TRUE;
$postNumber = 0;
$postPointer;
$postPointerString;
$postLines;
$postTag;
$postTitle;
$postContent;
$endCondition = "end";
while ($fetchingPost == TRUE) {
$endOfFile = strcmp($postsLines[$postNumber], $endCondition);
if ($endOfFile == 0) {
$fetchingPost = FALSE;
}
if ($endOfFile <> 0) {
$postPointer[$postNumber] = $postsLines[$postNumber];
$postLines = file($postPointer[$postNumber]);
$postNumber = $postNumber + 1;
}
}
And I get this errors when I run it, I am using the WAMP server
Warning: file(posts/leapMotionSandbox.txt ): failed to open stream: Invalid argument in C:\wamp\www\noahhuppert\Paralax v2\index.php on line 45
Warning: file(posts/topDownShooter.txt ): failed to open stream: Invalid argument in C:\wamp\www\noahhuppert\Paralax v2\index.php on line 45
Please help
The elements of the array returned by file() have a newline at the end of each line. This is not a valid filename character on Windows (it's valid on Unix, although it would be perverse to include newlines in a filename).
From the documentation:
Each line in the resulting array will include the line ending, unless FILE_IGNORE_NEW_LINES is used, so you still need to use rtrim() if you do not want the line ending present.
Your loop can also be simplified greatly. There's no need for the $fetchingPost or $endOfFile variables, just test for the end in the while() condition.
while (($line = rtrim($postsLines[$postNumber]) != $endCondition) {
$postPointer[$postNumber] = $line;
$postLines = file($line);
$postNumber++;
}
Alternatively, you can do:
$postsLines = file($posts, FILE_IGNORE_NEW_LINES);
Related
Using PHP 7.3, I'm trying to achieve "tail -f" functionality: open a file, waiting for some other process to write to it, then read those new lines.
Unfortunately, it seems that fgets() caches the EOF condition. Even when there's new data available (filemtime changes), fgets() returns a blank line.
The important part: I cannot simply close, reopen, then seek, because the file size is tens of gigs in size, well above the 32 bit limit. The file must stay open in order to be able to read new data from the correct position.
I've attached some code to demonstrate the problem. If you append data to the input file, filemtime() detects the change, but fgets() reads nothing new.
fread() does seem to work, picking up the new data but I'd rather not have to come up with a roll-your-own "read a line" solution.
Does anyone know how I might be able to poke fgets() into realising that it's not the EOF?
$fn = $argv[1];
$fp = fopen($fn, "r");
fseek($fp, -1000, SEEK_END);
$filemtime = 0;
while (1) {
if (feof($fp)) {
echo "got EOF\n";
sleep(1);
clearstatcache();
$tmp = filemtime($fn);
if ($tmp != $filemtime) {
echo "time $filemtime -> $tmp\n";
$filemtime = $tmp;
}
}
$l = trim(fgets($fp, 8192));
echo "l=$l\n";
}
Update: I tried excluding the call to feof (thinking that may be where the state becomes cached) but the behaviour doesn't change; once fgets reaches the original file pointer position, any further fgets reads will return false, even if more data is subsequently appended.
Update 2: I ended up rolling my own function that will continue returning new data after the first EOF is reached (in fact, it has no concept of EOF, just data available / data not available). Code not heavily tested, so use at your own risk. Hope this helps someone else.
*** NOTE this code was updated 20th June 2021 to fix an off-by-one error. The comment "includes line separator" was incorrect up to this point.
define('FGETS_TAIL_CHUNK_SIZE', 4096);
define('FGETS_TAIL_SANITY', 65536);
define('FGETS_TAIL_LINE_SEPARATOR', 10);
function fgets_tail($fp) {
// Get complete line from open file which may have additional data written to it.
// Returns string (including line separator) or FALSE if there is no line available (buffer does not have complete line, or is empty because of EOF)
global $fgets_tail_buf;
if (!isset($fgets_tail_buf)) $fgets_tail_buf = "";
if (strlen($fgets_tail_buf) < FGETS_TAIL_CHUNK_SIZE) { // buffer not full, attempt to append data to it
$t = fread($fp, FGETS_TAIL_CHUNK_SIZE);
if ($t != false) $fgets_tail_buf .= $t;
}
$ptr = strpos($fgets_tail_buf, chr(FGETS_TAIL_LINE_SEPARATOR));
if ($ptr !== false) {
$rv = substr($fgets_tail_buf, 0, $ptr + 1); // includes line separator
$fgets_tail_buf = substr($fgets_tail_buf, $ptr + 1); // may reduce buffer to empty
return($rv);
} else {
if (strlen($fgets_tail_buf) < FGETS_TAIL_SANITY) { // line separator not found, try to append some more data
$t = fread($fp, FGETS_TAIL_CHUNK_SIZE);
if ($t != false) $fgets_tail_buf .= $t;
}
}
return(false);
}
The author found the solution himself how to create PHP tail viewer for gians log files 4+ Gb in size.
To mark this question as replied, I summary the solution:
define('FGETS_TAIL_CHUNK_SIZE', 4096);
define('FGETS_TAIL_SANITY', 65536);
define('FGETS_TAIL_LINE_SEPARATOR', 10);
function fgets_tail($fp) {
// Get complete line from open file which may have additional data written to it.
// Returns string (including line separator) or FALSE if there is no line available (buffer does not have complete line, or is empty because of EOF)
global $fgets_tail_buf;
if (!isset($fgets_tail_buf)) $fgets_tail_buf = "";
if (strlen($fgets_tail_buf) < FGETS_TAIL_CHUNK_SIZE) { // buffer not full, attempt to append data to it
$t = fread($fp, FGETS_TAIL_CHUNK_SIZE);
if ($t != false) $fgets_tail_buf .= $t;
}
$ptr = strpos($fgets_tail_buf, chr(FGETS_TAIL_LINE_SEPARATOR));
if ($ptr !== false) {
$rv = substr($fgets_tail_buf, 0, $ptr + 1); // includes line separator
$fgets_tail_buf = substr($fgets_tail_buf, $ptr + 1); // may reduce buffer to empty
return($rv);
} else {
if (strlen($fgets_tail_buf) < FGETS_TAIL_SANITY) { // line separator not found, try to append some more data
$t = fread($fp, FGETS_TAIL_CHUNK_SIZE);
if ($t != false) $fgets_tail_buf .= $t;
}
}
return(false);
}
while (($line = fgets($handle)) !== false) {
//look for the first payor block
if(strpos($line, 'N1*PR*') !== false || $block_start) {
$header_end = true; $block_start = true;
//see if the block finished
if(strpos($line, 'CAS*CO*45*20.43**253*1.27~') !== false) {
$block_start = false;
$payor_blocks[$count] .= $line;
$count++;
}
$payor_blocks[$count] .= $line;
} else {
//append to the header
if($header_end) {
$footer .= $line."\n";
} else {
$header .= $line."\n";
}
}
}
//get payor blocks and create a file foreach payor
$new_files = array();
foreach($payor_blocks as $block) {
$filename = $file . "_" . $count;
$count++;
$new_files[] = array(
'name' => $filename,
'content' => $header."\n".$block."\n".$footer
);
//loop through new files and create them
foreach($new_files as $new_file) {
$myfile = fopen($file, "x");
fwrite($myfile, $new_file['content']);
//close the file
fclose($myfile);
I have the code above, it's suppose to be able to open an original file called "$file" and create a new file then close it, However its not creating and when I run it, i get this warning error:
Warning: fopen(362931550.1a): failed to open stream:
File exists in /script2.php on line 90 Warning:
fwrite() expects parameter 1 to be resource,
boolean given in /script2.php on line 94 Warning:
fclose() expects parameter 1 to be resource, boolean
given in /script2.php on line 96
Any help is kindly appreciated.
I have one file named: 362931550.1a
I did a code that splits them at certain areas, (its pretty long to post), when i run the script I see it on my browser but it doesn't create 2 new files in the folder.
Your file open mode is incorrect.
From php.net documentation:
'x' Create and open for writing only; place the file pointer at the beginning of the file. If the file already exists, the fopen() call will fail by returning FALSE and generating an error of level E_WARNING [...]
You should probably use 'w' mode:
'w' Open for writing only; place the file pointer at the beginning of the file and truncate the file to zero length. If the file does not exist, attempt to create it.
The script failed to open a stream with the fopen() function and return a boolean. The function fwrite() become the boolean value but need a resource.
The reason is that you only create files with the x-modifier in the stream.
Create and open for writing only; place the file pointer at the beginning of the file. If the file already exists, the fopen() call will fail by returning FALSE and generating an error of level E_WARNING. If the file does not exist, attempt to create it.
You see in the PHP manual more informations about the stream-modes (PHP manual).
To prevent this message check if the value isn't false.
$stream = fopen("file.txt", "x");
if($stream === false) {
echo "Error while open stream";
}
//here your code
I'm working on a script that edits PHP files contents. So far, i'm able to check if the line is empty on the file and then write what I need into it. However I need to find a way to loop through the array until it finds the next empty line if the first query was not empty.
For example, I want to edit this PHP file - example.php - which contains the following:
<?php
I am not an empty line.
I am not an empty line.
I am not an empty line.
?>
My script:
// File variables
$file = 'path/example.php';
$content = '';
// Check if the file exists and is readable
if (file_exists($file) && is_readable($file)) {
$content = file_get_contents($file);
}
// put lines into an array
$lines = explode("\n", $content);
//Get the fourth line
$Getline = $lines[3];
// check if the line is emptpy
if (empty($Getline) && $Getline !== '0') {
// Write something in the file
}
else {
// Find the next empty line
}
So all I need is to loop through the array until it finds the next empty line. Although I'm not sure how do that.
Use PHP file() function instead of file_get_contents() function. It will read the file in array format itself.
Then you can parse this array using foreach() and can check blank value in it.
May this will help you.
<?php
foreach($lines as $line)
{
// check if the line is empty
if (empty($line) || $line == '')
{
//Line = empty and do stuff here.
}
}
?>
after i have installed windows 8 on my desktop and reinstalled aptana and xampp, i somehow can't use !feof($handle). i want to get the symbols of nasdaq stored in my $symb arra.here is an example and my error:
$symb = array();
$url = "http://www.nasdaq.com/screening/companies-by-name.aspx?letter=0&exchange=nasdaq&render=download";
$handle = fopen("$url","r");
while( !feof($handle) ){
$line = fgetcsv($handle, 1024);
if($line!="Symbol" && isset($line[0]) && $line[0] != null ){
$symb[] = trim($line[0]);
}
fclose($handle);
}
And my Errors :
Warning: feof(): 3 is not a valid stream resource in C:\xampp\htdocs\demos\screener\candleScreener.php on line 61
Warning: fgetcsv(): 3 is not a valid stream resource in C:\xampp\htdocs\demos\screener\candleScreener.php on line 62
Warning: fclose(): 3 is not a valid stream resource in C:\xampp\htdocs\demos\screener\candleScreener.php on line 66
.......
Is there a setting i have to change on the php.ini file or what could it be ?
thanks.
.....
$url = "http://www.nasdaq.com/screening/companies-by-name.aspx?letter=0&exchange=nasdaq&render=download";
$handle = fopen("$url","r");
$txt = fread( $handle, 8 );
print_r($txt);
.....
prints out :
"Symbol"
so my fopen() is fine ....
The reinstallation and the fopen() are red herrings. You're closing the file handle inside the while loop, before the file has been read.
while( !feof($handle) ){
$line = fgetcsv($handle, 1024);
if($line!="Symbol" && isset($line[0]) && $line[0] != null ){
$symb[] = trim($line[0]);
}
// fclose($handle); // Move this outside the while loop
}
fclose($handle); // Moved this outside the while loop
I had the same problem in my code. I had an extra file close function in the code. In other words I was trying to write to the file for a second time and it was not open for use. I had this coded in the top of my program:
$newFile = $local_directory . $tenant.'-'.$namespace.'_Stats.xml';
$newDoc = fopen($newFile, "w");
fwrite($newDoc, $urlStats);
fwrite($newDoc, $response);
fclose($newDoc);
Then later I had:
fwrite($newDoc, $response);
fclose($newDoc);
Check to make sure the file is open before you write more content.
Hi, I have this file test1.php and in the other file test.php I have this
php code running:
<?php
$file = "http://inviatapenet.gethost.ro/sop/test1.php";
$line = '0';
if($f = fopen($file, 'r')){
$line = fgets($f); // read until first newline
fclose($f);
}
echo $line;
?>
The idea is to get just the second line of the web page test1.php.
Second Line
I've tried to change the $line = '2'; but no affect, it just displays the first line.
I need Help.
You can use file which reads a file into an array, you can then grab whichever line you want by using the index you want.
For example:
data.txt:
line one
line two
line three
line four
PHP code:
$file = file('data.txt');
echo $file[1]; // echo line number 2, remember arrays start at 0!
Updated PHP code for new versions (5.4):
echo file('data.txt')[1];
This should work. Obviously, change only the value of $linetofetch:
<?php
// Write here the number of the line you want to fetch.
$linetofetch = 2;
$file = "http://inviatapenet.gethost.ro/sop/test1.php";
$currentline = 1;
if($f = fopen($file, 'r')){
while ($currentline <= $linetofetch) {
$line = fgets($f); // read until first newline
$currentline++;
}
fclose($f);
}
echo $line;
?>