Как мне получить имя класса в PHP?

100
public class MyClass {

}

В Java мы можем получить имя класса с помощью String className = MyClass.class.getSimpleName();

Как это сделать в PHP? Я уже знаю get_class(), но это работает только для объектов. В настоящее время работаю в Active Record. Мне нужно заявление вроде MyClass::className.

Резан Ахмад
источник
1
Не могли бы вы привести конкретный пример, когда это может быть полезно на php? Если вы жестко запрограммировали имя класса - вы можете заключить его в кавычки и получить то, что хотите.
zerkms
2
К сожалению, при автоматическом рефакторинге (например, в IDE), таком как RenameClass, такие строки имен классов обычно не переименовываются. Поэтому было бы неплохо иметь какой-то статический способ получить имя класса, помимо public $__CLASS__ = __CLASS__;танца с каждым другим классом ...
Эрик Шефер 01

Ответы:

115

Начиная с 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()?
Александр Янк
1
@AlexanderJank Кажется, что static::classразрешается во время компиляции, а get_class_name()интерпретируется во время выполнения. Я узнал об этом, пытаясь получить доступ к :: класса свойства динамически сгенерированный класса и получить следующее сообщение об ошибке (?): Dynamic class names are not allowed in compile-time ::class fetch. См. Этот ответ для получения более подробной информации. Я также нашел эту заметку из документации полезной.
cjsimon
30

Вы можете использовать __CLASS__внутри класса, чтобы получить имя.

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

Брэд
источник
3
вы также можете посмотреть здесь все интересные константы
MatRt,
Спасибо @Brad за ссылку, я нахожу ответ здесь
Резан Ахмад
2
@ user1073122, это ссылка, на которую я указал в своем ответе.
Брэд
+1, поскольку я пытался получить имя класса в методе, который определен в родительском классе. Другие решения ( get_class($this), static::class) просто возвращают имя дочернего (расширяющего родительский) класс.
akinuri
продолжение : self::classтакже, похоже, возвращает имя родительского класса.
akinuri
23

Похоже, вы ответили на свой вопрос. 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) мне не нужно искать и заменять строку.
Резан Ахмад
Это также может помочь, если вам нужно использовать имя класса дочернего класса в родительском классе «Модель».
JR Lawhorne,
9

Чтобы получить имя класса, вы можете использовать ReflectionClass

class MyClass {
    public function myNameIs(){
        return (new \ReflectionClass($this))->getShortName();
    }
}
Омар Маклед
источник
Хотя этот фрагмент кода может быть решением, включение объяснения действительно помогает улучшить качество вашего сообщения. Помните, что вы отвечаете на вопрос читателей в будущем, и эти люди могут не знать причин вашего предложения кода.
yivi
Совершенно особенный !!! Это СУПЕР, но простое решение! Спасибо !!!!
Simone Campagna
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: вернуть класс с пространством имен. Итак, после того, как вам нужно только создать массив, получите последнее значение массива.

CallMarl
источник
0
<?php
namespace CMS;
class Model {
  const _class = __CLASS__;
}

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

для версий старше PHP 5.5

23Пзвезды
источник
0
echo substr(strrchr(__CLASS__, "\\"), 1);    
Лукас Корреа
источник