Як отримати назву класу в PHP?


99
public class MyClass {

}

У Java ми можемо отримати назву класу за допомогою String className = MyClass.class.getSimpleName();

Як це зробити в PHP? Я вже знаю get_class(), але це працює лише для об'єктів. В даний час я працюю в Active Record. Мені потрібна заява типу MyClass::className.


1
Не могли б ви навести конкретний приклад, коли це може бути корисним у php? Якщо ви жорстко закодували назву класу - ви можете обернути його в лапки і отримати те, що хочете.
zerkms

2
На жаль, автоматичні рефакторинги (наприклад, в середовищах розробки), такі як RenameClass, як правило, не перейменовують такі рядки імен класів. Тому було б непогано мати якийсь статичний спосіб отримати назву класу, крім того, щоб public $__CLASS__ = __CLASS__;танцювати з усіма іншими класами ...
EricSchaefer

Відповіді:


114

Починаючи з PHP 5.5, ви можете використовувати дозвіл імен класів через ClassName :: class .

Дивіться нові функції PHP5.5 .

<?php

namespace Name\Space;

class ClassName {}

echo ClassName::class;

?>

Якщо ви хочете використовувати цю функцію у своєму методі класу, використовуйте static :: class :

<?php

namespace Name\Space;

class ClassName {
   /**
    * @return string
    */
   public function getNameOfClass()
   {
      return static::class;
   }
}

$obj = new ClassName();
echo $obj->getNameOfClass();

?>

Для старих версій PHP ви можете використовувати get_class () .


5
Яка різниця між static::classі get_class_name()?
Alexander Jank

1
@AlexanderJank Здається, ніби static::classвирішується під час компіляції, а get_class_name()інтерпретується під час виконання. Я дізнався про це, намагаючись отримати доступ до :: класу властивості динамічно згенерований класу і отримати наступне повідомлення про помилку (?): Dynamic class names are not allowed in compile-time ::class fetch. Докладніше див. У цій відповіді . Я також знайшов цю примітку з документації корисною.
cjsimon

29

Ви можете використовувати __CLASS__всередині класу, щоб отримати ім’я.

http://php.net/manual/en/language.constants.predefined.php


3
Ви також можете подивитися тут, щоб переглянути всі цікаві const: php.net/manual/en/language.constants.predefined.php
MatRt

Дякую @Brad за посилання, я знаходжу тут
Резан Ахмад

2
@ user1073122, Це посилання, на яке я посилався у своїй відповіді.
Бред

+1, оскільки я намагався отримати ім’я класу в методі, визначеному в батьківському класі. Інші рішення ( get_class($this), static::class) просто повертають ім’я класу дочірнього (що розширює батьківський).
акінурі

Продовження : self::classтакож, схоже, повертає ім'я батьківського класу.
Акінурі

22

Схоже, ви відповіли на власне запитання. get_classдасть вам назву класу. Це процедурно, і, можливо, саме це спричиняє плутанину. Погляньте на документацію до php дляget_class

Ось їх приклад:

 <?php

 class foo 
 {
     function name()
     {
         echo "My name is " , get_class($this) , "\n";
     }
 }

 // create an object
 $bar = new foo();

 // external call
 echo "Its name is " , get_class($bar) , "\n"; // It's name is foo

 // internal call
 $bar->name(); // My name is foo

Щоб зробити його більш схожим на ваш приклад, ви можете зробити щось на зразок:

 <?php

 class MyClass
 {
       public static function getClass()
       {
            return get_class();
       }
 }

Тепер ви можете зробити:

 $className = MyClass::getClass();

Однак це дещо обмежено, оскільки, якщо мій клас буде розширено, він все одно поверне "MyClass". get_called_classНатомість ми можемо використовувати відносно нову функцію , яка спирається на пізнє статичне прив’язування та вимагає PHP> = 5,3.

<?php

class MyClass
{
    public static function getClass()
    {
        return get_called_class();
    }

    public static function getDefiningClass()
    {
        return get_class();
    }
}

class MyExtendedClass extends MyClass {}

$className = MyClass::getClass(); // 'MyClass'
$className = MyExtendedClass::getClass(); // 'MyExtendedClass'
$className = MyExtendedClass::getDefiningClass(); // 'MyClass'

Дякую @ J.Money за ідею .. Але це не працює у спадок.
Резан Ахмад

11

Тепер я маю відповідь на свою проблему. Дякую Бреду за посилання, я знайшов відповідь тут . І дякую J.Money за ідею. Моє рішення:

<?php

class Model
{
    public static function getClassName() {
        return get_called_class();
    }
}

class Product extends Model {}

class User extends Model {}

echo Product::getClassName(); // "Product" 
echo User::getClassName(); // "User" 

3
Це не має сенсу. FooBar::getClassName()є завжди 'FooBar'. Якщо ви могли набирати текст Product::getClassName()- тоді ви можете набирати текст 'Product'замість цього.
zerkms

7
Так, я знаю .. Я хочу уникати друкарської помилки, а також при повторному розкладі назви класу (за допомогою інструментів IDE) мені не потрібно шукати та замінювати рядок.
Резан Ахмад

Це також може допомогти, якщо вам потрібно використовувати ім'я класу дочірнього класу в батьківському класі "Модель".
Дж. Р. Лоухорн

8

Щоб отримати назву класу, ви можете використовувати ReflectionClass

class MyClass {
    public function myNameIs(){
        return (new \ReflectionClass($this))->getShortName();
    }
}

Хоча цей фрагмент коду може бути рішенням, включаючи пояснення, він дійсно допомагає поліпшити якість вашої публікації. Пам'ятайте, що ви будете відповідати на запитання для читачів у майбутньому, і ці люди можуть не знати причин вашої пропозиції коду.
yivi

Абсолютно Спеціально !!! Це СУПЕР, але просте рішення! Слава !!!!
Сімоне Кампанья

4

Схоже ReflectionClass, це досить продуктивний варіант.

class MyClass {
    public function test() {
        // 'MyClass'
        return (new \ReflectionClass($this))->getShortName();
    }
}

Тест:

Method Name      Iterations    Average Time      Ops/second
--------------  ------------  --------------    -------------
testExplode   : [10,000    ] [0.0000020221710] [494,518.01547]
testSubstring : [10,000    ] [0.0000017177343] [582,162.19968]
testReflection: [10,000    ] [0.0000015984058] [625,623.34059]

3

Я думаю, що важливо згадати невелику різницю між "self" і "static" у PHP, оскільки "найкраща відповідь" використовує "static", що може дати заплутаний результат для деяких людей.

<?php
class X {
    function getStatic() {
        // gets THIS class of instance of object
        // that extends class in which is definied function
        return static::class;
    }
    function getSelf() {
        // gets THIS class of class in which function is declared
        return self::class;
    }
}

class Y extends X {
}
class Z extends Y {
}

$x = new X();
$y = new Y();
$z = new Z();

echo 'X:' . $x->getStatic() . ', ' . $x->getSelf() . 
    ', Y: ' . $y->getStatic() . ', ' . $y->getSelf() . 
    ', Z: ' . $z->getStatic() . ', ' . $z->getSelf();

Результати:

X: X, X
Y: Y, X
Z: Z, X

2

end(preg_split("#(\\\\|\\/)#", Class_Name::class))

Class_Name::class: повернути клас із простором імен. Тож після того, як вам потрібно буде лише створити масив, отримайте останнє значення масиву.


0
<?php
namespace CMS;
class Model {
  const _class = __CLASS__;
}

echo Model::_class; // will return 'CMS\Model'

для старших за PHP 5.5


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.