phpwindowsfilepermissionsmounted-volumes

php is_writable returns always false for a writable mount


To convert my application to laravel I've tried to create a new application. I'm using a network mount to access the files on the linux server. There is no ssh access. My machine is Windows. The server is accessible as network mount. While creating the laravel-6 application on the mounted drive I got this error:

Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi

In PackageManifest.php line 179:

  The R:\path\to\laravel\bootstrap\cache directory must be present and writable.


Script @php artisan package:discover --ansi handling the post-autoload-dump event returned with error code 1

In all directories I can read and write. After some testing I recognized that is_writable always returns false for files on the drive (on Windows). This is stupid because i can create and modify files on the drive (including the cache directory). I also tried It in cygwin. Same result.

The php fileperms method returns formatted: 40777. So i guess it should be readable and writable. php version: 7.3.9

How to configure my windows php environment to see the files as writable?


Solution

  • This seems to be a already known bug in php when you access network (smb or samba) files.

    Similar question was already asked: is_writable returns false for NFS-share, even though it is writable for the user www-data

    Read this for more informations about the bug: https://bugs.php.net/bug.php?id=68926

    Unfortunally the only solution for the problem (that I know) is to write your own custom is_writeable functions like this:

    <?php
    namespace Same\As\One\You\Use\Them\In;
    function is_readable($file)
    {
        if(file_exists($file) && is_file($file))
        {
            $f = @fopen($file, 'rb');
            if(fclose($f))
            {
                return true;
            }
        }
    
        return false;
    }
    
    function is_writable($file)
    {
        $result = false;
        if(file_exists($file) && is_file($file))
        {
            $f = @fopen($file, 'ab');
            if(fclose($f))
            {
                return true;
            }
        }
    
        return false;
    }
    ?>