Defining your own magic constants in php? - php

Is there anyway in php, by which we can define our own magic constants, which value could vary throughout the program and how to define variables with the SUPER GLOBAL SCOPE.

Just add the variable as an Apache environment variable:
SetEnv foo bar
You could set that in httpd.conf, apache2.conf, or .htaccess.PHP should then be able to access it via one or more of the following methods:
$_SERVER['foo']
$_ENV['foo']
getenv('foo')

While you can declare global variables, superglobals are limited to those found in PHP. You might want to keep your data as $_SESSION['mysuperglobal'], althou I suggest more elaborated patterns like a config-singleton, a registry or dependency injection.

You cannot define magic constant w/o building own flavour of PHP. But you can mimic this by putting all your "magic" define()s in separate file and including it in each of your script you can use auto_prepend_file config directive. Still, if you think you need something like this, the I'd try to rethink that approach. Whenever "magic" or "global" things comes to play, it's rather indication of need of refactoring.

Related

PHP auto_prepend_file define a constant

I do have configured a auto_prepend_file in my .htaccess. It works fine!
Now I wanted to know how to make a string globally without using GLOBALS.
I do have something like this:
define('WWW_URL', 'http://www.xyz.de');
define('STATIC_URL', 'http://static.xyz.de');
How do I get the WWW_URL or STATIC_URL in my index.php which is loaded right after the prepend and before append file?
Thanks in advance,
Daniel
Like superglobals, the scope of a constant is global. You can access constants anywhere in your script without regard to scope.
From php manual
So you can access the constants inside your index.php using WWW_URL / STATIC_URL.
Beware constants are read-only: you won't be able to change their value after you "define()" them, unlike GLOBALS variables.

PHP : Difference of $_ENV and $GLOBALS

What is the difference of using $_ENV and $GLOBALS ?
I wish to have a global variable to get and set at anytime and anywhere (need to be accessible in OO class & plain procedural PHP script). Which of the above should I use?
You should not use global variables at all and instead use dependency injection (i.e. pass all necessary data as function parameters), but if you have to, use $GLOBALS. $_ENV holds data from outside the PHP script passed by the system. While it may serve the purpose as a superglobal, that's not what it's meant for.
You should use $GLOBALS as that is the purpose it was made for, to provide a place to set global variables that can be accessed in any context of your PHP code (inside function, classes, anywhere).
But as a good programming practice don't abuse global vars, in contrast try that your functions and objects methods have in context all data they need to work it, so your code is more flexible, see globals are evil.
For an alternative to globals, take a look at how Zend does this. Zend registry: http://framework.zend.com/manual/1.12/en/zend.registry.html
Basically it is a class with some static methods for getting and setting variables.
I personally prefer this kind of approach to using globals.

Do globals interfere with required files in PHP?

I need to edit a variable (array) that is defined outside of the function, so I can use it in another function further in. The easiest way I can think of is to define it as global inside the function, but I have many required files involved as well.
The documentation of global variables says that it can be used "anywhere in the program." Does that imply throughout all files (is it global in a sense of across all files) or is it just the file it's in (locally global, if that makes sense).
I did find a question about globals on this site that suggests passing it by reference, but I have this function implemented extensively in other files and requiring them to have an additional variable in their calls would be obnoxious to say the least.
If you define your variable global within the function, you will be referring to the globally scoped variable, and changes to that variable made within your function will be visible to other functions that use that global variable, whatever files they're in, so long as the inclusion / execution order is correct.
If the file you declare the global in is in memory, then that variable is available for you to use. But, if you don't include or require the file the global is declared in on a certain page, it will not be available to you.
Order is also important. If you try to call the global variable before the include or require of the file you set it in, it will be unavailable.
Globals are shared among all files. By the way, instead of declaring them with global $variable;, you should use $GLOBALS['variable'] to make explicit that you're accessing a global variable.
If a lot of functions grouped in a file require access to some common state, chances are you need to turn them into a class. That's pretty much the definition of a class.
Or you could turn the array into a class and have functions call methods on it.
Perhaps a singleton or a registry (2) could help.
Note that most OOP implementations pass a reference to the object as a method's first parameter, hidden (C++, PHP) or not (C, Python).

Php : what is better for configuration variable ? variable or parameter?

