How can i test if a file write has succeeded in PHP? - php

Is there any way to test if writing to a file was successfully accomplished? I need a method to obtain the end of time of a writing operation. If so to trigger a callback function.

fwrite() returns the number of bytes written, or FALSE on error.
Check whether fwrite() returns false and you'll know that the write succeeded. Be careful to use the === comparison operator instead of the == operator when checking if the returned value is false.
You can use filemtime() to get the last modification time of a file.

Related

PHP: How to check if file is complete

I would like to generate a csv using PHP but I want to download the file later using file_get_contents when it is complete. Is there a way to check if a file is already complete?
It's ok, but the way you are doing it is wrong (at least "not correct at all").
fgets() returns false, if the end of the file is reached, thus you should test against false instead. It works for you, because you use the "simple" equality operator (==), that will case null to false, when comparing against a boolean.
Returns a string of up to length - 1 bytes read from the file pointed to by handle. If there is no more data to read in the file pointer, then FALSE is returned.
If an error occurs, FALSE is returned.
This means, it have to look like:
while (($c = fgets($f)) !== false) {
doSomethingWith($c);
}

Need help understanding a sample PHP while

everyone. I saw a PHP while loop example today that I don't quite understand.
Example (Complete code)
// Open XML file
$fp=fopen("note.xml","r");
// Read data
while ($data=fread($fp,4096)) { // Line about which I have questions
xml_parse($parser,$data,feof($fp)) or
die (sprintf("XML Error: %s at line %d",
xml_error_string(xml_get_error_code($parser)),
xml_get_current_line_number($parser)));
}
The expression $data=fread($fp,4096) inside the while loop parentheses doesn't seem to change at all. It is just ONE assignment statement. How does this loop end?
The function xml_parse($parser,$data,feof($fp)) may end when parsing is complete, but I don't see how it will affect the test condition for the while loop. I feel the parsing of the XML file would repeat indefinitely.
Also when there is assignment expression as a test condition for a loop, are we really just looking to see if the RIGHT side of the assignment yields TRUE or FALSE to determine whether to end the loop? I have doubt about this though because then it would produce an infinite loop for this example since $data, once assigned, will always return TRUE.
Thanks
It ends when the fread() function returns false, which does when it reaches the end of the file. You can confirm this in the PHP documentation for fread:
http://php.net/fread
As for your question about the evaluation of the assignment, in PHP when you evaluate an assignment it will return the final value of the variable (different to Javascript for instance, in which the assignment is indeed what becomes evaluated), so you're basically both assigning a value to a variable from a function and evaluating the result of that function (assigned to the variable) without any extra syntax.
Work
while(there is data to read) OR (!EOF)
break when reach (EOF==true) OR no data to read OR return false
* EOF (end of file)
As php manual says, the function fread returns the read string or FALSE on failure.
That means:
$data=fread($fp,4096)
In the above statement the value of $data is either the contents of your file note.xml or false.
As you may know, while loop will continue until the condition is false. This statement is false only when fread($fp,4096) function fails to read data from the file, when there is no data left to read.

Session Handler Write Operation Return Value

With PHP's SessionHandler there is SessionHandler::write() which returns a value. The manual is somewhat vague about it:
Return Values
The return value (usually TRUE on success, FALSE on failure). Note this value is returned internally to PHP for processing.
(same for the interface)
I wonder what the meaning of that processing by PHP is.
I already was that clever and looked into session_set_save_handler but there the return value for the write() callback isn't even mentioned.
Well, "returned internally to PHP" in this context means: It is not passed back to your code (as the return type for session_write_close() is void.)
In other words, what PHP does with it should be treated as unknown (unless you look at the actual C source of PHP); thus I would simply follow the advice of returning true on success, and false if your custom session handler was somehow unable to write the session data.
If I should guess, I would say that maybe PHP generates a warning message, or maybe that ist just intended for use in a later version of PHP.
A way to find out would be to simply override SessionHandler::write() to always return false and see what happens. Check the console for any warnings.

PHP if() evaluation problem needs a rewrite

