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
警告:重命名(seeker / SeekerPhoto / katr.jpg,seeker / SeekerPhoto / ussl.jpg)[function.rename]:第100行/subdomains/www/html/ussl/job/insphoto.php中没有此类文件或目录
How can I avoid this warning message. That means whatever the warning was, it will go for the next task.
如何避免此警告消息。这意味着无论警告是什么,它都将用于下一个任务。
6 个解决方案
#1
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".
编辑:我没想到这个答案与其他答案相比有很大的提升。请注意评论。很难/几乎不可能提前测试可能导致警告信息的所有条件。在文件系统上执行您想要的测试,当您执行实际操作时它可能会失败。测试表字段,权限或你想要的东西,仍然你的SQL查询可能会失败(例如2006年 - MySQL服务器已经消失,可能随时发生)。等等。不过,您可以测试更可能原因的参数,让脚本“优雅地”处理这些错误。
#2
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:
或者,如果要禁止多个语句的警告,可以减少error_reporting值:
$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.
请注意,警告是有原因的。最好的方法是查看操作生成警告的原因,并注意您的代码可以处理这些情况。您应该只忽略警告作为最后的手段。
#3
Two things used together should best serve you:
一起使用的两件事最适合您:
error_reporting()
ini_set( 'display_errors', (boolean)showInBrowser )
ini_set('display_errors',(boolean)showInBrowser)
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.
使用error_reporting()为警告消息设置适当的详细级别。请注意,仅设置记录哪些警告,通知和/或错误,而不是是否显示。
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.
在你的情况下可能是“error_reporting(E_ERROR | E_USER_ERROR);”如果它实际上是一个错误,它只会记录一些东西,而不仅仅是一个通知或一个没有真正破坏任何东西的警告。
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:
然后在开发服务器上,您可以在.htaccess或VirtualHost指令中使用以下行:
SetEnv PHP_DEBUG=1
No need to set it at all in production since not set ≠ 1.
由于未设置≠1,因此无需在生产中进行设置。
On a side note, I personally prefer to have my error_reporting do set to:
另外,我个人更喜欢将我的error_reporting设置为:
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:
由于Arif没有要求确保操作成功,只是为了得不到消息。我将其解释为“不关心操作是否有效”。当然,更好的方法是对你的函数库进行如下操作:
/**
* @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;
}
#4
If you mean that you just want to suppress the warning, you can use the @ operator
如果您只想抑制警告,则可以使用@运算符
$file = @operation();
#5
#1
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".
编辑:我没想到这个答案与其他答案相比有很大的提升。请注意评论。很难/几乎不可能提前测试可能导致警告信息的所有条件。在文件系统上执行您想要的测试,当您执行实际操作时它可能会失败。测试表字段,权限或你想要的东西,仍然你的SQL查询可能会失败(例如2006年 - MySQL服务器已经消失,可能随时发生)。等等。不过,您可以测试更可能原因的参数,让脚本“优雅地”处理这些错误。
#2
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:
或者,如果要禁止多个语句的警告,可以减少error_reporting值:
$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.
请注意,警告是有原因的。最好的方法是查看操作生成警告的原因,并注意您的代码可以处理这些情况。您应该只忽略警告作为最后的手段。
#3
Two things used together should best serve you:
一起使用的两件事最适合您:
error_reporting()
ini_set( 'display_errors', (boolean)showInBrowser )
ini_set('display_errors',(boolean)showInBrowser)
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.
使用error_reporting()为警告消息设置适当的详细级别。请注意,仅设置记录哪些警告,通知和/或错误,而不是是否显示。
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.
在你的情况下可能是“error_reporting(E_ERROR | E_USER_ERROR);”如果它实际上是一个错误,它只会记录一些东西,而不仅仅是一个通知或一个没有真正破坏任何东西的警告。
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:
然后在开发服务器上,您可以在.htaccess或VirtualHost指令中使用以下行:
SetEnv PHP_DEBUG=1
No need to set it at all in production since not set ≠ 1.
由于未设置≠1,因此无需在生产中进行设置。
On a side note, I personally prefer to have my error_reporting do set to:
另外,我个人更喜欢将我的error_reporting设置为:
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:
由于Arif没有要求确保操作成功,只是为了得不到消息。我将其解释为“不关心操作是否有效”。当然,更好的方法是对你的函数库进行如下操作:
/**
* @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;
}
#4
If you mean that you just want to suppress the warning, you can use the @ operator
如果您只想抑制警告,则可以使用@运算符
$file = @operation();
#5
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方法的PHP手册以及附录你需要在php文件的顶部添加它:
ini_set('display_errors','1');