103

I am getting an error:

Fatal error: Constant expression contains invalid operations in config.php on line 214

That line was:

 protected static $dbname = 'mydb_'.$appdata['id']; 

Whether I did any mistakes in quotes? Or somewhere else?

My search for the error message only showed a different source cause (a dynamic default value in a function definition).

3
  • If you don't say what's unclear about the explanations you've found people will possibly waste time composing the same information again. Commented Oct 21, 2016 at 8:42
  • 1
    @ÁlvaroGonzález Sorry mate , The answer by Al Fonce here cleared my issue . actually other similar titles i found here in SO has only similar title but the query differs mate . That is why i asked this question Commented Oct 21, 2016 at 8:47
  • 1
    Then another way to express that is just "I couldn't find a similar question here" and I'd say that's explicitly assumed if you don't say anything. I've taken the liberty of editing your question to reflect that. Never mind, the question itself can be pretty interesting if there aren't dupes (and if there're dupes it'll hopefully be linked to one). Commented Oct 21, 2016 at 11:21

6 Answers 6

95

From the official Php documentation :

Like any other PHP static variable, static properties may only be initialized using a literal or constant before PHP 5.6; expressions are not allowed. In PHP 5.6 and later, the same rules apply as const expressions: some limited expressions are possible, provided they can be evaluated at compile time.

So you cannot initialize a static variable with another variable. Replace $appdata['id'] with a constant string or remove the static attribute.

This is because all static declarations are resolved in compile-time, when the content of other variables is not known (see this other page of official doc).

Sign up to request clarification or add additional context in comments.

2 Comments

Can you elaborate on compile-time? What would that even mean for an interpreted language like PHP? Even in compiled languages like C#, we wont have such limitation using static constructors.
I think the issue is values of static variables need to be initialized as soon as the class is read. Other variables may not be initialized when the class file is read. Referring to a possibly uninitialized variable to initialize a static variable is not logically allowed. This causes an error.
38

Unless you mess with reflection, the only way I can think of to have a static private/protected class property with a dynamically generated value is to calculate it outside the class:

class Foo { protected static string $dbname = DBNAME; public static function debug(): string { return Foo::$dbname; } } $appdata = [ 'id' => 31416, ]; define('DBNAME', 'mydb_' . $appdata['id']); var_dump(Foo::debug()); 

In your precise use case, however, it's possible that there's simply no good reason for the property to be static. In that case, it's as straightforward as using the constructor:

class Foo { protected string $dbname; public function __construct(array $appdata) { $this->dbname = 'mydb_' . $appdata['id']; } public function debug(): string { return $this->dbname; } } $appdata = [ 'id' => 31416, ]; $foo = new Foo($appdata); var_dump($foo->debug()); 

4 Comments

I believe this works only because you are effectively using constants. Try using an environment variable that cannot be resolved at "compile" time.
@Pierre-LucBertrand I'm unsure of what you're trying to say.
Instead of having $appdata= ['id'=>...], try using an environment variable instead of the constant 31416 and you should reproduce the same problem as the question. The difference would be that the environment variable is not resolvable at compile time unlike 31416.
@Pierre-LucBertrand I still cannot reproduce: 3v4l.org/6VNEX#v8.1.8 - Could you please share an online fiddle that exhibits such behaviour?
17

This is because a static variable contains a constant value in it. But in your case:

protected static $dbname = 'mydb_'.$appdata['id']; 

$appdata['id'] is dynamic that can change its value during the execution. That's why the error is showing.

2 Comments

i understood , i am just learning kindly guide me as in this case i need to associate a dynamic variable.So, how should i associate dynamic db name
Do not use static in this case
7

I had this error and my fix was to not declare a date within a class property array

public static $config_array = array( 'start_date' => date('Y-m-d H:i:s') // No can do ); 

Comments

1

In my case the solution to this issue was to create a singleton class so the variable's value is initialized (calculated) only once and still have access to it whenever I need.

(Extra info: The singleton is a design pattern which stricts you to have only 0 or 1 instance of your class in your entire program. There are several design pattern, I collected 115 of them so far on a single image)

In your case the code would look like this:

 class DataBaseConfig { private static $instance; private $dbname ; private final function __construct() { $this->dbname = 'mydb_'.$appdata['id']; } public static function getName() { if (!isset(self::$instance)) { self::$instance = new DataBaseConfig(); } return self::$instance->dbname; } } 

You can use it like DataBaseConfig::getName() for the shortest / simplest version.

In reality you have more complex classes and functions so by defining a getInstance() function you will avoid repeating the <check instance> - <create instance process> lines for every function you add.

(Extra info: 2 synonym paradigms DRY - Don't Repeat Yourself and DIE - Duplication Is Evil)

This is the refactoring you need:

public static function getInstance() { if (!isset(self::$instance)) { self::$instance = new PhpStarter(); } return self::$instance; } public function getName() { return $this->dbname; } 

Use it like $db = DataBaseConfig::getInstance(); then $db->getName() and $db->getSomethingElse() for the other functions.

Comments

-1

For your information:- I got the same error by using some characters in a constant expressions.

public static $dbPassword="mAkE-34@-||sR"; 

This is what caused the error and I removed this || which is the logical OR operator characters from the string and it worked.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.