3

在未修改的安装中,如何配置 Quercus 以便 PHP 文件函数使用 Apache Commons VFS 访问文件?

4

1 回答 1

2

这是相当大的发展!这里的答案不止于此。概括地说,这里有两个主要障碍需要克服:

  1. 在 PHP 中实现使用 VFS I/O 而不是常规 I/O 的函数
  2. 用上述函数替换标准文件函数(fopen/fread/fwrite/fclose)。

实现 Quercus 模块相当简单——您可以定义在 php.ini 中可用的函数。该模块的主要工作是为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 处理被省略以避免混乱。)

一旦模块被编码,作为健全性测试,编写一些 php 脚本,从这个模块调用自定义 vfs 函数。

由于您可以直接从 PHP 调用 java(和 vfs),因此您可以通过在 PHP 中编写等效的 VFS 调用来在没有模块的情况下执行此操作。

$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);
}

下一部分是将这些函数映射到标准 php 文件函数。这可以通过多种方式完成,如重新定义内置 php 函数中所述。

于 2011-08-25T22:43:57.450 回答