php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #79085 Incosistency on ::class constant
Submitted: 2020-01-08 19:18 UTC Modified: 2020-01-10 10:36 UTC
From: almamu at almamu dot com Assigned:
Status: Open Package: Class/Object related
PHP Version: 7.2.26 OS: Any
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: almamu at almamu dot com
New email:
PHP Version: OS:

 

 [2020-01-08 19:18 UTC] almamu at almamu dot com
Description:
------------
I've noticed some inconsistencies on how the ::class magic constant is handled compared to other constants/class members. As seen in the example script, if you try to access ::class on a non-existant class, you don't get any kind of error, which would be expected, as the class itself doesn't exist. This can provoke some nasty errors where you typo the class' name and PHP doesn't even give you a (expected) warning.

I've created an interactive example with that same code so you can check it live and toy with it: https://3v4l.org/RbIhK

Test script:
---------------
<?php
 echo FOO::class;
 echo FOO::constantName;
 echo FOO::$username; // It works as echoing Typo\WTF; It shall fail...

Expected result:
----------------
    Fatal error: Uncaught Error: Class 'FOO' not found in /in/RbIhK:2
    Stack trace:
    #0 {main}
      thrown in /in/RbIhK on line 3

    Process exited with code 255.

Actual result:
--------------
    FOO
    Fatal error: Uncaught Error: Class 'FOO' not found in /in/RbIhK:3
    Stack trace:
    #0 {main}
      thrown in /in/RbIhK on line 3

    Process exited with code 255.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-01-08 19:38 UTC] requinix@php.net
-Status: Open +Status: Not a bug -Type: Feature/Change Request +Type: Bug
 [2020-01-08 19:38 UTC] requinix@php.net
::class is special and not really a constant. The compiler sees it and expands the "FOO::class" to be a string. As in when that gets executed, it's a literal string value - like if you had written it right into the code yourself.
 [2020-01-09 11:57 UTC] almamu at almamu dot com
I understand that's how it works internally, that's why I did create this as Feature/Change request and not as a bug. I think this should behave consistently as other constants (because the documentation calls it a special constant: "The special ::class constant is available as of PHP 5.5.0, and allows for fully qualified class name resolution at compile time, this is useful for namespaced classes: "), just like there's a request to make it work with objects: https://wiki.php.net/rfc/class_name_literal_on_object

This RFC makes an important point too, we already support static::class, which is resolved on runtime and not compiletime.
 [2020-01-09 21:52 UTC] requinix@php.net
-Status: Not a bug +Status: Open -Type: Bug +Type: Feature/Change Request
 [2020-01-09 21:52 UTC] requinix@php.net
Personally I find it very helpful that I can FOO::class and have it not trigger the autoloader.
 [2020-01-10 09:40 UTC] almamu at almamu dot com
I've tried to come up with situations where that might be useful, but I fail to see any benefits on it. Do you mind sharing an example situation where it is useful?
 [2020-01-10 09:41 UTC] nikic@php.net
One common usage is in class_alias(). One of the operands will naturally not be declared at the time of the class_alias() call.
 [2020-01-10 10:36 UTC] almamu at almamu dot com
I see, I completely overlooked the class_alias function, I've always used "use ClassName as Alias". The second parameter doesn't look like it'd be a good idea to use ::class to specify it, but for the first parameter it might be an issue to autoload it on certain situations ( that would imply there is no "use ClassName" for it, because that would trigger the autoload regardless of what the third parameter says. which doesn't really look good to me either). I guess the same applies to the class_exists function.

Is this kind of usage that common? All the usages I've witnessed of "class_alias" in the wild leave out the third parameter (and thus enabling the autoload).
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Wed Oct 21 02:01:29 2020 UTC