PHP : Difference of $_ENV and $GLOBALS - php

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.

Related

Static variable in php without objects

I want to define a php variable that can be accessed in all the scripts and is initialized only one time per runtime. This is, like a static variable but with no object. I thought of using $GLOBALS but noticed the variables do not stick between script executions and I would have to instantiate the variable everytime. So how exactly can I accomplish this? Would I need to create an abstract class only to static the variable?
how about using $_SESSION? see http://www.w3schools.com/php/php_sessions.asp

Defining your own magic constants in 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.

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.

PHP best practices: repass variables from config file when calling functions or use global?

I have a program that I use on several sites. It uses require('config.php'); to set any site dependant variables like mysql connect info, paths, etc.
Let's say that I use one of these site-dependant variables in a function, like $backup_path.
This variable was initially declared in config.php, and does not appear in the main program file.
I need to access this variable in function makebackup($table_name); (also in a separate functions.php file).
Is it better to say
makebackup('my_table');
and then use "global $backup_path" inside the function, or is it better to call the function using
makebackup('my_table',$backup_path);
The argument for the first is that it keeps the main program flow simple and easy to understand, without clutter.
The argument for the second is that it might not be obvious that the variable $backup_path exists after some time has passed, and debugging or reworking could be difficult.
Is one or the other of these techniques "standard" among professional programmers? Or should I be using $_SESSION to declare these global variables?
The second alternative,
makebackup('my_table', $backup_path);
is a reusable function and therefore generally preferable. The extra argument is not a big price for reusability.
If you are entirely sure that you'll ever use that function in that particular application only, and for $backup_path only, then maybe consider the global alternative. Even then it's good to check that the global variable actually exists. And be aware that it's extremely difficult to get rid of globals once you start using them.
Remember that you can set a default value for your function:
function makebackup($table, $dir = CONFIG_BACKUP_PATH)
That way you won't have to supply the variable in the default case, you can simply assume that the configured backup path is the default.
This assumes that you are using constants, not global variables.
I'm think you must use Singleton of Factory class config for this purposes.
function makebackup($table)
{
$backup_path = ConfigFactory().getConfig($some_site_specific_data).getBackupPath()
mysqldump($table, $backup_path)
}
Passing references around is far easier to test (you can give mock configuration objects). Globals less so. You can assert that the reference is not null on the method. I would call testability best practice.
Label that global variable
Personally, I have also taken to marking global variables very clearly. If I must use them, I want to be clear about them.
So here, I'd rename $backup_path to $GLOBAL_backup_path. Every time I saw it, I'd know to be careful with it.
An alternative option is using php constants with define().
Your config.php will set constants for every parameter (mysql connection, css style, wathever). Then you will not need to pass variables to functions nor using global.
One downside is that you can define only booleans, floats, strings or integers, no complex data structures.
Not sure there's really a 'right' way to do it, but another option would be something like this:
function makebackup($table, $backup_path = '') {
if ( $backup_path == '' ) {
if ( isset($GLOBALS['backup_path']) ) {
$backup_path = $GLOBALS['backup_path'];
}
else {
die('No backup path provided');
}
}
}
That way you can either pass in the value (for testing and future use) or if you don't pass it in, then the function will look for a possible global variable.

Categories