javaquercusapache-commons-vfs

Apache Commons VFS with Quercus


On an unmodified install, how can I configure Quercus so that PHP file functions use Apache Commons VFS to access files?


Solution

  • That's quite a bit of development! More than can fit in an answer here. In outline, there are two main obstacles to overcome here:

    1. implementing functions in PHP that use VFS I/O rather than regular I/O
    2. replacing the standard file functions (fopen/fread/fwrite/fclose) with the functions above.

    Implementing a Quercus module is fairly straightforward - you define functions to be available in php. The main work of the module is to provide the interface to VFS.

    class VFSModule extends AbstractQuercusModule
    {
    
        FileSystemManager fsManager = VFS.getManager();
    
        public Object vfs_fopen(String filename, String mode) {            
            FileObject file =  fsManager.resolveFile(filename);
            if (mode.equals("r"))
                return file.getContent().getInputStream();
            else if (mode.equals("w"))
                return file.getContent().getOutputStream();
            throw new IllegalArgumentException("unsupported mode; "+mode);                
        }
    
        function String vfs_fread(Object stream, int length) {
            InputStream in = (InputStream)stream;
            byte[] buffer = new byte[length];
            int read = in.read(buffer);
            // todo - handle smaller than length reads
            return buffer;
        }
    
        function void vfs_fwrite(Object stream, int length, byte[] data) {
            OutputStream out = (OutputStream)stream;
            out.write(data);
        }
    
    } 
    

    (IOException handling is left out to avoid clutter.)

    Once the module is coded, as a sanity test, write some php script that calls the custom vfs functions from this module.

    Since you can call java (and vfs) directly from PHP, you could do this without a module by coding the equivalent VFS calls in PHP.

    $mgr = org.apache.commons.vfs2.VFS.getManager();
    
    function vfs_open($filename, $mode) {
       if ($mode=="r") {
          return $mgr->resolveFile($filename)->content->getInputStream();
       }
       else if ($mode=="w") {
          return $mgr->resolveFile($filename)->content->getOutputStream();
       }
      // todo - handle other mode combinations
    }
    function vfs_read($resource, $length) {
       $buf = str_repeat(" ", 1024);
       $lenRead = $resource->read($buf, 0, 1024);
       if ($lenRead<0) return "";
       return substr($buf, 0, $lenRead);
    }
    

    The next part is mapping these functions to the standard php file functions. This can be done several ways, as described in redefine buit-in php functions.