rfc:linking_in_stream_wrappers

PHP RFC: Support linking in stream wrappers

Introduction

This RFC suggests adding support for links in stream wrappers by adding appropriate hooks.

Proposal

Userland stream wrappers must be able to hook into:

 1. Creating links
 2. Testing for links' existance
 3. Returning file type
 4. Resolving links

Currently, #2 and #3 are already supported by streamWrapper::url_stat(). With this accomplished, frameworks such as vfsStream can support testability of symlinking correctly.

Use case #1 - new functionality:

class wrapper {
 
  /**
   * Creates a hard link to the existing target with the specified name link. 
   *
   * @param  string $target
   * @param  string $link
   * @return bool Whether the operation succeeded or not.
   */
  function url_link($target, $link) {
    // ...
  }
 
  /**
   * Creates a symbolic link to the existing target with the specified name link. 
   *
   * @param  string $target
   * @param  string $link
   * @return bool Whether the operation succeeded or not.
   */
  function url_symlink($target, $link) {
    // ...
  }
}

Use cases #2 and #3 - already possible today:

class wrapper {
 
  /**
   * See http://php.net/manual/en/streamwrapper.url-stat.php
   *
   * @param  string $url
   * @param  int $flags
   * @return array or FALSE on error
   */
  function url_stat($url, $flags) {
    if ($flags & STREAM_URL_STAT_LINK) {
      // Stat the link, not the file it points to
    }
 
    // ...
 
    return [
      // ...
      'mode' => $permissions & 0120000  // S_ISLINK
    ]; 
  }
}

Use case #4 - new functionality:

class wrapper {
 
  /**
   * Reads a link and returns the target
   *
   * @param  string $link
   * @return string The link target or FALSE if the does not exist
   */
  function url_readlink($link) {
    // ...
  }
}
  • When url_readlink() returns a string, it will be used as readlink()'s return value.
  • When url_readlink() returns FALSE, readlink() quietly returns FALSE
  • For all other return values of url_readlink(), a warning is raised and readlink() returns FALSE
  • When url_readlink() is not implemented, a warning is raised an readlink() returns FALSE.

Limitations

It will not be possible to create links between two different stream wrappers like this:

symlink('foo://some/resource', 'bar://another/resource'); // will yield a PHP_WARNING and return false

Backward Incompatible Changes

This RFC introduces no BC breaks.

Proposed PHP Version(s)

The next PHP 5.x version, or PHP 7.

RFC Impact

To SAPIs

No impact.

To Existing Extensions

No impact.

To Opcache

No impact.

New Constants

No new constants are introduced.

Open Issues

TODO: Check whether realpath() can be hooked into easily. Maybe it needs to be omitted…

Unaffected PHP Functionality

TODO:

Future Scope

This sections details areas where the feature might be improved in future, but that are not currently proposed in this RFC.

Proposed Voting Choices

This RFC requires a 50%+1 majority

Patches and Tests

TODO: Implement and submit GitHub pull request. https://github.com/thekid/php-src/compare/rfc/linking_in_stream_wrappers

References

rfc/linking_in_stream_wrappers.txt · Last modified: 2017/09/22 13:28 (external edit)