Reputation:
Recently I worked in project where I needed to a rename a picture. The problem is when I rename the picture it renamed but show a warning message like bellow
Warning: rename(seeker/SeekerPhoto/katr.jpg,seeker/SeekerPhoto/ussl.jpg) [function.rename]: No such file or directory in /subdomains/www/html/ussl/job/insphoto.php on line 100
How can I avoid this warning message. That means whatever the warning was, it will go for the next task.
Upvotes: 1
Views: 9080
Reputation: 96159
You can do some testing on the parameter before renaming the file.
if ( !file_exists($oldfile) || !is_readable($oldfile) ) {
// some error handling here
}
else {
$b = rename($oldfile, $newfile);
}
edit: I didn't expect this answer to be upvoted that much in comparison to the others. Please note the comments. It's very hard/virtually impossible to test all conditions that could cause a warning message here in advance. Do what ever testing you want on the filesystem, when you perform the actual action it may fail. Test table fields, permissions or what ever you want and still your sql query may fail (e.g. 2006-MySQL server has gone away, can happen at any time). And so on and on. Nevertheless you can test parameters for the more likely causes and let the script handle those errors "gracefully".
Upvotes: 11
Reputation: 41837
Two things used together should best serve you:
Use error_reporting()
to set an appropriate level of verbosity for the warning messages. note that only sets which warnings, notices and/or errors are logged, not whether they are displayed.
In your case probably "error_reporting( E_ERROR | E_USER_ERROR )
;" which will only log something if it's actually an error, not just a notice or a warning that doesn't really break anything.
All in all it is probably a good idea to do something like this:
if (getenv('PHP_DEBUG')=='1')
{
error_reporting( E_ERROR | E_USER_ERROR );
ini_set( 'display_errors', true );
}
else
{
error_reporting( E_ERROR | E_USER_ERROR );
ini_set( 'display_errors', false );
}
And then on the development server you could have the following line in your .htaccess or VirtualHost directive:
SetEnv PHP_DEBUG=1
No need to set it at all in production since not set ≠ 1.
On a side note, I personally prefer to have my error_reporting do set to:
error_reporting( E_ALL | E_STRICT );
which you could read in english as "warn on everything I could possibly have done wrong so to force me to do a better job" because I feel that if I can beat every notice and warning just by checking some stuff before using it, and initializing variables properly, the end result will probably be at least a little more secure.
edit: some clarification:
Since Arif didn't ask to make sure the operation succeeded, just to not get the message. Which I interpreted as "don't care if the operation worked". Ofcourse the better way of going about it would be something like the following to your function library:
/**
* @author: Kris
* @license: see http://sam.zoy.org/wtfpl/
*
* PLEASE NOTE THAT THE FOLLOWING CODE IS TESTED BY ME, NOT QUALITY ASSURANCE
*/
/**
* Move a file
*
* If uses filename from $source if $destination is a directory
*
* @param string $source
* @param string $destination
* @param bool $overwrite
* @return bool
*/
function my_move_file( $source, $destination, $overwrite = false )
{
return _internal_my_move_or_copy_file( $source, $destination, true, $overwrite );
}
/**
* Copy a file
*
* If uses filename from $source if $destination is a directory
*
* @param string $source
* @param string $destination
* @param bool $overwrite
* @return bool
*/
function my_copy_file( $source, $destination, $overwrite = false )
{
return _internal_my_move_or_copy_file( $source, $destination, false, $overwrite );
}
define( '__internal_my_move_or_copy_file_e_error', E_USER_ERROR ); // change to E_USER_NOTICE if not meant to be fatal
define( '__internal_my_move_or_copy_file_e_notice', E_USER_NOTICE );
/**
* Should not be called by userland code, use my_move_file or my_copy_file instead
*
* one function to implement both move and copy because almost all of the required validations is identical.
*
* @param string $source
* @param string $destination
* @param bool $is_move
* @param bool $overwrite
* @return bool
*/
function _internal_my_move_or_copy_file( $source, $destination, $is_move, $overwrite )
{
// what we'll be returning
$result = false;
// input sanity checks
if ( !is_string( $source ) || !is_callable( $source, '__toString' ) )
{
trigger_error(
"_internal_my_move_or_copy_file: expects \$source to be a string.",
__internal_my_move_or_copy_file_e_error );
return false;
}
elseif ( !is_string( $destination ) || !is_callable( $destination, '__toString' ) )
{
trigger_error(
"_internal_my_move_or_copy_file: expects \$destination to be a string.",
__internal_my_move_or_copy_file_e_error );
return false;
}
elseif ( ! is_bool( $is_move ) )
{
trigger_error(
"_internal_my_move_or_copy_file: expects \$is_move to be a bool.",
__internal_my_move_or_copy_file_e_error );
return false;
}
elseif ( ! is_bool( $overwrite ) )
{
trigger_error(
"_internal_my_move_or_copy_file: expects \$overwrite to be a bool.",
__internal_my_move_or_copy_file_e_error );
return false;
}
$action_word = $is_move ? 'move' : 'copy';
if ( file_exists( $source ) && is_readable( $source ) )
{
$to = preg_split( '/\//', $destination, -1, PREG_SPLIT_NO_EMPTY );
$destination = '/'.implode( '/', $to );
if ( is_dir( $destination ) )
{
// make sure we don't accidentally allow ../ etc
if ( in_array( '..', $to ) || in_array( '.', $to ) )
{
trigger_error( "my_{$action_word}_file: \$destination does not allow path traversion using /../ or /./", $e_error_code );
}
// make sure we have a filename on $destination
if ( is_dir( $destination ) )
{
// user gave a directory but no filename so use the filename in $source
$to[] = basename( $source );
$destination = '/'.implode( '/', $to );
}
}
if ( file_exists( $destination ) && is_writable( $destination ) )
{
if ( ! $overwrite )
{
trigger_error(
"my_{$action_word}_file: \$destination already exists and I am instructed not to overwrite.",
__internal_my_move_or_copy_file_e_notice );
return false;
}
}
elseif ( is_dir( dirname( $destination ) ) || is_writable( dirname( $destination ) ) )
{
// we can write
}
else // all allowable situations are already passed
{
trigger_error(
"my_{$action_word}_file: $destination directory does not exist or cannot be written to.",
__internal_my_move_or_copy_file_e_error );
}
if ( $is_move )
{
// if we are going to move a file the source also needs to be writable
if ( ! is_writable( $source ) )
{
trigger_error(
"my_{$action_word}_file: Cannot {$action_word} \$source because it cannot be written.",
__internal_my_move_or_copy_file_e_error );
}
$result = rename( $source, $destination );
}
else
{
$result = copy( $source, $destination );
}
// see if what php's built in function gave us is acceptible
if ( $result === false )
{
trigger_error(
"my_{$action_word}_file: unexpected failure to {$action_word} \$source to \$destination.",
__internal_my_move_or_copy_file_e_error );
}
// postflight check if the work we did was successful
if ( !file_exists( $destination ) )
{
trigger_error(
"my_{$action_word}_file: unexpected failure to {$action_word} \$destination does not exist after {$action_word} operation.",
__internal_my_move_or_copy_file_e_error );
}
}
else // file does not exists or is unreadable
{
trigger_error(
"my_{$action_word}_file: \$source \"$source\" does not exist or cannot be read.",
__internal_my_move_or_copy_file_e_error );
}
return $result;
}
Upvotes: 3
Reputation: 75714
You can use the @ operator, which suppresses error messages for single statements.
@rename($oldFileName, $newFileName);
Alternately, you could reduce the error_reporting
value if you want to suppress warnings for multiple statements:
$oldErrorReportingValue = error_reporting(0);
rename($oldFileName, $newFileName);
# do something else ....
error_reporting($oldErrorReportingValue);
Note that warnings are there for a reason. The best approach would be to look into why the operation generates a warning and take care that your code can handle these situations. You should only ignore warnings as a last resort.
Upvotes: 6
Reputation: 1647
You can look at the PHP manual for the ini_set method as well as the appendix You'll need to add this at the top of your php file:
ini_set('display_errors','1');
Upvotes: 0
Reputation: 45721
If you mean that you just want to suppress the warning, you can use the @ operator
$file = @operation();
Upvotes: 0