php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
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

Add a Patch

Pull Requests

Add a Pull Request

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
-Assigned To: +Assigned To: ralphschindler
 [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-10-29 13:40 UTC] jpauli@php.net
Got a patch at https://github.com/jpauli/php-src/compare/65419

I basically add a runtime resolve for self:: into Traits, making it behaves like __CLASS__
 [2014-11-28 12:38 UTC] jpauli@php.net
Automatic comment on behalf of jpauli
Revision: http://git.php.net/?p=php-src.git;a=commit;h=7c77ca38b1e3ea7a707380c731b237c2c480e093
Log: Fix #65419 - Inside trait, self::class != __CLASS__
 [2014-11-28 12:38 UTC] jpauli@php.net
-Status: Verified +Status: Closed
 [2014-11-28 12:39 UTC] jpauli@php.net
Automatic comment on behalf of jpauli
Revision: http://git.php.net/?p=php-src.git;a=commit;h=7c77ca38b1e3ea7a707380c731b237c2c480e093
Log: Fix #65419 - Inside trait, self::class != __CLASS__
 [2014-11-28 12:39 UTC] jpauli@php.net
Automatic comment on behalf of jpauli
Revision: http://git.php.net/?p=php-src.git;a=commit;h=7c77ca38b1e3ea7a707380c731b237c2c480e093
Log: Fix #65419 - Inside trait, self::class != __CLASS__
 [2014-11-28 13:22 UTC] jpauli@php.net
-Status: Closed +Status: Feedback
 [2014-11-28 13:22 UTC] jpauli@php.net
Please try using this snapshot:

  http://snaps.php.net/php5.5-latest.tar.gz
 
For Windows:

  http://windows.php.net/snapshots/


 [2014-12-05 07:00 UTC] ab@php.net
Automatic comment on behalf of jpauli
Revision: http://git.php.net/?p=php-src.git;a=commit;h=7c77ca38b1e3ea7a707380c731b237c2c480e093
Log: Fix #65419 - Inside trait, self::class != __CLASS__
 [2014-12-05 07:00 UTC] ab@php.net
-Status: Feedback +Status: Closed
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 07:01:29 2024 UTC