====== PHP RFC: Add is_cacheable() stream-wrapper operation ====== * Version: 1.2 * Date: 2015-01-04 * Author: François Laupretre, francois@tekwire.net * Status: Under discussion * First Published at: http://wiki.php.net/rfc/streams-is-cacheable ===== 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 a quick-and-dirty workaround and there is real need for 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) ===== PHP 7. ===== RFC Impact ===== ==== To SAPIs ==== None ==== To Existing Extensions ==== Phar needs to implement an is_cacheable() function, returning always 1. The same for the plain files wrapper. ==== To Opcache ==== Opcode caches must 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 ==== None ===== Open Issues ===== Discussion is under way to define how the cache can compute the key corresponding to a stream-wrapped path. ===== Unaffected PHP Functionality ===== Stream wrappers that don't require their scripts to be cacheable are not modified in any way. ===== Proposed Voting Choices ===== Required majority: 50%+1 ===== Patches and Tests ===== Pull Request: [[https://github.com/php/php-src/pull/976]] This PR includes every modification described in this RFC, including phar and plain files is_cacheable() handler. It also contains tests. PHP documentation additions (file_is_cacheable(), streamWrapper::is_cacheable()) not written yet. ===== Implementation ===== ===== References ===== Pull request: [[https://github.com/php/php-src/pull/976]] ===== Rejected Features =====