Search code examples
phpvalidationpathsuppress-warnings

Check if string could be a path (without warning)


How can I check if a string is a valid path in PHP without warning if string isn't a valid path?

When I use file_get_contents, is_file, realpath, file_exists with a string that isn't a path I get the following warning.

"function_name()" expects parameter 1 to be a valid path, string given in [...]

So how to determine whether the string could be a valid path or not.


What the hell do you want to do? You may ask...

Well, I want to create a function like this.

funtion my_smart_function( string $path_or_content )
{
    $content = is_file_without_warning_if_not_a_valid_path( $path_or_content )
             ? file_get_contents( $path_or_content )
             :                    $path_or_content;
    // do nice stuff with my $content
}

Sometimes $path_or_content will be a valid path to a file and sometimes $path_or_content will be the content of a file by itself (eg the binary data of an image created on the fly that doesn't even have a path (at least not yet)). In the latter case all these string related functions I mentioned above (eg file_exists()) will throw a warning (see quote above).


Something I'm wondering about.
realpath('xyz') doesn't throw a warning but
realpath( file_get_contents('path/to/actual/image.jpg') ) does...

So realpath and the other functions mentioned above distinguish between a string or a string that is a valid path. So how can we do either beforehand?


Solution

  • This may be a reasonable time to use the @ modifier to suppress errors.

    funtion my_smart_function( string $path_or_content )
    {
        $content =      @file_exists( $path_or_content )
                 ? file_get_contents( $path_or_content )
                 :                    $path_or_content;
    }
    

    If it's not a valid path, file_exists() will return a falsey value, and the @ will keep it from complaining about the bad string.

    On Linux, the only character that's not allowed in a path is the null byte. So you could just check for this:

    if (strpos($path_or_contents, "\0") === false) {
        return file_get_contents($path_or_contents);
    } else {
        return $path_or_contents;
    }