rfc:streams-is-cacheable

This is an old revision of the document!


PHP RFC: Add is_cacheable() stream-wrapper operation

Introduction

The RFC proposes a generic way for opcode caches to determine if a given URI is cacheable or not.

Proposal

When stream wrappers were introduced in PHP, their relationship with opcode caches was not a problem, as they were mostly used to access remote data. The need for a better interaction arose with package systems, like phar and phk, as these stream wrappers manage a virtual PHP source tree through stream URIs. If the scripts provided by such a system cannot be opcode-cached, the system looses a great part of its value.

Historically, the issue was addressed using different workarounds : either every URI is considered as opcode-cacheable (APC), whatever wrapper it is coming from, or a list of 'cacheable' protocols is declared explicitely in the cache code. For instance, opcache is using the second solution : 'file' and 'phar' are explicitely declared as the only 'cacheable' stream wrappers. This is nothing more than a quick-and-dirty workaround and we now need a reliable and generic way of determining whether an URI is cacheable.

What I am proposing :

  • An element named 'stream_is_cacheable' is added at the end of the php_stream_wrapper_ops structure. This is an optional pointer to a function able to determine if a given URI is cacheable or not. This function receives an URI, an options bitfield, and an optional context. It returns a value different of 0 if the URI is cacheable. If the 'stream_is_cacheable' element is null, every URI for this wrapper are considered as non-cacheable.
  • A new C function named php_stream_is_cacheable(const char *path, int options, php_stream_context *context) is defined. It determines the right wrapper from the path it receives and forwards the request to the corresponding stream_is_cacheable() function, if it exists. If the stream_is_cacheable() element is not defined, 0 is returned.
  • Userspace stream wrappers can define a method named is_cacheable(path [,options]). This method determines if the input path is cacheable and returns true or false. If the method is not defined, every path for this wrapper are non-cacheable.
  • For completeness, a new PHP function named file_is_cacheable(path [, options [, context]]) is defined. It allows to determine from a PHP script whether a path is cacheable.

Backward Incompatible Changes

None

Proposed PHP Version(s)

5.7, if released. Otherwise, PHP 7.

RFC Impact

To SAPIs

None

To Existing Extensions

Phar needs to implement an is_cacheable() function. This function always returns 1.

The same for the plain files wrapper.

To Opcache

Opcode caches will implement the following logic :

If the received path is a 'stream' path, call php_stream_is_cacheable(path, 0, NULL).

If the returned value is non null, the path is cacheable. If it is null, the path is not cacheable.

New Constants

The C-level PHP_STREAMS_SUPPORT_IS_CACHEABLE is defined. This allows conditional code using '#ifdef' stanza.

Open Issues

None

Unaffected PHP Functionality

Stream wrappers that don't require their scripts to be cacheable are not modified in any way.

Proposed Voting Choices

2/3 or 50%+1 majority ? Not clear for me :)

Patches and Tests

A pull request is available at :

https://github.com/php/php-src/pull/976

This patch includes every modification described in this RFC, including phar and plain files is_cacheable() handler. It also contains tests.

PHP manual changes not written yet.

Implementation

References

Rejected Features

rfc/streams-is-cacheable.1420335635.txt.gz · Last modified: 2017/09/22 13:28 (external edit)