php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #80938 ParseError with class_exists & property promotion
Submitted: 2021-04-05 16:03 UTC Modified: 2021-04-05 16:32 UTC
From: jr at rushlow dot dev Assigned:
Status: Not a bug Package: Class/Object related
PHP Version: 7.4.16 OS:
Private report: No CVE-ID: None
 [2021-04-05 16:03 UTC] jr at rushlow dot dev
Description:
------------
Calling class_exists() on a class that uses constructor property promotion results in a ParseError.

Property promotion is only available in PHP8.0+ but one would expect that you could use class_exists() regardless class implementation.

Test script:
---------------
// See https://github.com/rushlow-development/attribute-test for a simple reproducer w/ composer && phpunit

<?php

class PromoteConstructorProperty
{
    public function __construct(
        public string $var
    ) {
    }
}

$bool = class_exists(PromoteConstructorProperty);

Expected result:
----------------
$bool = true

Actual result:
--------------
ParseError: syntax error, unexpected 'public' (T_PUBLIC), expecting variable (T_VARIABLE)

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-04-05 16:05 UTC] nikic@php.net
-Status: Open +Status: Not a bug
 [2021-04-05 16:05 UTC] nikic@php.net
class_exists() with autoload:true (the default) will load the class. If the class declaration doesn't parse, you get an error, as usual.
 [2021-04-05 16:22 UTC] danack@php.net
Incidentally, the reproduce code gives a different error https://3v4l.org/oEW4q:

Fatal error: Uncaught Error: Undefined constant "PromoteConstructorProperty" in /in/oEW4q:11

class_exists(PromoteConstructorProperty); 

should probably be:

class_exists(PromoteConstructorProperty::class);
 [2021-04-05 16:22 UTC] jr at rushlow dot dev
That makes sense. But to put it another way for clarity - calling class_exists() on a class that is not correctly defined for the PHP version used a runtime cannot be done?

If that is the case - should we change the docs to reflect this? 

"class_exists — Checks if the class has been defined" -> https://www.php.net/manual/en/function.class-exists.php

I'll start a thread in internals (to further discuss options) if the above is true as it would seem that one can no longer use class_exists() in code bases that support multiple PHP versions. Granted I may be missing something obvious :)
 [2021-04-05 16:23 UTC] danack@php.net
https://3v4l.org/oEW4q even
 [2021-04-05 16:32 UTC] jr at rushlow dot dev
-Summary: ParseError with class_exists & property promotion +Summary: jr@rushlow.dev
 [2021-04-05 16:32 UTC] jr at rushlow dot dev
Good catch dan!

<?php

class PromoteConstructorProperty
{
    public function __construct(
        public string $var
    ) {
    }
}

$bool = class_exists(PromoteConstructorProperty::class);

-> https://3v4l.org/4cMW4
 [2021-04-05 16:32 UTC] jr at rushlow dot dev
-Summary: jr@rushlow.dev +Summary: ParseError with class_exists & property promotion
 [2021-04-05 16:32 UTC] jr at rushlow dot dev
oops..
 [2021-04-05 17:32 UTC] claude dot pache at gmail dot com
Property promotion is implemented since PHP 8.0 only. It is totally expected that you get a parse error in PHP 7.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Dec 26 14:01:30 2024 UTC