I have trouble accessing a constant of a class via the object operator(->).
I have these 2 classes:
class withConstant {
const MY_CONSTANT = 5;
}
class usingConstant {
public $class = null;
function __construct() {
$this->class = new withConstant();
}
}
When I do this:
$myClass = new usingConstant();
echo $myClass->class::MY_CONSTANT;
I get an error Parse error: syntax error, unexpected '::' (T_PAAMAYIM_NEKUDOTAYIM). However, I can get around it with this:
$myClass = new usingConstant();
$myClass = &$myClass->class;
echo $myClass::MY_CONSTANT;
I prefer to access the constant without assigning the member variable to another variable first.
This is the closest I can come to what you're actually after achieving unfortunately:
echo constant(get_class($myClass->class).'::MY_CONSTANT');
Note that this is incredibly inefficient, since it looks up the class to determine it's name, then looks it up again to reference the constant.
You can make a getter function in withConstant and call that.
class withConstant {
const MY_CONSTANT = 5;
function getConstant(){
return self::MY_CONSTANT;
}
}
Then you can call that function:
$myClass = new usingConstant();
echo $myClass->class->getConstant();
Related
I would like to be able to do something like this:
class ThingIDs
{
const Something = 1;
const AnotherThing = 2;
}
$thing = 'Something';
$id = ThingIDs::$thing;
This doesn't work. Is there a straightforward way of doing something equivalent? Note that I'm stuck with the class; it's in a library I can't rewrite. I'm writing code that takes arguments on the command line, and I would really like it to take symbolic names instead of id numbers.
Use the constant() function:
$id = constant("ThingIDs::$thing");
Use Reflection
$r = new ReflectionClass('ThingIDs');
$id = $r->getConstant($thing);
If you are using namespaces, you should include the namespace with the class.
echo constant('My\Application\ThingClass::ThingConstant');
Helper function
You can use a function like this:
function class_constant($class, $constant)
{
if ( ! is_string($class)) {
$class = get_class($class);
}
return constant($class . '::' . $constant);
}
It takes two arguments:
Class name or object instance
Class constant name
If an object instance is passed, its class name is inferred. If you use PHP 7, you can use ::class to pass appropriate class name without having to think about namespaces.
Examples
class MyClass
{
const MY_CONSTANT = 'value';
}
class_constant('MyClass', 'MY_CONSTANT'); # 'value'
class_constant(MyClass::class, 'MY_CONSTANT'); # 'value' (PHP 7 only)
$myInstance = new MyClass;
class_constant($myInstance, 'MY_CONSTANT'); # 'value'
<?php
class Dude {
const TEST = 'howdy';
}
function symbol_to_value($symbol, $class){
$refl = new ReflectionClass($class);
$enum = $refl->getConstants();
return isset($enum[$symbol])?$enum[$symbol]:false;
}
// print 'howdy'
echo symbol_to_value('TEST', 'Dude');
If you have a reference to the class itself then you can do the following:
if (defined(get_class($course). '::COURSES_PER_INSTANCE')) {
// class constant is defined
}
My problem was similiar to this subject. When you have the object, but not the class name, you could use:
$class_name = get_class($class_object);
$class_const = 'My_Constant';
$constant_value = constant($class_name.'::'.$class_const);
I know I'm a bit late, but I hope this can help anyway.
Based on Phil's answer, I created a default enumerator class that can be extended.
class DefaultEnum
{
static public function getConstantText(string $constant)
{
try {
// Get child class name that called this method
$child_class = get_called_class();
$reflection = new ReflectionClass($child_class);
$const = $reflection->getConstant($constant);
return $const;
} catch (\ReflectionException $e) {
// ...
}
}
}
class CustomEnum extends DefaultEnum
{
const something = 'abcd';
const something2 = 'ABCD';
}
You can call this method like this
CustomEnum::getConstantText('something');
It will return 'abcd'.
The function get_called_class() is a function that returns the class name that called this method and it works specifically for static methods.
In this case $child_class value will be CustomEnum::class. ReflectionClass accepts strings and object as parameter.
I need to access a constant that belongs to a class, but instead of writing the class' name explicitly, I want to retrieve it from the object directly. The object is a property of another object.
$this->fetcher::BASE_URL
This statement produces the error syntax error, unexpected '::' (T_PAAMAYIM_NEKUDOTAYIM)
Here's an ugly work-around....
<?php
class simpleClass {
public function __construct() {
$this->fetcher = new simpleClass2();
}
public function printBaseURL() {
$fetcher = $this->fetcher;
print 'Base URL: ' . $fetcher::BaseUrl;
}
}
class simpleClass2 {
const BaseUrl = 'one';
}
$simpleClass = new simpleClass();
$simpleClass->printBaseURL();
You could use a function to return the constant
class MyClass
{
function getConstant() {
return self::CONSTANT . "\n";
}
}
Then call that function
$class = new MyClass();
$class->getConstant();
Or simply call the constant
MyClass::CONSTANT;
You can find more information about accessing constants within classes here. Look at the "user contributed notes", very good examples with explanation there.
I have a question regarding "dynamic" class initialising, let me explain what I mean:
$class = 'User';
$user = new $class();
//...is the same as doing
$user = new User();
So... that's not the problem, but I am having some trouble doing the same while calling a static variable from a class, for example:
$class = 'User';
print $class::$name;
Which gives out the following error:
Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM in
Off course I have tested doing print User::$name; and that works. So class works.
Why is this and is there a way around it?
Follow up question:
Also is there any valid reasons to not use this "dynamic" way in creating classes?
This code works good on PHP 5.4.3:
<?php
class A {
public static $var = "Hello";
}
print(A::$var);
$className = "A";
print($className::$var);
?>
This is the answer from the question I linked in the comments:
You can use reflection to do this. Create a ReflectionClass
object given the classname, and then use the getStaticPropertyValue
method to get the static variable value.
class Demo
{
public static $foo = 42;
}
$class = new ReflectionClass('Demo');
$value=$class->getStaticPropertyValue('foo');
var_dump($value);
If you don't have PHP version of 5.3 and above, and you don't want to use reflection (which in my opinion is an overkill - unless you want to access multiple static properties) you can define getter function and call it via call_user_func():
class A {
public static $var = "Hello";
public static function getVar() {
return self::$var;
}
}
$className = "A";
echo call_user_func(array($className, 'getVar'));
If I have an instance in PHP, what's the easiest way to get to a static property ('class variable') of that instance ?
This
$classvars=get_class_vars(get_class($thing));
$property=$classvars['property'];
Sound really overdone. I would expect
$thing::property
or
$thing->property
EDIT: this is an old question. There are more obvious ways to do this in newer
PHP, search below.
You need to lookup the class name first:
$class = get_class($thing);
$class::$property
$property must be defined as static and public of course.
From inside a class instance you can simply use self::...
class Person {
public static $name = 'Joe';
public function iam() {
echo 'My name is ' . self::$name;
}
}
$me = new Person();
$me->iam(); // displays "My name is Joe"
If you'd rather not
$class = get_class($instance);
$var = $class::$staticvar;
because you find its two lines too long, you have other options available:
1. Write a getter
<?php
class C {
static $staticvar = "STATIC";
function getTheStaticVar() {
return self::$staticvar;
}
}
$instance = new C();
echo $instance->getTheStaticVar();
Simple and elegant, but you'd have to write a getter for every static variable you're accessing.
2. Write a universal static-getter
<?php
class C {
static $staticvar = "STATIC";
function getStatic($staticname) {
return self::$$staticname;
}
}
$instance = new C();
echo $instance->getStatic('staticvar');
This will let you access any static, though it's still a bit long-winded.
3. Write a magic method
class C {
static $staticvar = "STATIC";
function __get($staticname) {
return self::$$staticname;
}
}
$instance = new C();
echo $instance->staticvar;
This one allows you instanced access to any static variable as if it were a local variable of the object, but it may be considered an unholy abomination.
classname::property;
I think that's it.
You access them using the double colon (or the T_PAAMAYIM_NEKUDOTAYIM token if you prefer)
class X {
public static $var = 13;
}
echo X::$var;
Variable variables are supported here, too:
$class = 'X';
echo $class::$var;
You should understand what the static property means. Static property or method is not for the objects. They are directly used by the class.
you can access them by
Class_name::static_property_name
These days, there is a pretty simple, clean way to do this.
<?php
namespace Foo;
class Bar
{
public static $baz=1;
//...
public function __toString()
{
return self::class;
}
}
echo Bar::$baz; // returns 1
$bar = new Bar();
echo $bar::$baz; // returns 1
You can also do this with a property in PHP 7.
<?php
namespace Foo;
class Bar
{
public static $baz=1;
public $class=self::class;
//...
}
$bar = new Bar();
echo $bar->class::$baz; // returns 1
class testClass {
public static $property = "property value";
public static $property2 = "property value 2";
}
echo testClass::$property;
echo testClass::property2;
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
From the string name of a class, can I get a static variable?
Somewhere in a parent class, I need to find the value of a static variable of one of the possible child classes, determined by the current instance.
I wrote:
$class = get_class($this);
$value = isset($class::$foo['bar']) ? $class::$foo['bar'] : 5;
In this example, the subclass whose name is in $class has a public static $foo.
I know using $class::$foo['bar'] is not a very beautiful piece of code, but it gets the job done on PHP 5.3.4.
In PHP 5.2.6 though, I am getting a syntax error:
Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM, expecting ',' or ')'
Is there an alternative way that would work on PHP 5.2.4+ that would get the same thing done?
EDIT: Reflection is better.
You can try the get_class_vars method. No access to PHP 5.2.6, but this works in 5.2.11...
class Test {
public static $foo;
function __construct() {
echo("...Constructing...<br/>");
Test::$foo = array();
Test::$foo['bar'] = 42;
}
function __toString() {
return "Test";
}
}
$className = 'Test';
$class = new $className();
$vars = get_class_vars($className);
echo($vars['foo']['bar'] . "<br/>");
Output:
...Constructing...
42
The reason that this does not work in PHP 5.2, is because before PHP 5.3 you are not allowed to use variables in the classname. So, if possible use eval for this.
eval('$result = ' . $c . '::$foo[\'bar\'];');
echo $result;
Otherwise, you're forced to use a function in the child class to receive the value. For example:
class MyParent {
public function __construct() {
$var = $this->_getVariable();
echo $var['bar'];
}
}
class MyChild extends MyParent {
static $var = array('bar' => 'foo');
protected function _getVariable() {
return self::$var;
}
}
new MyChild();
class Bar1 {
static $var = array('index' => 'value');
}
class Bar2 extends Bar1 {
}
class Foo extends Bar2 {
static $var = array('index' => 'value in Foo');
public function __construct() {
echo parent::$var['index'];
}
}
$foo = new Foo();
will output 'value', but not 'value in Foo'
Hope, that's what you are looking for.
You can get class static/call static method in the class you are working in using self key word or for parent class using parent. You can get that error on php 5.2.6 because of changes in get_class function in PHP 5.3.0