i have an application done in php and all configuration variables are loaded in a big $conf variable at the beginning of the script.
What is the better way to communicate this configuration variable to all other functions ?
make it a parameter of every function ? or use it with "global $conf;" statement in every function ?
is there a better way to do ?
Thanks
Use PHP constants.
For ponies sake, avoid using global variables at all costs :)
EDIT
Some explanations about "avoiding global variables at all costs" and possible alternatives:
https://stackoverflow.com/questions/357187/when-are-global-variables-acceptable/357361#357361
http://my.opera.com/zomg/blog/2007/08/30/globals-are-evil
https://stackoverflow.com/questions/1285700/what-are-some-good-tips-for-a-new-php-developer (especially section Scope of the accepted answer)
Make a configuration class that stores the options. Make it a singleton PHP Manual describes that here. This is just an alternative to global variables. It would allow you to define a method to load options from a file or a php array and store them in the class. Other classes can use the configuration object by getting the single instance and accessing the data.
I think this is better than a global variable as the other answer also says. But it still lets you define options as arrays, or even nested arrays if you want (and set up your class accordingly)
Your use of a single global-scoped variable $conf is perfectly fine. Many PHP applications do that. But there are drawbacks to combat.
In particular it's often more effort to write global $conf in each function where you want to access them. In that case I would recommend a simple global wrapper function instead:
function conf($key, $sub="") {
global $conf;
if (defined($key))
{ return constant($key); }
elseif ($sub)
{ return $conf[$key][$sub]; }
else
{ return $conf[$key]; }
}
This allows you to write conf("setting1") or conf("main", "opt3") whereever you need it. Still you can access the global $conf where that is more suitable. As extra bonus you can make this wrapper function more intelligent, by allowing it to query alternative settings etc. Also see how easy it is to also sneak in conf("CONSTANT") support.
Keeping this adds some flexibility in defining your configuration settings. Personally I use a similar approach, albeit with defining the array step-wise rather than at once:
$app_config["title"] = ...;
$app_config["editor.btns"] = ...;
define("RESTRICTED_MODE", true);
I'm preferring the array() approach, but transitioning to an ini-file for storage at a later point is not a problem. Also you can still make your config array read-only if the need arises. For that just define an:
class Read_Only_Array extends ArrayObject { function offsetSet() {} }
$conf = new ReadOnlyArray($conf);
So it's still accessible as array, but you easily established what others use cumbersome registries or syntactic workarounds for.
The "globals are evil" meme is completely baloney. It's parrotted on SO by cargo cult programmers with a desire for oversimplification and newcomers who glance over bold headlines without understanding the language semantics.
In your case, you just use a single $conf variable, and do not pollute the shared scope. When it is coherently accessed from the whole application, then it's not an issue. You should however strictly avoid to modify contents at runtime (use Read_Only_Array if need be). Create a secondary $app_var[] aray for that, and keep your config settings static.

Where to place "Settings" of a framework

this is more a conceptual question. Consider you have a php framework that runs a generic website.
You can of course tweak the framework behavior with settings, the question is: where is more natural to place these settings?
My framework consists of some functions that helps me doing some tasks (for example cache managment).
In this fw I use a generic variable
$config = array( 'setting1'=>'value1' etc );
And if a function needs it does a global:
function manageCache() {
global $config;
//> perform task with settings from $config
}
Consider the procedural nature of my framework, and the fact someone says global is evil, how would you manage the settings?
Thanks
Edit1: Please don't tell to use constats, i have tons of settings and i don't want to make a tons of constant + they must be editable
There's nothing wrong with your configuration array. It's quite a common approach. The fallacy globals are evil is cargo cult programming advise. Please ignore.
Now the $config array is often easy to use by itself. But you can expand on that. It's quite simple for example to turn it into an ArrayObject once initialized:
$config = new ArrayObject($config, 2);
This will allow you to access the settings as $config["setting"] and $config->setting alike. It's easier on the eyes.
If you also want to avoid having to import the array everywhere, because you sometimes need just a single value, then expand with a wrapper function config("setting") for convenience.
Btw, I'm usually using a mix of config array and constants myself. And I made a little management tool for plugins and a settings array in a central config.php. http://web135.srv3.sysproserver.de/milki.erphesfurt.de./genericplugins/genconfig.html
If your settings are constant and do not change then consider using define() - http://php.net/manual/en/function.define.php
//Set anywhere like this
define("DB_NAME", "stackoverflow");
// You can then read it from anywhere using
echo DB_NAME;
Is they need to be editable then you can use globals, but ensure that register_globals is off.
If you are using PHP5 then you could implement the Registry pattern to do this.
I'd be tempted to use a define rather than a variable, as this would at least remove the need for global variables.
That said, you can't (easily) store complex data types such as arrays via defines, so you'll want to factor this in.
Pass the global as a parameter of function
manageCache($config);
Globals are really evil
Normally you would have a config folder somewhere in your framework that you auto include on startup.
It would potentially look like this:
ROOT/
config/
db.php
cache.php
constants.php
You would then have something like a Config class that handles importing this configuration variables and converting them into instance variables. This way you can access these configuration variables like this:
$config->get_config('settings_1');

Categories