Làm cách nào để lấy tên lớp trong PHP?


99
public class MyClass {

}

Trong Java, chúng ta có thể lấy tên lớp bằng String className = MyClass.class.getSimpleName();

Làm thế nào để làm điều này trong PHP? Tôi đã biết get_class(), nhưng nó chỉ hoạt động cho các đối tượng. Hiện tại tôi làm việc trong Active Record. Tôi cần tuyên bố như thế nào MyClass::className.


1
Bạn có thể đưa ra một ví dụ cụ thể khi nó có thể hữu ích trong php? Nếu bạn đã mã hóa cứng tên lớp - bạn có thể đặt nó trong dấu ngoặc kép và nhận được những gì bạn muốn.
zerkms

2
Thật không may, tự động tái cấu trúc (ví dụ như trong IDE) như RenameClass thường không đổi tên các chuỗi tên lớp như vậy. Do đó nó sẽ được tốt đẹp để có một số loại đường tĩnh để có được tên lớp, ngoài việc thực hiện các public $__CLASS__ = __CLASS__;điệu nhảy với tất cả các lớp khác ...
EricSchaefer

Câu trả lời:


114

Kể từ PHP 5.5, bạn có thể sử dụng độ phân giải tên lớp thông qua ClassName :: class .

Xem các tính năng mới của PHP5.5 .

<?php

namespace Name\Space;

class ClassName {}

echo ClassName::class;

?>

Nếu bạn muốn sử dụng tính năng này trong phương thức lớp của mình, hãy sử dụng static :: class :

<?php

namespace Name\Space;

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

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

?>

Đối với các phiên bản PHP cũ hơn , bạn có thể sử dụng get_class () .


5
Sự khác biệt giữa static::classvà là get_class_name()gì?
Alexander Jank

1
@AlexanderJank Có vẻ như static::classđược giải quyết trong thời gian biên dịch trong khi get_class_name()được thông dịch trong thời gian chạy. Tôi thấy điều này ra bằng cách cố gắng để truy cập :: lớp tài sản của một lớp học tạo động và nhận được lỗi sau (?): Dynamic class names are not allowed in compile-time ::class fetch. Xem câu trả lời này để biết thêm chi tiết. Tôi cũng thấy ghi chú này từ tài liệu hữu ích.
cjsimon

29

Bạn có thể sử dụng __CLASS__trong một lớp để lấy tên.

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


3
bạn cũng có thể có một cái nhìn vào đây để xem tất cả const thú vị: php.net/manual/en/language.constants.predefined.php
MatRt

Cảm ơn @Brad về liên kết, tôi tìm thấy câu trả lời ở đây
Rezan Achmad

2
@ user1073122, Đó là liên kết mà tôi đã liên kết đến trong câu trả lời của mình.
Brad

+1 khi tôi đang cố gắng lấy tên lớp trong một phương thức được xác định trong lớp cha. Các giải pháp khác ( get_class($this), static::class) chỉ đơn giản trả về tên lớp con (mở rộng tên lớp cha).
akinuri

tiếp tục : self::class, cũng, dường như để trả lại tên lớp cha mẹ.
akinuri

22

Có vẻ như bạn đã trả lời câu hỏi của chính mình. get_classsẽ giúp bạn có được tên lớp. Đó là thủ tục và có thể đó là những gì đang gây ra sự nhầm lẫn. Hãy xem tài liệu php choget_class

Đây là ví dụ của họ:

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

Để làm cho nó giống với ví dụ của bạn hơn, bạn có thể làm điều gì đó như:

 <?php

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

Bây giờ bạn có thể làm:

 $className = MyClass::getClass();

Tuy nhiên, điều này có phần hạn chế, bởi vì nếu lớp học của tôi được mở rộng, nó vẫn sẽ trả về 'MyClass'. get_called_classThay vào đó, chúng ta có thể sử dụng tính năng này dựa trên Late Static Binding , một tính năng tương đối mới và yêu cầu 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'

Cảm ơn @ J.Money về ý tưởng .. Nhưng nó không hoạt động trong kế thừa.
Rezan Achmad

11

Bây giờ, tôi đã có câu trả lời cho vấn đề của mình. Cảm ơn Brad về liên kết, tôi tìm thấy câu trả lời ở đây . Và cảm ơn J.Money về ý tưởng. Giải pháp của tôi:

<?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
Không có nghĩa lý gì. FooBar::getClassName()luôn luôn 'FooBar'. Nếu bạn có thể nhập Product::getClassName()- thì bạn cũng có thể nhập 'Product'thay thế.
zerkms

7
Vâng, tôi biết .. Tôi muốn tránh lỗi đánh máy và cũng như khi tính toán lại tên lớp (bằng các công cụ IDE), tôi không cần phải tìm kiếm và thay thế chuỗi.
Rezan Achmad

Điều này cũng có thể hữu ích nếu bạn cần sử dụng tên lớp của lớp con trong lớp cha "Model".
JR Lawhorne

8

Để lấy tên lớp, bạn có thể sử dụng ReflectionClass

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

Mặc dù đoạn mã này có thể là giải pháp, nhưng bao gồm phần giải thích thực sự giúp cải thiện chất lượng bài đăng của bạn. Hãy nhớ rằng bạn đang trả lời câu hỏi cho người đọc trong tương lai và những người đó có thể không biết lý do cho đề xuất mã của bạn.
yivi

Hoàn toàn đặc biệt !!! Đây là một giải pháp SIÊU nhưng đơn giản! Cảm ơn !!!!
Simone Campagna

4

Có vẻ như đây ReflectionClasslà một lựa chọn khá hiệu quả.

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

Điểm chuẩn:

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

Tôi nghĩ điều quan trọng là phải đề cập đến sự khác biệt nhỏ giữa 'self' và 'static' trong PHP vì 'câu trả lời tốt nhất' sử dụng 'static' có thể mang lại kết quả khó hiểu cho một số người.

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

Các kết quả:

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

2

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

Class_Name::class: trả về lớp có không gian tên. Vì vậy, sau khi bạn chỉ cần tạo một mảng, sau đó lấy giá trị cuối cùng của mảng.


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

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

cho PHP cũ hơn 5.5


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.