PHP :: Bug #65419 :: Inside trait, self::class != __CLASS__

Bug #65419 Inside trait, self::class != __CLASS__
Submitted: 2013-08-08 08:44 UTC Modified: 2014-11-28 13:22 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:0 of 1 (0.0%)
From: nicolas dot grekas+php at gmail dot com Assigned: ralphschindler (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: 5.5.1 OS:
Private report: No CVE-ID: None

 [2013-08-08 08:44 UTC] nicolas dot grekas+php at gmail dot com

Description:
------------
The RFC for ::class name resolution as scalar say that self::class resolves the same as __CLASS__:

https://wiki.php.net/rfc/class_name_scalars#considerations

But this is not true when using traits.

Test script:
---------------
<?php

trait abc
{
  static function def()
  {
    echo self::class, "\n";
    echo __CLASS__, "\n";
}

class ghi
{
  use abc;
}

ghi::def();

Expected result:
----------------
ghi
ghi

Actual result:
--------------
abc
ghi

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports

 [2013-08-08 18:33 UTC] requinix@php.net

The RFC was created a few weeks after 5.4.0 was released and does not specify how self::class would work for traits. I would take that to mean the writer did not consider how it would 
work for traits, rather than that traits should "inherit" the behavior for classes.

So either this is a doc bug and the ::class doc should state that it resolves to the trait itself when used for traits (as a "::trait" syntax would be weird), or self::class is fixed so 
be identical to __CLASS__. Presumably parent::class and static::class would receive similar changes.

Note for the latter: in zend_language_scanner, __CLASS__ has special handling when used inside traits. I imagine similar logic - creating "a special __CLASS__ constant" - would be used in 
zend_do_resolve_class_name().

 [2013-08-09 07:55 UTC] nicolas dot grekas+php at gmail dot com

I totally agree with you.

This reminds me the discussion that happened in https://bugs.php.net/55214 and that led to this special handling for __CLASS__.

I think that the very same arguments apply here also.

Concerning parent and static, they are free from this problem because they are resolved at run-time (tested, it works).

 [2013-08-09 07:57 UTC] gron@php.net

-Status: Open +Status: Verified

 [2013-08-09 07:57 UTC] gron@php.net

Yes, that looks wrong. It should indeed behave as __CLASS__.

 [2013-08-11 15:31 UTC] laruence@php.net

I prefer to trigger a COMPILE ERROR prevent from using ::class in a traits

 [2013-08-14 10:10 UTC] nicolas dot grekas+php at gmail dot com

Why remove ::class support inside traits? It mostly works today, and it is as usefull there than inside classes or anywhere else, am I wrong?

Would it be possible to replace self::class occurences by __CLASS__ at compile time so that the code path for __CLASS__ is also used here?

 [2013-09-12 16:52 UTC] ralphschindler@php.net

Ill work up a patch that will demonstrate ::class resolving in traits similar to how __CLASS__ works in traits.

This seems to be the consensus (correct me if I am wrong), and consistent with __CLASS__ (to some degree) in traits.

 [2014-02-18 08:34 UTC] nicolas dot grekas+php at gmail dot com

It would be nice if this could be resolved for 5.6. I fear people could start relying on this buggy behavior...

 [2014-11-28 12:38 UTC] jpauli@php.net

-Status: Verified +Status: Closed

 [2014-11-28 13:22 UTC] jpauli@php.net

-Status: Closed +Status: Feedback

 [2014-12-05 07:00 UTC] ab@php.net

-Status: Feedback +Status: Closed