Jak uzyskać nazwę klasy w PHP?

100
public class MyClass {

}

W Javie możemy uzyskać nazwę klasy za pomocą String className = MyClass.class.getSimpleName();

Jak to zrobić w PHP? Już wiem get_class(), ale działa tylko dla obiektów. Obecnie pracuję w Active Record. Potrzebuję oświadczenia w stylu MyClass::className.

Rezan Achmad
źródło
1
Czy mógłbyś podać konkretny przykład, kiedy może być pomocny w PHP? Jeśli wpisałeś nazwę klasy na stałe - możesz zawinąć ją w cudzysłów i dostać to, czego chcesz.
zerkms
2
Niestety automatyczne refaktoryzacje (np. W IDE), takie jak RenameClass, zwykle nie zmieniają nazw takich ciągów nazw klas. Dlatego byłoby miło mieć jakiś statyczny sposób na uzyskanie nazwy klasy, oprócz wykonywania public $__CLASS__ = __CLASS__;tańca z każdą inną klasą ...
EricSchaefer

Odpowiedzi:

115

Od PHP 5.5 możesz używać rozwiązywania nazw klas poprzez ClassName :: class .

Zobacz nowe funkcje PHP5.5 .

<?php

namespace Name\Space;

class ClassName {}

echo ClassName::class;

?>

Jeśli chcesz użyć tej funkcji w swojej metodzie klasowej, użyj static :: class :

<?php

namespace Name\Space;

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

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

?>

W przypadku starszych wersji PHP możesz użyć metody get_class () .

Boazeria
źródło
5
Jaka jest różnica między static::classi get_class_name()?
Alexander Jank
1
@AlexanderJank Wygląda na static::classto, że problem został rozwiązany podczas kompilacji, podczas gdy get_class_name()jest interpretowany w czasie wykonywania. Znalazłem to przez próby dostępu do :: klasę właściwość dynamicznie generowanej klasy i otrzymuję następujący błąd (?) Dynamic class names are not allowed in compile-time ::class fetch. Zobacz tę odpowiedź, aby uzyskać więcej informacji. Również ta notatka z dokumentów była pomocna.
cjsimon
29

Możesz użyć __CLASS__w klasie, aby uzyskać nazwę.

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

Ćwiek
źródło
3
możesz również zajrzeć tutaj, aby wyświetlić wszystkie interesujące const: php.net/manual/en/language.constants.predefined.php
MatRt,
Dzięki @Brad za link, odpowiedź znajduję tutaj
Rezan Achmad
2
@ user1073122, to jest link, do którego umieściłem link w mojej odpowiedzi.
Brad
+1, ponieważ próbowałem uzyskać nazwę klasy w metodzie zdefiniowanej w klasie nadrzędnej. Inne rozwiązania ( get_class($this), static::class) po prostu zwracają nazwę klasy podrzędnej (rozszerzającej klasę nadrzędną).
akinuri
ciąg dalszy : self::classwydaje się również zwracać nazwę klasy nadrzędnej.
akinuri
23

Wygląda na to, że odpowiedziałeś na własne pytanie. get_classpoda Ci nazwę klasy. Jest to proceduralne i być może to właśnie powoduje zamieszanie. Zapoznaj się z dokumentacją php dotyczącąget_class

Oto ich przykład:

 <?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

Aby bardziej przypominać Twój przykład, możesz zrobić coś takiego:

 <?php

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

Teraz możesz:

 $className = MyClass::getClass();

Jest to jednak nieco ograniczone, ponieważ jeśli moja klasa zostanie rozszerzona, nadal będzie zwracać „MyClass”. get_called_classZamiast tego możemy użyć funkcji Late Static Binding , która jest stosunkowo nową funkcją i wymaga 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'
Żaden
źródło
Dzięki @ J.Money za pomysł .. Ale to nie działa w przypadku dziedziczenia.
Rezan Achmad
11

Teraz mam odpowiedź na mój problem. Dzięki Bradowi za link, odpowiedź znajduję tutaj . Dziękuję J.Money za pomysł. Moje rozwiązanie:

<?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" 
Rezan Achmad
źródło
3
To nie ma sensu. FooBar::getClassName()jest zawsze 'FooBar'. Gdybyś mógł pisać Product::getClassName()- możesz też 'Product'zamiast tego pisać .
zerkms
7
Tak, wiem ... Chcę uniknąć literówek, a także przy ponownym rozkładaniu nazwy klasy (za pomocą narzędzi IDE), nie muszę wyszukiwać i zamieniać ciągu.
Rezan Achmad
Może to również pomóc, jeśli musisz użyć nazwy klasy podrzędnej w nadrzędnej klasie „Model”.
JR Lawhorne
9

Aby uzyskać nazwę klasy, możesz użyć ReflectionClass

class MyClass {
    public function myNameIs(){
        return (new \ReflectionClass($this))->getShortName();
    }
}
Omar Makled
źródło
Chociaż ten fragment kodu może być rozwiązaniem, dołączenie wyjaśnienia naprawdę pomaga poprawić jakość Twojego posta. Pamiętaj, że odpowiadasz na pytanie do czytelników w przyszłości, a osoby te mogą nie znać powodów, dla których zaproponowałeś kod.
yivi
Absolutnie wyjątkowy !!! To SUPER, ale proste rozwiązanie! Dzięki !!!!
Simone Campagna
4

Wygląda na to, że ReflectionClassjest to całkiem produktywna opcja.

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

Reper:

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]

Илья Зеленько
źródło
3

Myślę, że ważne jest, aby wspomnieć o niewielkiej różnicy między „własnym” a „statycznym” w PHP, ponieważ „najlepsza odpowiedź” wykorzystuje słowo „statyczne”, co może niektórym wydawać się mylące.

<?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();

Wyniki:

X: X, X
Y: Y, X
Z: Z, X
JerzySkalski
źródło
2

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

Class_Name::class: zwraca klasę z przestrzenią nazw. Więc po utworzeniu tylko tablicy, pobierz ostatnią wartość tablicy.

ZadzwońMarl
źródło
0
<?php
namespace CMS;
class Model {
  const _class = __CLASS__;
}

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

dla starszych niż PHP 5.5

23Pstars
źródło
0
echo substr(strrchr(__CLASS__, "\\"), 1);    
Lukas Correa
źródło