I noticed this weird evaluation yesterday after searching for a few hours in my code for an error. i am passing scores into php, sometimes the score=0 which causes an issue.
send php ?blah=blah&score=0
if(!empty($_REQUEST['score']){
//do database update stuff
}else{
// show entire webpage
}
It works great unless the score=0 the if() will evaluate to false and return the entire webpage to my ajax handler and error. I have temporarily changed !empty to isset but this will cause problems in the future because isset evaluates to true even if the score key is in the url string without a value.
ex: (?blah=blah&score=&something=else)
my question is: what is the best way to recode this to work correctly now and in the future?
edit: there are a few working answers here, i appreciate everyones time. it was difficult to choose an answer
As the manual says, a variable is considered empty() if it has an empty or zero value.
So it will treat your variable wrongly as empty even though 0 is a perfectly acceptable value in your case.
If you need score to be a number, you could use isset() in combination with a is_numeric() check instead:
if((isset($_REQUEST['score']) and (is_numeric($_REQUEST['score'])){
Check out the manual page to see the kinds of values is_numeric() accepts. If score is always an integer, you can also use is_int((int)$_REQUEST['score']) but that will convert invalid input values to 0.
Additionally, as #sightofnick says, it's better to use explicit $_GET or $_POST instead of $_REQUEST.
Re your update:
In that case I would
Do check whether the variable is "0" (string "zero")
If it is "0", make it 0 (integer "zero")
If it is not 0, convert it to an integer (int)$_REQUEST["score"])
If the conversion resulted in 0, it was invalid input - exit
You have a valid integer variable.
empty() will return false if a value is zero. Use isset() or array_key_exists() instead, if you want to check if a variable in an array is set:
if (array_key_exists('score', $_REQUEST)) {...}
Try doing
if (isset($_REQUEST['score']) && ($_REQUEST['score'] !== '')) {
...
}
The isset will handle the presence/absence of the query parameter, and the strict string (!==) comparison will handle the case where the 'score' query is present but has no value. PHP treats all data coming from _GET/_POST/_REQUEST as strings, so this test is 100% reliable.
if(isset($_REQUEST['score']) && $_REQUEST['score'] != ''){
//do database update stuff
}else{
// show entire webpage
}
You may be able to solve that with
if (isset($_REQUEST['score']) && is_numeric($_REQUEST['score'])) {}
That of course if scrore can only contain numeric value

How to check if a PHP stream resource is readable or writable?

In PHP, how do I check if a stream resource (or file pointer, handle, or whatever you want to call them) is either readable or writable? For example, if you're faced with a situation where you know nothing about how the resource was opened or created, how do you check if it's readable? And how do you check if it's writable?
Based on the testing that I've done (just with regular text files using PHP 5.3.3), fread() does not throw any errors at any level when the resource is not readable. It just returns an empty string, but it also does that for an empty file. And ideally, it would be better to have a check that doesn't modify the resource itself. Testing if a resource is readable by trying to read from it will change the position of the pointer.
Conversely, fwrite() does not throw any errors at any level when the resource is not writable. It just returns zero. This is slightly more useful, because if you were trying to write a certain number of bytes to a file and fwrite() returns zero, you know something went wrong. But still, this is not an ideal method, because it would be much better to know if it's writable before I need to write to it rather than trying to write to it and see if it fails.
Also, ideally, the check should work on any sort of stream resource, not just files.
Is this possible? Does anything like this exist? I have been unable to find anything useful. Thanks in advance for your answers.
Quite simple. Just call stream_get_meta_data($resource) from your script, then check the mode array element of the return value:
$f = fopen($file, 'r');
$meta = stream_get_meta_data($f);
var_dump($meta['mode']); // r
And if you want to know if the underlying data is writable:
var_dump(is_writable($meta['uri'])); // true if the file/uri is writable
Okay, so this may not be the best solution, but I think it suffices, given that there's nothing in PHP to do this automagically.
For the first step, you'll get the inode of the resource from the file, and then read the filename:
$stat = fstat($fp);
$inode = $stat['ino'];
system("find -inum $inode", $result);
Taken directly from this question about finding the filename from a filehandle.
Now that you have the filename (in $result) you can do a fileperms($result) on it to get the permissions out.
Note that fileperms() returns an int, and the documentation does the magic (actually just treating the int as an octal) of retaining that leading 0 (e.g. 0755).
Also note that the documentation does the magic of converting that int into a nice string like -rw-r--r--

Categories