PHP Object access with class constant - php

Is it possible in PHP to access a member of an object where the name of the member is specified by a class constant?
Consider this example:
class X{
const foo = "abc";
}
class Y{
public $abc;
}
$y = new Y();
$y->X::foo = 23; //This does not work
The parser doesn't accept the last line but this is what I want. I want to access the field with the name stored in the class constant X::foo. Is there a syntax to achieve that?

Use variable variables, either via a temp or directly:
$name = X::foo; // Via temp var
$y->$name = 23; // Access the member by the string's content
var_dump($y->{X::foo}); // Dumps 23
Working sample here.

You should write your code like this
$y->{X::foo} = 23;
Hope it helps

Related

error when using variable class name and static method

Running PHP 5.4, so I wasn't expecting this, but I'm encountering the following error:
Parse error: syntax error, unexpected '::' (T_PAAMAYIM_NEKUDOTAYIM)
Assume you have a variable of stdClass setup as follows:
$this->variable = new stdClass();
$this->variable->other = array('class' => 'helloworld');
Now, assume you want to access a static method of class helloworld:
// Standard call
$x = helloworld::my_static_method();
// Call with variable class name
$x = $this->variable->other['class']::my_static_method();
When calling the above using the variable class name, I receive the parsing error. What's odd, is that if I do the following, no error is presented:
$class = $this->variable->other['class'];
$x = $class::my_static_method();
To me this seems very odd, can anyone think of a reason why the class name isn't resolving correctly when using the first example versus the second?
can anyone think of a reason why the class name isn't resolving correctly when using the first example versus the second?
The PHP parser does not support such a syntax, and that's merely all. This is because the parser has grown historically. I can't give more reason than that.
It will be that with PHP 7 you can see some changes on these syntax details working more into your expected direction Uniform Variable Syntax:
($variable->other['class'])::my_static_method();
But until then, you can go around that with the help of call_user_func:
call_user_func([$variable->other['class'], 'my_static_method']);
call_user_func($variable->other['class'] . '::my_static_method');
Or as you wrote your own, by creating a variable:
$class = $variable->other['class'];
$class::my_static_method();
Or even a variable that looks like something different:
${(int)!${0}=$variable->other['class']}::my_static_method();
Related Material:
Interpolation (double quoted string) of Associative Arrays in PHP
This doesn't work ($this->variable->other['class']::my_static_method()) as it's essentially using a string as the class name directly. It works when you assign it to a variable first, as it's then being evaluated out as the class name instead.
You can also look into using ReflectionMethod invocation in order to call the method, in which case you wouldn't have to store the class name in a variable before using it. Here's the docs on that: http://php.net/manual/en/class.reflectionmethod.php and on the invoke method (you pass in NULL to indicate a static method) http://php.net/manual/en/reflectionmethod.invoke.php
Here are a couple examples of ways to invoke your function:
class helloworld{
public static function my_static_method($i = 0){
echo "Here: ".$i;
}
}
class Foo{
private $variable;
public function __construct(){
//Create a new class
$this->variable = new stdClass();
//Create a new property of the class, storing an array
$this->variable->other = array('class' => 'helloworld');
//Call function statically
$x = helloworld::my_static_method(1); //Outputs: "Here: 1"
//Store class name in a variable before use
$class = $this->variable->other['class'];
$y = $class::my_static_method(2); //Outputs: "Here: 2"
//Using a ReflectionMethod, you can call the function this way, too
$z = new ReflectionMethod($this->variable->other['class'], 'my_static_method');
$z->invoke(null, 3); //Outputs: "Here: 3"
}
}
//Instantiate new Foo class
new Foo();

Assign value to php class const

I am not at all good in oop concept but i tried
final class my_class
{
const VALUE = "test";
const VALUE1 = "test";
}
this is working
$some = 'test';
final class my_class
{
const VALUE = $some;
const VALUE1 = "test";
}
this is not working why?
Because PHP5 currently doesn't support this.
If you want this feature, you have to wait for PHP5.6 which added constant scalar expressions: https://wiki.php.net/rfc/const_scalar_exprs
That means, you can use constant scalar expressions to define constants - something like const VALUE = $var; still wont work for some good reasons.
If you really want to define some runtime constants, you have to use define() or manipulate classes with runkit(runkit_constant_add)

Class property as class name

$this->property = 'SomeClass';
$x = new $this->property(); // works
$x = $this->property::create(); // fails (parse error)
Is this a bug in PHP?
Can a static method be called using the property, without assigning the value to a new variable, and using that variable instead?
Use call_user_func
$x = call_user_func(array($this->property, 'create'));
It's been entered as a bug for a few months and is still in Open status, so I'm gonna go with yes.
https://bugs.php.net/bug.php?id=61397
Similarly,
https://bugs.php.net/bug.php?id=54095

How to access a class const dynamically in PHP?

Let's say I have a class like so:
class Order {
const STATUS_INITIALIZED = 'initialized';
const STATUS_ORDERED = 'ordered';
}
and I'd like to grab the constant like so:
$status = $_GET['status']; // ?status=STATUS_ORDERED
Is there a way to access the value of the constant, given the name of the constant as a string?
I've tried:
Order::$status
Order::$$status
The function constant does this. The syntax is
constant('Order::'.$status)
See it in action.

Accessing PHP Class Constants

The PHP manual says
Like static members, constant values can not be accessed from an instance of the object.
which explains why you can't do this
$this->inst = new Classname();
echo $this->inst::someconstant;
but then why does this work?
$this->inst = new Classname();
$inst = $this->inst;
echo $inst::someconstant;
From the PHP interactive shell:
php > class Foo { const A = 'a!'; }
php > class Bar { public $foo; }
php > $f = new Foo;
php > $b = new Bar;
php > $b->foo = $f;
php > echo $b->foo::A;
PHP Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM, expecting ',' or ';' in php shell code on line 1
The reason that the former syntax fails is that the PHP parser doesn't know how to resolve the double-colon after the property reference. Whether or not this is intentional is unknown.
The latter syntax works because it's not going through the property directly, but through a local variable, which the parser accepts as something it can work with:
php > $inst = $b->foo;
php > echo $inst::A;
a!
(Incidentally, this same restriction is in place for anonymous functions as properties. You can't call them directly using parens, you have to first assign them to another variable and then call them from there. This has been fixed in PHP's trunk, but I don't know if they also fixed the double colon syntax.)
If you are within the class, you can access the constant like this:
self::MY_CONSTANT;
For example:
class MyClass {
const MY_CONSTANT = 'constant value';
public function showConstant() {
echo self::MY_CONSTANT;
}
}
http://php.net/manual/en/language.oop5.constants.php
To quote the manual:
As of PHP 5.3.0, it's possible to reference the class using a variable. The variable's value can not be a keyword (e.g. self, parent and static).
It goes on to use this example:
$class = new MyClass();
echo $class::constant."\n"; // As of PHP 5.3.0
So $inst::someconstant is supposed to work.
As to why $this->inst::someconstant gives a parsing error, I don't know. PHP is funny about some things.
php supports accessing class constants from an object instance. Code below is working (checked in phpv5.5.5):
<?php
class superheroes{
const kal_el = 'Superman';
}
$instance = new superheroes;
echo $instance::kal_el;
Source: http://dwellupper.io/post/48/defining-class-constants-in-php

Categories