Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP constants declaration based on condition

Tags:

php

I am using one separate file for all constants of my PHP application.

class constants
{
    const USERNAME = 'abc';
    /*
      ⋮
    */
}

For lets say USERNAME constant, value can be either xyz or abc based on file exists check. If xyz file exists USERNAME value would be xyz. How can I do this check in my constants class?

like image 994
CM. Avatar asked Apr 17 '10 17:04

CM.


1 Answers

If the value of the constant is variable, then it is not a constant, but a variable.

Since you are (correctly) trying to keep your application stuff capsuled and away from the global scope, you might be interested in the Registry Pattern. A Registry is basically a glorified array that stores whatever you throw into it and is globally accessible throughout your application.

Some resources:

  • http://www.patternsforphp.org/index.php?title=Registry
  • http://www.brandonsavage.net/the-registry-pattern-reexamined/
  • http://blog.fedecarg.com/2007/10/26/registry-pattern-or-dependency-injection-container/

EDIT If you are truly desperate and have to have the constant redefined, you can use

  • runkit_constant_redefine — Redefine an already defined constant

Runkit might not be available if you are on shared hosting and I consider needing it a code smell, but here is how you'd basically do it (in your bootstrap)

if ( file_exists('xyc') ) {
    runkit_constant_redefine('Constants::USERNAME', 'xyz');
}

EDIT Some more options (all of which not exactly pretty either):

class Abc { const FOO = 1; const BAR = 2; }
class Xyz extends Abc { const FOO = 2; }
class_alias(file_exists('abc') ? 'Abc' : 'Xyz', 'Constants');

For this you would rename your current constants class to Abc and add a second class Xyz to extend it and overwrite the USERNAME constant (FOO in the example). This would obviously break your code, because you used to do Constants::USERNAME, so you have to create an alias for the former class name. Which class Constants will point to, is decided with the conditional check. This requires PHP5.3.

A pre-5.3 solution would be to simply save the Constants class file under two different names, e.g. abc_constants.php and xyz_constants.php, modify the latter accordingly to hold USERNAME xyz and then include either or depending on the file check.

Or replace the value of USERNAME with a placeholder and instead of including the class you load it into a variable as a string. Then you replace the placeholder according to the filecheck result and eval the string, effectively including the class this way.

But I have to say it again: I strongly suggest refactoring your code over using these.

like image 52
Gordon Avatar answered Oct 06 '22 01:10

Gordon