I know it's not a good practice to hide the warnings using #copy, but what other alternatives are there?
Is there any way you can make sure copy would work or not ?
Use is_readable() and is_writable() to check the status of the source and target before attempting the copy().
Really, you should not be displaying errors to the browser. Turn off display_errors in php.ini.
Then you can test if it succeeded by its boolean return value, without needing to worry about the warnings on screen.
if (!copy('srcfile', 'destfile')) {
// something failed.
}
If you use '#' before a function you'll not the warning or the notice returned but you'll keep the result (boolean, string...).
Try this :
if (!#copy('srcfile', 'destfile')) {
// something failed.
}
Related
I'm getting the following warning when using PHPass (http://www.openwall.com/phpass/):
open_basedir restriction in effect. File(/dev/urandom) is not within the allowed path(s)
Although this is not a big problem (it will fall back on something else), I'd like not to have this warning. The PHP application should run on different servers, some users will be able to add that path to their allowed open_basedir paths, but others won't have access to that configuration.
My first guess was to check readability with is_readable(), however, I'm still getting the warning.
The question: How do I check if a certain path or file has been added to the open_basedir paths?
You can read the value of PHP directives with the ini_get() function:
ini_get('open_basedir')
If the directive's not empty, it should contain a string with one ore more paths separated by PATH_SEPARATOR.
You can use is_readable and disable the warning for this function with a #.
If is_readable returns false then you know that it's not readable.
$readable = #is_readable(..);
if(!$readable) {
....not readable
}
file_exists emits a warning if directory is restricted. Let's use it:
function isRestricted($path)
{
// Default error handler is required
set_error_handler(null);
// Clean last error info. You can do it using error_clean_last in PHP 7.
#trigger_error('__clean_error_info');
// Testing...
#file_exists($path);
// Restore previous error handler
restore_error_handler();
// Return `true` if error has occured
return ($error = error_get_last()) && $error['message'] !== '__clean_error_info';
}
I was wondering when does file_exists() return an E_WARNING???
in the manual it says
Upon failure, an E_WARNING is emitted.
Can you tell me a simple example of this, cause i couldn't come up with anything?
UPDATE:
so, if i try to check a file that doesn't exist like:
if (false === file_exists('path/image.png')) {
//something
}
This will only return false, and NOT an E-Warning, right???
I'm srry if this is a stupid question (i'm still a total noob in php :-))
Thx
For example when the safe mode restrictions prevent the script from accessing the filesystem, or the file system is not reachable for another reason or an I/O or permission error occurs.
And I think, thats about it.
I made a function like this (no need to write the whole function here) :
public function selectNode($from, $attributes = null, $childs = null)
and, of course, if I call it this way :
$node->selectNode();
The argument $from isn't initialized and then you got a warning error.
I know you can suppress the error doing #$node->selectNode(); or something like that thanks to #.
But, I want to handle it myself. How can I do that if that's possible?
The only way I found is to initialize it like this public function selectNode($from = null, $attributes = null, $childs = null) but that doesn't make it clear ($from is not an option as the others).
(And, of course, this function, here, is just an example. It could be extended to other functions)
How come you can miss a required parameter? It is not a file or an outside variable! You will get this error just by trying to call this script. It is like parse error. What to handle here?
It's development phase error. It just needs to be corrected, not handled.
Anyway, you are doing it wrong.
Never add intentional errors to your code.
Language's error reporting mechanism is for handling unexpected errors, not intentional ones.
If you expect an error here - handle it yourself. Don't make PHP to raise error
So, make it $from = null,, yes. And then handle this null whatever you want.
Surely if the $from parameter is not required you should assign it a default variable so it's optional and then do checking based on this.
It would probably be most elegant to just check if $from isset in the code before you reference it and supply it with null as default in the parameters, isset will return false from a null value.
I guess you've got display_errors set to on in php.ini and now these warnings are popping up on your screen and you don't want to see them popping up anymore? If that's the case, then change your php.ini :
display_errors = Off
log_errors = On
error_log = /path/to/php-error.log
Errors will then be logged to the file you specified in error_log, and won't show up on your screen anymore.
You could use a try-catch block handling the error yourself.
try {
$node->selectNode();
}
catch (Exception $e){
echo $e; // do whatever you like here with error info $e, if you leave the parenthesis empty here nothing is done and the error message is suppressed
}
Are you looking for the following (or one of its variants)?
<?php error_reporting(0); ?>
I'm trying to make errors hidden but it seems I'm doing something wrong.
In my hosting configuration display_errors is set to off and I don't have .htaccess file. I tried to write follownng script
<?php
echo ord(ini_get("display_errors")) . " ";
die("error");
?>
And I'm getting following output:
0 error
So, display_errors is set to off, but die() function still shows error on the screen. How to avoid this?
By doing die("error"), you're are commanding the code that it should output the string "error" and stop the code.
You are seeing the "error" message does not mean that there is an error, it is just another string.
die() is a function (commonly used to handle errors), but it is not deactivated when you set display errors off. It will still work and to whatever it is meant to do.
How to avoid this?
Do not use die() to handle errors.
use trigger_error() instead, which will follow the behavior you expected
There is a option to display error to stderr instead of stdout so you won't see them on you webpage, but only in the logs. (Manual)
I found error_log() function. Now I can use
function quit($error)
{
echo "Request failed";
error_log($error);
die();
}
If a call to unlink() returns false for the specified path, how do you find out what the reason for the failure was (i.e. EISDIR, ENOENT, ELOOP etc.)? PHP 5.x running on redhat linux.
here's one way
unlink("/path/that/does/not/exist");
print_r(error_get_last());
See Error handling for more details
I don't think it is possible to get back any error code(s) issued by the system. That is maybe down to the fact that PHP is supposed to be portable, and different OS's have different methods of reporting errors.
You could of course do a exec('rm ....') and get the error level back but that's not very portable, and makes your app depend on exec() rights.
Otherwise, if you really, really need this, only a very hacky workaround comes to mind: Create a custom error handler function that tries to fetch the reason for the failure from the warning unlink throws - e.g. check for "Permission denied", or just fetch the whole error message.
Create a wrapper function around unlink that sets and re-sets the error handler. Something like this:
function my_unlink($file)
{
set_error_handler("my_error_handler");
unlink($file);
restore_error_handler();
}
you get my drift.
If anybody knows a better solution - I'd be interested to hear about it, too....
This is not possible, i'm afraid. Here's the C code that handles unlink in php 5.3.
ret = VCWD_UNLINK(url); <-- calls unlink(2)
if (ret == -1) {
if (options & REPORT_ERRORS) {
php_error_docref1(NULL TSRMLS_CC, url, E_WARNING, "%s", strerror(errno));
}
return 0;
}
as you can see, errno is not returned and there's no way to access it later.
There's already a bugreport about this, but it doesn't seem to draw too much attention. ;)
See also this discussion