ฉันจะได้ชื่อคลาสใน PHP ได้อย่างไร


103
public class MyClass {

}

ใน Java เราสามารถรับชื่อคลาสด้วย String className = MyClass.class.getSimpleName();

วิธีการทำใน PHP? ฉันรู้แล้วget_class()แต่มันใช้ได้กับวัตถุเท่านั้น ขณะนี้ฉันทำงานใน Active Record ฉันต้องการคำสั่งเช่นMyClass::className.


1
คุณช่วยยกตัวอย่างเฉพาะเมื่อมันอาจเป็นประโยชน์ใน php ได้หรือไม่? หากคุณได้เข้ารหัสชื่อคลาสไว้อย่างถาวรคุณสามารถใส่เครื่องหมายอัญประกาศและรับสิ่งที่คุณต้องการได้
zerkms

2
น่าเสียดายที่การ refactor อัตโนมัติ (เช่นใน IDE) เช่น RenameClass มักจะไม่เปลี่ยนชื่อสตริงชื่อคลาสดังกล่าว ดังนั้นคงจะดีหากมีวิธีคงที่ในการตั้งชื่อชั้นนอกจากการpublic $__CLASS__ = __CLASS__;เต้นกับชั้นเรียนอื่น ๆ ...
EricSchaefer

คำตอบ:


119

ตั้งแต่ PHP 5.5คุณสามารถใช้ความละเอียดชื่อชั้นผ่านClassName :: ระดับ

ดูคุณสมบัติใหม่ของ 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

30

คุณสามารถใช้__CLASS__ภายในคลาสเพื่อรับชื่อ

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


3
คุณสามารถดูที่นี่เพื่อดู const ที่น่าสนใจทั้งหมด: php.net/manual/en/language.constants.predefined.php
MatRt

ขอบคุณ @Brad สำหรับลิงค์ฉันพบคำตอบที่นี่
Rezan Achmad

2
@ user1073122 นั่นคือลิงค์ที่ฉันเชื่อมโยงไปในคำตอบของฉัน
Brad

+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แทนได้ซึ่งอาศัยLate Static Bindingซึ่งเป็นคุณสมบัติที่ค่อนข้างใหม่และต้องใช้ 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 สำหรับแนวคิด .. แต่มันไม่ได้เป็นมรดก
Rezan Achmad

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" 

4
มันไม่มีเหตุผล อยู่เสมอFooBar::getClassName() 'FooBar'หากคุณสามารถพิมพ์Product::getClassName()- คุณสามารถพิมพ์'Product'แทนได้เช่นกัน
zerkms

7
ใช่ฉันรู้ .. ฉันต้องการหลีกเลี่ยงการพิมพ์ผิดและเมื่อทำการแฟ็กซ์ชื่อคลาสอีกครั้ง (ด้วยเครื่องมือ IDE) ฉันไม่จำเป็นต้องค้นหาและแทนที่สตริง
Rezan Achmad

นอกจากนี้ยังสามารถช่วยได้หากคุณจำเป็นต้องใช้ชื่อคลาสของคลาสย่อยในคลาส "Model" หลัก
JR Lawhorne

9

ในการรับชื่อคลาสคุณสามารถใช้ ReflectionClass

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

แม้ว่าข้อมูลโค้ดนี้อาจเป็นวิธีแก้ปัญหา แต่การมีคำอธิบายจะช่วยปรับปรุงคุณภาพของโพสต์ของคุณได้มาก โปรดจำไว้ว่าคุณกำลังตอบคำถามสำหรับผู้อ่านในอนาคตและบุคคลเหล่านั้นอาจไม่ทราบสาเหตุของการแนะนำโค้ดของคุณ
yivi

พิเศษสุด !!! นี่เป็นวิธีแก้ปัญหาที่ยอดเยี่ยม แต่เรียบง่าย! ขอบคุณ !!!!
Simone Campagna

5

ดูเหมือนว่า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


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.