On 21/12/2024 20:50, Niels Dossche wrote:
Adding a parameter for a cache, which should've been transparent in the first
place, to every file operation is messy.
I would say it's less messy than having to work out when to turn a
global setting on or off. In particular, it would be horrible for shared
libraries, the equivalent of the above would be something like this:
$old_cache_setting = ini_set('enable_stat_cache', 1);
$perms = fileperms($name); $size = filesize($name);
ini_set('enable_stat_cache', $old_cache_setting);
Similarly, for the false case, library code would either have to assume
the cache might be enabled, and call clearstatcache() just in case; or
it would have to carefully wrap code in similar ini_set blocks.
As far as I can see, both code that benefits from the cache, and code
that suffers from it, is very rare; but if you know you're writing one
or the other, having an explicit way to mark *that code* seems more
appropriate than toggling a global setting.
But if you want to add extra parameters to functions that can potentially touch
the stat cache, then you need to take into account spl as well. Adding extra
parameters to the functions in those classes are a BC break because the
signature of potential userland function overrides would no longer be
compatible at compile time.
Ah yes, I hadn't thought of objects being affected. On the other hand,
objects have an obvious place to store both the state of the setting and
the cache itself: on the instance.
For example, a local rather than global cache would allow this to make
two stat calls, rather than four:
$file1 = new SplFileInfo($name1, usecache: true);
$file2= new SplFileInfo($name2, usecache: true);
if (
$file1->getSize() !== $file2->getSize()
|| $file1->getMTime() !== $file2->getMTime()
) { ... }
In fact, it would probably be useful to pre-fetch a snapshot in the
constructor, rather than just caching on the first method call, so that
this worked:
$before = new SplFileInfo($name, snapshot: true);
do_something();
$after = new SplFileInfo($name, snapshot: true);
if ( $before->getSize() !== $after->getSize() ) { ... }
Inheritance of constructors isn't restricted, so that would not be a BC
break, and seems both more powerful and easier to understand than the
current feature.
Regards,
--
Rowan Tommins
[IMSoP]