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.
Related
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();
In PHP sometimes it would be nice if I could define a function or a class with a variable name like
$myfunctionname="test";
function $myfunctionname(){
//...
}
so it would create the function test()
or with classes too like:
$foo = bar;
class $foo {
// lots of complicated stuff
// ...
}
but this doesen't work. like this it would give parse errors!
Is there a solution to this?
(I know, this is not good practise, but just as a workaround, it would be handy)
EDIT: My actual problem:
I have a framework with a migration process where every migration step is in a separate php include file in a folder.
Each file contains only one migration class that contains the name of the include file.
Because the class has to have that certain name, I would like to create the name of the class to a generic name that is created by the filename constant __FILE__
Yes, you can, but I dont want you to.
$classname = "test";
eval("class {$classname}{ public function hello(){ echo \"hello!\"; } }");
$evil_class = new $classname();
$evil_class->hello(); // echo's "hello!"
now, if you don't mind me I'm going for a shower.
You can use a factory pattern:
class poly_Factory {
public function __construct() {
$class = 'poly';
return new $class();
}
}
If that is anything you want to get to.
http://net.tutsplus.com/tutorials/php/understanding-and-applying-polymorphism-in-php/
Scroll down to step 4, last part...
I know you did not ask for that, but what can your question be good for else?
No. This code throws a parse error on line 3 because of the $:
$foo = 'bar';
class $foo {
function hello() {
echo "World";
}
}
$mybar = new bar();
$mybar->hello();
Result:
Parse error: syntax error, unexpected T_VARIABLE, expecting T_STRING on line 3
And as Jan Dvorak pointed out in the comments: even if you figure out a way to do this, don't do this.
If you want to create a value object you can just use the stdClass builtin type.
$object = new stdClass;
$object->someValue = "Hello World";
echo $object->someValue;
See it in Action
If you want to assign methods then you have to use the magic __call function, here is how I would do it.
class AnonObject{
private $properties = array();
private $methods = array();
public function __get($property){
return array_key_exists($property, $this->properties)?$this->properties[$property]:null;
}
public function __set($property, $value){
if (!is_string($value) && is_callable($value)){
if ($value instanceof \Closure){
// bind the closure to this object's instance and static context
$this->methods[$property] = $value->bindTo($this,get_class($this));
} else {
// invokable objects
$this->methods[$property] = $value;
}
} else {
$this->properties[$property] = $value;
}
}
public function __call($method, $args){
if (array_key_exists($method, $this->methods)){
call_user_func_array($this->methods[$method], $args);
} else {
throw new RuntimeException("Method ".$method." does not exist on object");
}
}
}
See it In Action
Note, as stated by several other people this is bad practice. If the goal of this exercise is to compose the behavior of an instance of an object at runtime a more maintainable solution would be to use the Strategy Pattern
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'));
In php, is there any difference between using
$myClass::method()
and
$myClass->method()
What's the reason for the change? (I believe -> has been around longer.)
I could see a point of using :: for methods and -> for properties or vice versa.
:: is the scope resolution operator, used for accessing static members of classes.
-> is the member operator, used for access members of objects.
Here's an example:
class Car {
public $mileage, $current_speed, $make, $model, $year;
public function getCarInformation() {
$output = 'Mileage: ' . $this->mileage;
$output = 'Speed: ' . $this->current_speed;
$output = 'Make: ' . $this->make;
$output = 'Model: ' . $this->model;
$output = 'Year: ' . $this->year;
return $output;
}
}
class CarFactory {
private static $numberOfCars = 0;
public static function carCount() {
return self::$numberOfCars;
}
public static function createCar() {
self::$numberOfCars++;
return new Car();
}
}
echo CarFactory::carCount(); //0
$car = CarFactory::createCar();
echo CarFactory::carCount(); //1
$car->year = 2010;
$car->mileage = 0;
$car->model = "Corvette";
$car->make = "Chevrolet";
echo $car->getCarInformation();
Consider this:
class testClass {
var $test = 'test';
function method() {
echo $this->test;
}
}
$test = new testClass();
$test->method();
testClass::method();
The output will be something like:
test
Fatal error: Using $this when not in object context in ... on line 7
This is because :: makes a static call to a class while -> is used to call methods or properties on a specific instance of a class.
Incidentally, I don't believe you can do $test::method() because PHP will give you a parse error like this:
Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM in ... on line 14
:: is also used within a class/object to call its parent, e.g.:
parent::__constructor();
Also if it's called from within an object (so not statically).
I am trying to access static member of a class.
my class is:
class A
{
public static $strName = 'A is my name'
public function xyz()
{
..
}
..
}
//Since I have bunch of classes stored in an array
$x = array('A');
echo $x::$strName;
I am getting error while printing. How can I print 'A is my name'
If A is a class, you can access it directly via A::$strName.
class A {
public static $strName = 'A is my name';
}
echo A::$strName; // outputs "A is my name"
Update:
Depending on what you have inside your array, whether its what I like to define as class objects or class literals could be a factor. I distinguish these two terms by,
$objClasses = array(new A(), new B()); // class objects
$myClasses = array('A','B'); // class literals
If you go the class literals approach, then using a foreach loop with PHP5.2.8 I am given a syntax error when using the scope resolution operator.
foreach ($myClasses as $class) {
echo $class::$strName;
//syntax error, unexpected '::', expecting ',' or ';'
}
So then I thought about using the class objects approach, but the only way I could actually output the static variable was with an instance of an object and using the self keyword like so,
class A {
public static $strName = 'A is my name';
function getStatic() {
return self::$strName;
}
}
class B {
public static $strName = 'B is my name';
function getStatic() {
return self::$strName;
}
}
And then invoke that method when iterating,
foreach($objClasses as $obj) {
echo $obj->getStatic();
}
Which at that point why declare the variable static at all? It defeats the whole idea of accessing a variable without the need to instantiate an object.
In short, once we have more information as to what you would like to do, we can then go on and provide better answers.
If you want a working version for PHP5.2, you can use reflection to access the static property of a class.
class A {
static $strName= '123';
}
$lstClass = array('A');
foreach ($lstClass as $value) {
$c = new ReflectionClass($value);
echo $c->getStaticPropertyValue('strName');
}
Demo : http://ideone.com/HFJCW
You have a syntax error with missing semicolon and because it is an array you need to access the index of 0, or else it would be trying to call class 'Array'.
class A
{
public static $strName = 'A is my name';
public function xyz()
{
// left blank and removed syntax error
}
}
$x = array('A');
echo $x[0]::$strName;
Should fix it.
UPDATE
If you want to iterate over an array to call a class variable:
$x = array('A', 'B');
foreach ($x as $class) {
echo $class::$strName;
}
Not sure why you would want that, but there you go. And this has been tested, no errors were thrown, valid response of A is my name was received.
EDIT
Apparently this only works under PHP 5.3
I do find next one simple solution but don't know whether its good one or not.
My soln is:
eval('return '.$x[0].'::$strName;');
From inside a class and want to access a static data member of its own you can also use
static::
instead of
self::