Sadly the documentation is a bit lacking, so this article will try provide some middle ground behind the unexplained usage example you'll find in a few places, and the dry API docs. (In fact skip the API docs completely - the source is more understandable.)
I'm going to show this completely outside PHPUnit, as that clouds the issues. Let's start with the include we need:
require_once 'vfsStream/vfsStream.php';
(Aside: all tests here are being done with version 0.12.0, installed using pear.)
Here is our minimal example:
vfsStream::setup('logs');
file_put_contents(vfsStream::url('logs/test.log'),"Hello\n");
The first line creates our filesystem.
The second line creates a file called "test.log", and puts a string inside it.
There is something I want to emphasize here, as it confused me no end. We have not created a directory called "logs". We have created a virtual file system called "logs". We have no sub-directories at all. test.log lives in the root of the filesystem.
Here is our troubleshooting tool:
require_once 'vfsStream/visitor/vfsStreamStructureVisitor.php';
print_r(vfsStream::inspect(new vfsStreamStructureVisitor())->getStructure());
It outputs:
Array
(
[logs] => Array
(
[test.log] => Hello
)
)
(Yes, I know it still looks like logs is a directory name there too. It isn't.)
Another way to troubleshoot this is using PHP functions directly:
$dir=dir("vfs://logs");
while(($entry=$dir->read())!==false)echo $entry."\n";
This outputs:
test.log
Note: you cannot use "vfs://" as a url to get the root. This is like trying to access the root of a website with "http://". You need to use "http://example.com/" and you need to use "vfs://logs" for a virtual filesystem. As I said, I found this confusing, so I prefer to rewrite my above examples as follows (this also shows the complete code):
require_once 'vfsStream/vfsStream.php';
vfsStream::setup('_virtualroot_',null,array('logs'=>array()));
file_put_contents(vfsStream::url('_virtualroot_/logs/test.log'),"Hello\n");
print_r(vfsStream::inspect(new vfsStreamStructureVisitor())->getStructure());
$dir=dir("vfs://_virtualroot_");
while(($entry=$dir->read())!==false)echo $entry."\n";
?>
This time we do have a directory called "logs", which is in the root of a virtual file system called "_virtualroot_". You may hate that approach for its horrible verbosity. Me? I like it.
A few random other points about vfsStream:
- chdir("vfs://logs") does not work. The Known Issues page lists a few more.
- vfsStream::url("logs/test.log") simply returns "vfs://logs/test.log".
- fopen($fname,"at") fails. The "t" is not supported. You have to change your code to use "a" or "ab" (aside: "ab" is better, as "a" could work differently on different systems).
- Calling vfsStream::setup a second time removes the previous filesystem, even if you use a different virtual filesystem name.
- I've not worked out how to use the git version. It may be that my above examples do not work with the very latest version. If I work it out, and that is the case, I'll post additional examples.
2 comments:
Thanks for this post, it helped me make sense of a few things.
Thanks for this post, it helped me make sense of a few things.
Post a Comment