phprector

When to use PHP self::class? When to use __CLASS__?


Preamble

I'm working on a legacy Open Source project supporting PHP 5.5 to PHP 8.3.

Question

My question is simple:

  1. When to use PHP self::class?
  2. When to use __CLASS__?
  3. Does it may change from PHP version to version? (at least interested after PHP 5.5)

NOTE: You can skip the other sections. It's just a description of why I am here and what I tried.

Documentation

https://www.php.net/manual/en/language.constants.magic.php

https://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class.class

It seems it does not mention changes between them.

Tests

I tried to do define some tests (feel free to suggest more):

<?php
/**
 * This is just a test class
 */
class A {
        public function selfclass_normal() {
                return self::class;
        }
        public function constclass_normal() {
                return self::class;
        }
        public static function selfclass_static() {
                return self::class;
        }
        public static function constclass_static() {
             return __CLASS__;
        }
}

class B extends A {}

class C extends A {
        public function selfclass_normal() {
                return self::class;
        }
        public function constclass_normal() {
                return self::class;
        }
        public static function selfclass_static() {
                return self::class;
        }
        public static function constclass_static() {
             return __CLASS__;
        }
}

echo "Normal class:\n";
$a = new A();
echo $a->selfclass_normal();
echo $a->constclass_normal();
echo A::selfclass_static();
echo A::constclass_static();
echo "\n\n";

echo "Empty extended class\n";
$b = new B();
echo $b->selfclass_normal();
echo $b->constclass_normal();
echo B::selfclass_static();
echo B::constclass_static();
echo "\n\n";

echo "Extended class rewriting methods\n";
$c = new C();
echo $c->selfclass_normal();
echo $c->constclass_normal();
echo C::selfclass_static();
echo C::constclass_static();
echo "\n\n";

This is the output on PHP 7.4:

Normal class:
AAAA

Empty extended class
AAAA

Extended class rewriting methods
CCCC

So I'm inclined to think that self::class and __CLASS__ are the same.

Exploring it in Rector.php

I discovered that Rector.php has a rule to convert __CLASS__ to self::class and not the vice-versa.

https://github.com/rectorphp/rector/blob/main/docs/rector_rules_overview.md#classconstanttoselfclassrector

So it seems Rector prefers self::class.

Does it help in understanding the historical differences between self::class and __CLASS__?


Solution

  • Does it may change from PHP version to version? (at least interested after PHP 5.5)

    self::class should be the replacement of __CLASS__ in design and more flexible. Unfortunately, if you are still using php 5, you may encounter some bugs (e.g. this, this), but if you are using php 7 or later, it will be OK.