Table of Contents

PHP RFC: Property hook improvements

Introduction

While finalizing the implementation of the property hooks RFC patch, we have found a small area for improvement. This is nominally changes from the behavior defined in the original RFC, and thus we want to refer them through the RFC process.

Proposal

There is one improvement we propose.

As defined in the original RFC, the following code would have been detected and throw a dedicated error.

class C
{
    public string $val = 'a' {
        get {
          return $this->val . $this->suffix();
        }
    }
 
    public function suffix(): string
    {
        return $this->val;
    }
}
 
$c = new C();
print $c->val;

While looking for optimizations, Ilija found he was able to refactor the hook logic to make it more than twice as fast: While there is still some overhead to a hook compared to a traditional get method, it's been reduced from “close to the cost of __get” to “almost negligible compared to a method.” Enough that it would almost certainly be swamped by the cost of the hook body itself. This is a massive improvement.

A side effect of that optimization, however, is that we cannot proactively detect the bug above. Instead, it would result in an infinite loop, which would eventually trigger a stack limit exception from PHP. (That logic already exists.)

We consider the slightly worse error handling fully justified by the performance improvement, and by the fact that the code above is a bug no matter what (it's just a question of when the bug gets reported). But as it is a change from the behavior stated in the previous RFC, we are putting it out for consideration.

Backward Incompatible Changes

None.

Proposed PHP Version(s)

PHP 8.4.

RFC Impact

Proposed Voting Choices

Remove the extra hook recursion guard?
Real name Yes No
alcaeus (alcaeus)  
beberlei (beberlei)  
bwoebi (bwoebi)  
crell (crell)  
derick (derick)  
devnexen (devnexen)  
ericmann (ericmann)  
galvao (galvao)  
girgias (girgias)  
ilutov (ilutov)  
jhdxr (jhdxr)  
jimw (jimw)  
josh (josh)  
kalle (kalle)  
kguest (kguest)  
kocsismate (kocsismate)  
lbarnaud (lbarnaud)  
mauricio (mauricio)  
mbeccati (mbeccati)  
nicolasgrekas (nicolasgrekas)  
nielsdos (nielsdos)  
patrickallaert (patrickallaert)  
petk (petk)  
pierrick (pierrick)  
ramsey (ramsey)  
rasmus (rasmus)  
reywob (reywob)  
sebastian (sebastian)  
sergey (sergey)  
theodorejb (theodorejb)  
timwolla (timwolla)  
trowski (trowski)  
weierophinney (weierophinney)  
Final result: 33 0
This poll has been closed.

Patches and Tests

Implementation

After the project is implemented, this section should contain

  1. the version(s) it was merged into
  2. a link to the git commit(s)
  3. a link to the PHP manual entry for the feature
  4. a link to the language specification section (if any)

References

Links to external references, discussions or RFCs

Rejected Features

Keep this updated with features that were discussed on the mail lists.