public class MyClass {
}
In Java, we can get class name with String className = MyClass.class.getSimpleName();
How to do this in PHP? I already know get_class(), but it works only for objects. Currently I work in Active Record. I need statement like MyClass::className.
Since PHP 5.5 you can use class name resolution via ClassName::class.
See new features of PHP5.5.
<?php
namespace Name\Space;
class ClassName {}
echo ClassName::class;
?>
If you want to use this feature in your class method use static::class:
<?php
namespace Name\Space;
class ClassName {
/**
* #return string
*/
public function getNameOfClass()
{
return static::class;
}
}
$obj = new ClassName();
echo $obj->getNameOfClass();
?>
For older versions of PHP, you can use get_class().
You can use __CLASS__ within a class to get the name.
http://php.net/manual/en/language.constants.predefined.php
It sounds like you answered your own question. get_class will get you the class name. It is procedural and maybe that is what is causing the confusion. Take a look at the php documentation for get_class
Here is their example:
<?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
To make it more like your example you could do something like:
<?php
class MyClass
{
public static function getClass()
{
return get_class();
}
}
Now you can do:
$className = MyClass::getClass();
This is somewhat limited, however, because if my class is extended it will still return 'MyClass'. We can use get_called_class instead, which relies on Late Static Binding, a relatively new feature, and requires 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'
It looks like ReflectionClass is a pretty productive option.
class MyClass {
public function test() {
// 'MyClass'
return (new \ReflectionClass($this))->getShortName();
}
}
Benchmark:
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]
To get class name you can use ReflectionClass
class MyClass {
public function myNameIs(){
return (new \ReflectionClass($this))->getShortName();
}
}
Now, I have answer for my problem. Thanks to Brad for the link, I find the answer here. And thanks to J.Money for the idea. My solution:
<?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"
I think it's important to mention little difference between 'self' and 'static' in PHP as 'best answer' uses 'static' which can give confusing result to some people.
<?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();
Results:
X: X, X
Y: Y, X
Z: Z, X
This will return pure class name even when using namespace:
echo substr(strrchr(__CLASS__, "\\"), 1);
end(preg_split("#(\\\\|\\/)#", Class_Name::class))
Class_Name::class: return the class with the namespace. So after you only need to create an array, then get the last value of the array.
From PHP 8.0, you can use ::class even on objects:
$object = new \SplPriorityQueue();
assert($object::class === \SplPriorityQueue::class);
<?php
namespace CMS;
class Model {
const _class = __CLASS__;
}
echo Model::_class; // will return 'CMS\Model'
for older than PHP 5.5
Related
public class MyClass {
}
In Java, we can get class name with String className = MyClass.class.getSimpleName();
How to do this in PHP? I already know get_class(), but it works only for objects. Currently I work in Active Record. I need statement like MyClass::className.
Since PHP 5.5 you can use class name resolution via ClassName::class.
See new features of PHP5.5.
<?php
namespace Name\Space;
class ClassName {}
echo ClassName::class;
?>
If you want to use this feature in your class method use static::class:
<?php
namespace Name\Space;
class ClassName {
/**
* #return string
*/
public function getNameOfClass()
{
return static::class;
}
}
$obj = new ClassName();
echo $obj->getNameOfClass();
?>
For older versions of PHP, you can use get_class().
You can use __CLASS__ within a class to get the name.
http://php.net/manual/en/language.constants.predefined.php
It sounds like you answered your own question. get_class will get you the class name. It is procedural and maybe that is what is causing the confusion. Take a look at the php documentation for get_class
Here is their example:
<?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
To make it more like your example you could do something like:
<?php
class MyClass
{
public static function getClass()
{
return get_class();
}
}
Now you can do:
$className = MyClass::getClass();
This is somewhat limited, however, because if my class is extended it will still return 'MyClass'. We can use get_called_class instead, which relies on Late Static Binding, a relatively new feature, and requires 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'
It looks like ReflectionClass is a pretty productive option.
class MyClass {
public function test() {
// 'MyClass'
return (new \ReflectionClass($this))->getShortName();
}
}
Benchmark:
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]
To get class name you can use ReflectionClass
class MyClass {
public function myNameIs(){
return (new \ReflectionClass($this))->getShortName();
}
}
Now, I have answer for my problem. Thanks to Brad for the link, I find the answer here. And thanks to J.Money for the idea. My solution:
<?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"
I think it's important to mention little difference between 'self' and 'static' in PHP as 'best answer' uses 'static' which can give confusing result to some people.
<?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();
Results:
X: X, X
Y: Y, X
Z: Z, X
This will return pure class name even when using namespace:
echo substr(strrchr(__CLASS__, "\\"), 1);
end(preg_split("#(\\\\|\\/)#", Class_Name::class))
Class_Name::class: return the class with the namespace. So after you only need to create an array, then get the last value of the array.
From PHP 8.0, you can use ::class even on objects:
$object = new \SplPriorityQueue();
assert($object::class === \SplPriorityQueue::class);
<?php
namespace CMS;
class Model {
const _class = __CLASS__;
}
echo Model::_class; // will return 'CMS\Model'
for older than PHP 5.5
I've found that by using ::class, I can get the fully qualified class name of a namespaced class:
namespace NameSpace {
class Foo { }
echo Foo::class;
}
// echoes 'NameSpace\Foo'
But I can't figure out a way to do this with a variable class name. Trying to treat the class keyword like a static property doesn't seem to work:
namespace NameSpace {
class Foo { }
$className = 'Foo';
echo $className::class;
}
// Parse error: syntax error, unexpected 'class'
Does anyone know if its possible to get the fully qualified class name dynamically like I'm trying to?
I want to be able to do this with classes from outside the current namespace:
namespace ReallyLongHardToWriteNameSpace {
class Foo { }
}
namespace NameSpace {
use ReallyLongHardToWriteNameSpace\Foo;
class Bar { }
echo Foo::class; // echoes 'ReallyLongHardToWriteNameSpace\Foo'
echo Bar::class; // echoes 'NameSpace\Bar'
foreach (['Foo', 'Bar'] as $className) {
echo $className::class; // Parse error: syntax error, unexpected 'class'
}
}
You can use get_class with an instance of that class:
<?php
namespace NS {
class Foo { }
$className = "\\NS\\Foo";
echo get_class(new $className);
}
// prints NS\Foo
Do note that to create an instance of the class I had to use the FQN in the string, so it might not be useful at all.
Ok, I came up with another solution. Even tho this is somewhat different.
namespace NameSpace;
class Foo {
public static function getFullName() {
return __CLASS__;
}
}
print Foo::getFullName(); // Prints NameSpace\Foo
Just create a abstract class which has getFullName() as method and inherit from it on all classes you want to be able to return full name.
Simplest approch (I almost forgot) is the use of get_class()
$className = get_class($yourClassObject); // returns NameSpace\Foo
You can also try using eval() for this.
$className = 'NameSpace\Foo::class';
eval('$fullName = ' . $className);
print $fullName; // returns NameSpace\Foo
Even tho, this might not be exactly what you want, but you should look at the Reflection library. Its very handy to use for such things.
// Lets say you have an object of your class
$object = new ReflectionObject($yourObject);
$name = $object->getName(); // will return NameSpace\Foo
// You can also give the class name to it
$class = new ReflectionClass('Foo');
$name = $class->getName(); // also returns NameSpace\Foo
Look here for more information
There are also classes for methods, properties, etc.
You can use __NAMESPACE__ to get the current namespace, then just prepend that to the string that contains the class name.
namespace NS {
class Foo {
}
$className = 'Foo';
echo __NAMESPACE__ . '\\' . $className;
}
In php you often check if the object you get is of the correct type. If not you throw an exception with a message like this:
use My\Class\MyClass
...
if (!$object instanceof MyClass) {
throw new Exception(
sprintf(
"object must be of type '%s'",
'My\Class\MyClass'
)
);
}
Right now I pass the full namespace and the name of the class in a string to sprintf.
How can I get this from the class reference so that i can do something like this
sprintf("object must be of type '%s'", MyClass::getName())
EDIT:
I would like to achieve this for all classes without adding new methods. So it should be a solution using some existing method or one of the php __ MAGIC__ methods.
As of php 5.5 there's a magic constant that gives you the FQCN of any class. You can use it like this:
namespace My\Long\Namespace\Foo\Bar;
MyClass::class;
// will return "My\Long\Namespace\Foo\Bar\MyClass"
It's documented on the new features page.
namespace test;
class a {
public function getname()
{
return __CLASS__;
}
}
And:
$a = new a();
echo $a->getname(); //
Outputs
test\a
Static method works same way:
public static function getname()
{
return __CLASS__;
}
...
a::getname(); // test\a
You can also get only namespace with __NAMESPACE__
Update:
you can you ReflectionClass for same thing:
$a = new a();
$r = new \ReflectionClass($a);
echo $r->getName(); // test\a
you can create ClassHelper class to have it for using anywhere you need it easily:
class ClassHelper
{
public static function getFullQualifiedName($object)
{
$rc = new \ReflectionClass($object);
return $rc->getName();
}
}
And use it:
echo ClassHelper::getFullQualifiedName($a); // test\a
Finnaly: if you use php 5.6 and above (for future), you can work with class constant
echo a::class; // test\a
I'm trying to namespace my plugin functions by using a class and static functions. I'm getting the error:
Fatal error: Constructor Read_Time::read_time() cannot be static in /Applications/MAMP/htdocs/Wordpress/wp-content/plugins/readtime/readtime.php on line 41
class Read_Time {
public $options;
static public function init() {
add_filter('wp_meta', __CLASS__ . '::post_text');
}
static private function post_text() {
if(is_single()) {
global $post;
$content = $post->post_content;
echo("<h1>" . self::read_time($content) . "</h1>");
}
}
static private function word_count($to_count) {
return str_word_count($to_count);
}
static private function read_time($content) {
$wpm = 200;
$int_minutes = ceil( self::word_count($content) / $wpm );
if($int_minutes == 1) {
return $int_minutes . " minute";
}
else {
return $int_minutes . " minutes";
}
}
}
add_action('init', 'Read_Time::init');
Can someone tell me what I'm doing wrong?
PHP is interpreting your method read_time as a constructor for the class Read_Time, because it is not case-sensitive. The constructor cannot be static.
From the online documentation:
As of PHP 5.3.3, methods with the same name as the last element of a namespaced class name will no longer be treated as constructor. This change doesn't affect non-namespaced classes.
Example #2 Constructors in namespaced classes
<?php
namespace Foo;
class Bar {
public function Bar() {
// treated as constructor in PHP 5.3.0-5.3.2
// treated as regular method as of PHP 5.3.3
}
}
?>
P.S. If you really are using a version of PHP < 5.3.3, you should strongly consider upgrading. A lot has changed, and older versions may have unpatched bugs.
I'm looking for the get_called_class() equivalent for __FILE__ ... Maybe something like get_included_file()?
I have a set of classes which would like to know what directory they exist in. Something like this:
<?php
class A {
protected $baseDir;
public function __construct() {
$this->baseDir = dirname(__FILE__);
}
public function getBaseDir() {
return $this->baseDir;
}
}
?>
And in some other file, in some other folder...
<?php
class B extends A {
// ...
}
class C extends B {
// ...
}
$a = new A;
echo $a->getBaseDir();
$b = new B;
echo $b->getBaseDir();
$c = new C;
echo $c->getBaseDir();
// Annnd... all three return the same base directory.
?>
Now, I could do something ghetto, like adding $this->baseDir = dirname(__FILE__) to each and every extending class, but that seems a bit... ghetto. After all, we're talking about PHP 5.3, right? Isn't this supposed to be the future?
Is there another way to get the path to the file where a class was declared?
ReflectionClass::getFileName
Have you tried assigning it as a static member of the class?
<?php
class Blah extends A {
protected static $filename = __FILE__;
}
(Untested, and statics plus class inheritance becomes very fun...)
what if you don't use __FILE__ but a separate variable and set the variable to __FILE__ in each class
class A {
protected static $baseDir;
protected $filename = __FILE__; // put this in every file
public function __construct() {
}
public function getBaseDir() {
return dirname($this->filename) . '<br>'; // use $filename instead of __FILE__
}
}
require('bdir/b.php');
require('cdir/c.php');
class B extends A {
protected $filename = __FILE__; // put this in every file
}
$a = new A;
echo $a->getBaseDir();
$b = new B;
echo $b->getBaseDir();
$c = new C;
echo $c->getBaseDir();
you still have to redeclare the property in each class, but not the method
You could use debug_backtrace(). You probably don't want to, though.
Tested:
protected static $filename = __FILE__;
static::$filename
Doesn't work.
It looks like the constant is registered when the class is loaded which is not "late".
Not sure it was possible before, but what was best for me today is using reflection :
$basePath = new \ReflectionObject($this);
$dir = dirname($basePath->getFileName());