Check if file was created

4

I made a function that creates a file in php, but I need it to return true if everything worked fine or false if one of the steps failed. I have decided as follows:

function createFile($path, $nome, $content){
    if (!($fp = fopen($path.$nome,"wb")))
        return false;
    if (!fwrite($fp,$content))
        return false;
    if (!fclose($fp))
        return false;
    return true;
}

Is there a cleaner way to do this?

The problem with using file_exists is that I will not know if there was an error in fwrite for example. I was wondering if there is something like try()catch() but with errors instead of exceptions.

    
asked by anonymous 27.12.2016 / 16:28

1 answer

5

Simplifying

function createFile($path, $nome, $content){
    return file_put_contents($path.$nome, $content);
}

The function file_put_contents () returns boolean false in case of error. Otherwise, it will return the amount of bytes written to the file.

This is basically what returns from the fwrite () function, which needs the < fopen () .

However, it does not mean that it is more performative because it has fewer codes. Usually fopen() , fwrite() and fclose() cost less. However, for a single process it is a whimsical cost difference.

If you want to keep the question code and give it more consistency, you could add a fourth conditional by checking the resource:

function createFile($path, $nome, $content){
    if (!($fp = fopen($path.$nome,"wb")))
        return false;
    if (!fwrite($fp,$content))
        return false;
    if (!fclose($fp))
        return false;
    if (!is_resource($fp))
        return false;
    return true;
}

But in this case it is somewhat unusual. It can happen in specific environments where fclose() returns true and the resource is still active. In this case the is_resource () function can be useful.

The file_put_contents() function simplifies all this. After all, the result will be the same.

Note also that the name of the function you created is createFile() , however there are several operations that may return different results that may not necessarily be related to what the function's nomenclature says "create file".

If you want a meticulous return, you could create an array containing the return of each function, because a situation that may occur is that the file is created and the contents are written correctly and only fail in fclose() . But as it is, a failure in fclose() would return false and you will not know where the false value came from.

You could implement something like this:

function createFile($path, $nome, $content){
    $rs = array(
        'fopen' => null,
        'fwrite' => null,
        'fclose' => null
    );
    if (($rs['fopen'] = fopen($path.$nome, 'wb')) !== false) {
        $rs['fwrite'] = fwrite($rs['fopen'], $content);

        // Invoque fclose() independente do resultado de fwrite().
        $rs['fclose'] = fclose($fp);
    }
    return $rs;
}

Note that fclose() is invoked regardless of the return of fwrite() . This is because even if fwrite() fails the fopen() resource will remain open. In the original version of the question this does not happen. You have a small leak.

But I would still suggest renaming the function because you are not just creating a file. You are also entering data. For a createfile, the ideal would also be to check if the directory is a valid path before it even invokes fopen() . Giving more consistency to the function. It may be the case to think of OOP to organize better and avoid this "spaghetti" of codes.

If you ask me if I do this in real life. No, I do not. I only use file_put_contents() to be happy. For in most cases it does not need so much complication. Except, of course, for cases where it really requires a real need to create a "highly" consistent routine.

    
27.12.2016 / 17:33