2

If I have a file in a php streamwrapper, such as "media://icon.png" how can I get it to tell me the filesystem path of that file, assuming it's on a filesystem?

I looked on the documentation page but didn't see a method to return the streamwrapper path.

user151841
  • 17,377
  • 29
  • 109
  • 171
  • Who says it has to use a file behind the scene? That's the whole purpose of stream wrappers: to use the well-known file manipulation functions with data streams that are not necessarily tied to the file system. – axiac Jun 22 '15 at 16:37
  • In this case, I want to construct a `src` path for an html `img` tag. Where I'm using it, I'm pretty certain it's a file, and I can always use something like `is_file()` to make sure. – user151841 Jun 22 '15 at 16:59

1 Answers1

1

The StreamWrapper class represents generic streams. Because not all streams are backed by the notion of a filesystem, there isn't a generic method for this.

If the uri property from stream_get_meta_data isn't working for your implementation, you can record the information during open time then access it via stream_get_meta_data. Example:

class MediaStream {
    public $localpath = null;

    public function stream_open($path, $mode, $options, &$opened_path)
    {
        $this->localpath = realpath(preg_replace('+^media://+', '/', $path));

        return fopen($this->localpath, $mode, $options);
    }
}

stream_wrapper_register('media', 'MediaStream');

$fp   = fopen('media://tmp/icon.png', 'r');
$data = stream_get_meta_data($fp);
var_dump(
    $data['wrapper_data']->localpath
);

Of course, there's always a brute force approach: after creating your resource, you can call fstat, which includes the device and inode. You can then open that device, walk its directory structure, and find that inode. See here for an example.

Community
  • 1
  • 1
bishop
  • 37,830
  • 11
  • 104
  • 139