Cannot Use Concatenation When Declaring Default Class Properties in PHP

Cannot use concatenation when declaring default class properties in PHP?

For PHP Versions Before 5.6

See http://www.php.net/manual/en/language.oop5.properties.php

They are defined by using one of the keywords public, protected, or private, followed by a normal variable declaration. This declaration may include an initialization, but this initialization must be a constant value--that is, it must be able to be evaluated at compile time and must not depend on run-time information in order to be evaluated.

For more complex initialisation, use the constructor

public function __construct()
{
$this->settings = __DIR__ . '/';
}

PHP 5.6 and Above

As of PHP version 5.6, you can use concatenation when declaring default class properties in PHP. See https://wiki.php.net/rfc/const_scalar_exprs.

This allows places that only take static values (const declarations, property declarations, function arguments, etc) to also be able to take static expressions.

Why can't I concat strings for class variable definition in PHP?

You try to uses the properties css as if they were static, but they are not.

function __construct() 
{
$this->CSS_reset = $this->css . "reset.css";
$this->CSS_styles = $this->css . "styles.css";

}

PHP Assigning Concatenated Methods in a Class Property

You can't set dynamic values in the class properties like that; they have to be constant values. You have to make such assignments in the constructor

// NO
private $person_info = $this->getName . ' ' . $this->getGender . ' and ' . $this->getAge() . '.';

// YES
public function __construct() {
$this->person_info = $this->getName . ' ' . $this->getGender . ' and ' . $this->getAge() . '.';
}

But what you actually mean is this

// you're calling get methods, not properties
// make sure to use $this->getName(), not $this->getName
public function __construct() {
$this->person_info = $this->getName() . ' ' . $this->getGender() . ' and ' . $this->getAge() . '.';
}

But actually all of your code is bad

// This makes no sense to have as a constant property in a class
private $person = array(
'name' => 'Sarah',
'gender' => 'female',
'age' => 21
);

This class makes way more sense for your purposes

class Person { 

// container for your info object
private $info = [];

// make info a parameter for your constructor
public function __construct(array $info = []) {
$this->info = $info;
}

// use PHP magic method __get to fetch values from info array
public function __get(string $attr) {
return array_key_exists($attr, $this->info)
? $this->info[$attr]
: null;
}

// use PHP magic method __set to set values in the info array
public function __set(string $attr, $value) {
$this->info[$attr] = $value;
}

// single method to fetch the entire info object
public function getInfo() {
return $this->info;
}
}

Simple. Let's see how it works now

$p = new Person([
'name' => 'Sarah',
'gender' => 'female',
'age' => 21
]);

echo $p->name, PHP_EOL;
// Sarah

echo $p->gender, PHP_EOL;
// female

echo $p->age, PHP_EOL;
// 21

echo json_encode($p->getInfo()), PHP_EOL;
// {"name":"Sarah","gender":"female","age":21}

Because the $info array is a parameter now, you can easily create Person objects with other data

$q = new Person([
'name' => 'Joey',
'gender' => 'male',
'age' => 15
]);

echo $q->name, PHP_EOL;
// Joey

echo $q->gender, PHP_EOL;
// male

echo $q->age, PHP_EOL;
// 15

echo json_encode($q->getInfo()), PHP_EOL;
// {"name":"Joey","gender":"male","age":15}

Can't use string concatenation in constants?

The problem isn't the constant, it's that you're defining a class variable as a string using a non-literal.

const SOME_PATH = __DIR__;

Is fine, but once you start using concatenation, the parser throws a hissy fit.

It's the same reason why this works:

class myClass {
public $something = "something";
}

But this doesn't:

class myClass {
public $something = "some" . "thing";
}

PHP error, concatenation in array() in member initialiser

You cannot initialize class attributes with an expression. You have to do that in the constructor or use a fixed value, like a regular string.

How to perform text concatenation in object variables in PHP?

You can only do that in the constructor, as class variables/properties must be initialized on declaration with constant expressions. From the manual:

This declaration may include an initialization, but this initialization must be a constant value--that is, it must be able to be evaluated at compile time and must not depend on run-time information in order to be evaluated.

This means you can't use any operators or function calls.

class bla {
public $a;

public function __construct() {
$this->a = 'a' . 'b';
}
}

Can I use string concatenation to define a class CONST in PHP?

Imho, this question deserves an answer for PHP 5.6+, thanks to @jammin comment

Since PHP 5.6 you are allowed to define a static scalar expressions for a constant:

class Foo { 
const BAR = "baz";
const HAZ = self::BAR . " boo\n";
}

Although it is not part of the question, one should be aware of the limits of the implementation. The following won't work, although it is static content (but might be manipulated at runtime):

class Foo { 
public static $bar = "baz";
const HAZ = self::$bar . " boo\n";
}
// PHP Parse error: syntax error, unexpected '$bar' (T_VARIABLE), expecting identifier (T_STRING) or class (T_CLASS)

class Foo {
public static function bar () { return "baz";}
const HAZ = self::bar() . " boo\n";
}
// PHP Parse error: syntax error, unexpected '(', expecting ',' or ';'

For further information take a look at: https://wiki.php.net/rfc/const_scalar_exprs and http://php.net/manual/en/language.oop5.constants.php

Concatenate instance variables

You can not execute arbitrary code in the class definition. You can only declare values (static strings, numbers and arrays with static information).

If you want to dynamically add values, you would have to do so in the constructor.

class Settings 
{
public $appDir = 'app';
public $controllerDir = '/controllers';

public function __construct()
{
$this->controllerDir = $this->appDir . $this->controllerDir;
}
}


Related Topics



Leave a reply



Submit