Skip to content

Property hooks cause an infinite recursion in traits #15240

Closed
@dlsrc

Description

@dlsrc

Description

If I put the hook code in a class, everything works as expected:

<?php

class TestClass {
    public int $foo {
        set(int $foo) {
            if ($foo > 10) {
                $this->foo = 10;
            }
            elseif ($foo < 1) {
                $this->foo = 1;
            }
            else {
                $this->foo = $foo;
            }
        }
    }

    public function __construct() {
        $this->foo = 1;
    }

    public function __toString() {
        return (string) $this->foo;
    }
}

$test = new TestClass;
$test->foo = 400;
print $test;

Result is:

10

Ok.
But if I need to use a trait:

<?php

trait TestTrait {
    public int $foo {
        set(int $foo) {
            if ($foo > 10) {
                $this->foo = 10;
            }
            elseif ($foo < 1) {
                $this->foo = 1;
            }
            else {
                $this->foo = $foo;
            }
        }
    }
}

class TestClass {
    use TestTrait;

    public function __construct() {
        $this->foo = 1;
    }

    public function __toString() {
        return (string) $this->foo;
    }
}

$test = new TestClass;
$test->foo = 400;
print $test;

Resulted in this output:

PHP Fatal error:  Uncaught Error: Maximum call stack size of 8339456 bytes (zend.max_allowed_stack_size - zend.reserved_stack_size) reached. Infinite recursion? in /var/www/hosts/pub/tests/test.php:5
#0 /var/www/hosts/pub/tests/test.php(13): TestClass->$foo::set()
#1 /var/www/hosts/pub/tests/test.php(13): TestClass->$foo::set()
#2 /var/www/hosts/pub/tests/test.php(13): TestClass->$foo::set()
#3 /var/www/hosts/pub/tests/test.php(13): TestClass->$foo::set()
#4 /var/www/hosts/pub/tests/test.php(13): TestClass->$foo::set()
#5 /var/www/hosts/pub/tests/test.php(13): TestClass->$foo::set()
.
.
.
#9815 /var/www/hosts/pub/tests/test.php(13): TestClass->$foo::set()
#9816 /var/www/hosts/pub/tests/test.php(37): TestClass->$foo::set()
#9817 /var/www/hosts/pub/tests/test.php(45): TestClass->__construct()
#9818 {main}
  thrown in /var/www/hosts/pub/tests/test.php on line 5

But I expected this output instead:

10

PHP Version

PHP 8.4.0alpha4

Operating System

RHEL9 and Windows10

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions