views:

1494

answers:

5

Recently i worked in project. there i need 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 mean whatever the warning was it will go for next task.

Thank you ....Arif

A: 

If you mean that you just want to suppress the warning, you can use the @ operator

$file = @operation();
PatrikAkerstrand
+3  A: 

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.

soulmerge
You're only hiding the problem...
Bart S.
That is only partially correct - updated the answer to reflect that. Sometimes such error handling is really required - have a look at VolkerK's response, he would get a warning anyway in the case of a race condition.
soulmerge
A: 

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');
Yannooo
+11  A: 

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".

VolkerK
+1 That would be the correct way of doing it
soulmerge
YAY! Somebody who knows PHP /and/ knows how to actually write clean code.
Sean McSomething
...and still it's not entirely correct. You would need to check read/write access to the old file and write permissions for the new file (and as mentioned deal with race conditions if they can occur). But anyway ...it's only an example ;-) And I'm not entirely opposed to the @ in this case. You can suppress the output of the warning and still check the return value, set your own error handler, use track_errors/$php_errormsg, ...
VolkerK
Actually, that only half of the necessary checks, we still don't know if the $newfile is writable, nor if it's in a directory that even exists.
Kris
... not mentioning race conditions that would require you to suppress warnings anyway to be able to evaluate the return value without PHP jumping in ...
soulmerge
...and many more conditions that are hard to test in advance. disc-quota e.g. if you "rename"/copy the file (unawaringly) to another filesystem. It's time to edit the post.....
VolkerK
+1  A: 

Two things used together should best serve you:

  1. error_reporting()
  2. 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.

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; 
}
Kris
Something messed up some indentation in the code and i hate it when that happens :-/
Kris