According to many sources, register_globals (global variables that is) should be disables in your php.ini.
Should I write define() in my code and use constants if global variables are disabled? Are those even related?
They are related in that they have global scope, but constants are meant to not change once defined, unlike global variables which the page can modify as it goes along. So just switching over to using define() instead of a global won't help much.
It's better if you refactor your methods to take the variables as parameters and rely on that to pass variables around.
Global variables aren't constant (you can change the value of a global variable, but you can only define a constant once).
Constants aren't always global (you can declare a constant in a class).
Also, global variables can be any type: scalar, array, or object. Constants can only be scalars.
I'm not going to say either constants or globals are good or bad. When used appropriately, they both have beneficial uses. There are security issues around the register_globals feature that are separate from more general use of globals.
A few things here.
First, the register_globals that you disable in your php.ini refers to an old PHP feature where any variable sent via a query string (GET) or form (GET/POST) would be converted into a global PHP variable. This is the functionality that is (and should be) disabled when you turn off register_globals. Even with this off, you can still define global variables in your application.
In general programming terms, global variables (not PHP's register_globals) are considered "bad" because when you encounter one as a programmer, you have no idea what other parts of the application might be using or changing it, or what effect your changes to that global might have. Also, if you're defining a new global variable, there's a chance you're going to overwriting an existing variable that someone else is relying on. When variables are defined locally (in a single function, or in other languages a single block) you can examine the local scope and usually determine what a change to that variable will do.
Constants, on the other hand, never change. You define them once, and they stay defined and no one can change them. That's why having global constants is considered "less bad" than having global variables.
Constants, once defined, cannot be changed.
Don't use constants as variables. If you need to use variables within functions, pass them into the function itself. Use everything in the way it was intended to be used. Variables are variable and Constants are constant.
Some constant examples:
<?php
// Certainly constant
define('MINUTES_PER_HOUR', 60);
define('DOZEN', 12);
// Constant, but specific to this application
define('GREETING', 'Dear %s');
define('TIMEOUT', 30);
// Configurable, but constant for this installation
define('DATABASE', 'mydb');
define('IMAGES_DIRECTORY', '/tmp/images');
// Not constant, or some other reason why can't be constant
$user = $_POST['userid'];
$days_of_week = array('Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su');
?>
Something else to consider -- constants can't store things like arrays or objects, whereas something defined to $GLOBALS can be any variable type. So in some cases, if you need something to be global but it can't be stored to a constant by using define(), you might want to use $GLOBALS instead.
Also, register_globals and $GLOBALS are NOT the same thing!
You can change the global variable inside the function if both have a same name, because local variable override the global variable but does not change the value of global variable outside.in constant if you want to use same name variable in different function that not allowed to you and give a error,because it define one time and used in all program and you can not change the value of this variable in any function or block it is fixed value .
Try this simple test:
fileA.php:
<?php
define('SOMEVAL', 2);
?>
fileB.php:
<?php
if(defined('SOMEVAL')) echo SOMEVAL;
else echo "SOMEVAL does not exists\n";
include 'fileA.php';
if(defined('SOMEVAL')) echo 'SOMEVAL='.SOMEVAL;
else echo "SOMEVAL does not exists\n";
?>
Then run fileB.php and you'll see that before you include fileA.php, SOMEVAL is not defined. So what this means is that before you define anything, it won't be visible to the script.
Related
So I have recently learned about constants in PHP. fortunately there is not really anything to learn on them, they appear to be just an entity which stores value of something, just like a variable.
The only different that I can see (Correct me if I am wrong) is that a constant cannot be assigned a new value (that is it?). Which makes sense asthetically for example if you are making a config file with configurations that should not be changed.
But surely it brings other benefits/usage than just using a variable anyway?
In what situations should I be choosing to use constants?
If you find yourself setting a variable for convenience and never changing it during a script, the chances are you should be using a constant instead. Constants are like variables except that once they are defined they cannot be undefined or changed - they are constant as the name suggests. In many languages, constants are faster than variables and so are recommended, but this is not the case as much in PHP - although they are perhaps a small amount faster, the primary advantage to using constants is the fact that they do not have a dollar sign at the front, and so are visibly different from variables. Furthermore, constants are automatically global across your entire script, unlike variables.
To set a constant, use the define() function - it takes two parameters, with the first being the name of the constant to set, and the second being the value to which you wish to set it. For example, this following line of code sets the variable CURRENT_TIME to be the return value of the time() function, then prints it out:
define("CURRENT_TIME", time());
print CURRENT_TIME;
Note that it is not $CURRENT_TIME or Current_Time - constants, like variables, are case sensitive, but unlike variables they do not start with a dollar sign. You can change this behaviour by passing true as a third parameter to define(), which makes the constant case-insensitive:
define("CURRENT_TIME", time(), true);
print Current_TiMe;
There are two helpful functions available for working with constants, and these are defined() and constant(). The defined() function is basically the constant equivalent of isset(), as it returns true if the constant string you pass to it has been defined. For example:
define("CURRENT_TIME", time(), true);
if (defined("CURRENT_time")) {
/// etc }
Note that you should pass the constant name into defined() inside quotes.
A key characteristic of constants is that they behave like functions and classes, in the sense that they need to be defined when you try to use them, otherwise PHP will produce an error; and that they're global and unconcerned by scope. This makes them ideal for flags in function parameters, where the value is relatively unimportant, yet requires unique identification. Just look at how PHP itself uses constants:
json_encode($foo, JSON_UNESCAPED_UNICODE)
pathinfo($bar, PATHINFO_FILENAME)
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)
What would the alternatives be?
$pdo->setAttribute('errmode', 'exception')
Strings cannot be checked for existence the same way constants can, typos are easier and require more manual error handling inside the function, and strings cannot be introspected the same way you can introspect PDO for its constants, and hence discoverability of available options is reduced.
$pdo->setAttribute(1, 2)
Magic numbers are obviously even worse, with even less meaning and the same lack of enforcement and discoverability.
In these cases, constants are ideal. They provide an enforced, readable identifier for a meaning; the actual value the constant holds is relatively unimportant.
Constants are for when someone else might read and try to install your code, but doesn't know what bits they should change to add their own details in. It's especially useful if you don't have an installation script, as the new admin will need to set their own details.
Example:
You need to install a new script on your website that uses a database of some kind. You'd open up the main file, and edit the constants that you need to add in your database connection details. Because they're constants, you know they shouldn't change - And they shouldn't, otherwise your database wouldn't work! If you use variables, the values could be accidentally changed in the script. It's also clearer to know which parts you have to change - and as they're usually at the start of a document or in a separate file easy to identify as well.
An important note: $GLOBALS are dirty and evil. Don't use them. Ever. Never ever ever.
Please focus on the fact that it doesn't work and not why you would be doing this in the first place, it is purely a theoretical question about a technical exercise.
This is a rather weird one. I'm attempting to construct a variable variable using a string named $GLOBALS.
From the global scope
Let's see what we get when var_dump()ing this in the global scope.
$g = sprintf('%s%s%s%s%s%s%s', chr(71), chr(76), chr(79), chr(66), chr(65), chr(76), chr(83));
var_dump($$g);
The result is an array of global variables, which you can see here. Great! So, let's try this in a function.
From a function scope
First, let's just make sure that we can actually run an $GLOBALS check within a function.
function globalAllTheThings()
{
var_dump($GLOBALS);
}
globalAllTheThings();
The result is: it works!! You can see this here.
Now, let's try the first test that we used in the global scope, within the function, and see what happens.
function globalAllTheThings()
{
$g = sprintf('%s%s%s%s%s%s%s', chr(71), chr(76), chr(79), chr(66), chr(65), chr(76), chr(83));
var_dump($$g);
}
globalAllTheThings();
For simplicity's sake
You can also try this without the weird obfuscation (don't ask).
function globalAllTheThings()
{
$g = 'GLOBALS';
var_dump($$g);
}
globalAllTheThings();
It returns NULL. What's that about?? Why does it return NULL, and what can I do to get this working. Why, you ask? For educational purposes of course, and for science!
Because the manual says so:
Warning
Please note that variable variables cannot be used with PHP's Superglobal arrays within functions or class methods. The variable $this is also a special variable that cannot be referenced dynamically.
http://php.net/manual/en/language.variables.variable.php
It's simply "special". PHP is "special". Superglobals don't play by the same rules as regular variables to begin with. Someone forgot to or decided against making them compatible with variable variables in functions. Period.
I'm planning to expose some common variables as globals in my script and am wondering if the following naming scheme would be considered bad ideas:
using single underscore at the beginning and end like: $_some_var_
using triple underscore at the beginning like: $___some_var
I know that php uses single underscore at the beginning for superglobals and double underscore for magic methods so there shouldn't be any conflicts. Is there anything else that could cause trouble? And is doing this considered bad for any other reason?
Thanks!
It won't cause any problems per say. For ease of typing you may just want to go with the single underscore.
In my app, if I must introduce such globals that I may use in many scripts both inside and outside of functions, I use the $GLOBALS superglobal so it is very apparent that the variable being accessed is a global.
This also saves having to use global $somevar; in functions. But it is a lot more typing depending on how often you use them.
Could the values possible be constants or are they actually variable?
If you really think you need global state, how about creating a static class instead?
class myVars {
static property $var1;
}
If they are to be treated as constants then use:
define("CONSTANT_NAME", value)
If they are truly global variables, then one convention is:
$mVariableName
I have a php file in which I need to be able to easily flip a switch. The switch is set to 1 for local server and 0 for production server. local_on='1'; or local_on='0';. Which way is better (creating a global or using define)? If either way is good which way is best practice?
define. You can't change its value later, and its value is always available in all scopes, tersely.
A global variable is, as its name indicates, variable -- which means its value can be changed by any portion of your code ; which, in your case, is probably not what you want.
On the other hand, a constant (that you'll set with define) is... well... constant ; and, as such, cannot be modified once set ; which is probably what you want, in your case.
Considering the variable vs constant idea, for this kind of switches, I generally use define() and constants.
The define is the better choice of the two, because global variables are bad news for reasons I'm sure you're already familiar with, and because you have to remember to declare global $var in every function and method in your code. Defined constants are automatically available everywhere. Additionally, a variable could inadvertently be set from one state to the other during the running of your script. This could cause some really hard-to-find bugs if it happened.
Another way that performs a little better than define symbols and minimizes name clashes is a class declaration like
abstract config {
const LOCAL = true; // toggle to false
// or maybe
const SERVER = 'local'; // toggle to 'remote'
// (maybe having if (config.SERVER == 'remote') would be more readable in some
// cases than if (!config.LOCAL) depends on your app)
}
I prefer define. Reasons:
You can't redefine it accidentally
You can use in other scope (ex. functions) without ugly $GLOBALS construction
PS: since PHP 5.3 you can use const , not only define to declare constants. It's more readable for me
Both work fine as long as you remember to choose a distinctive name (all-uppercase for defines) and use the modern way to access global variables via the $GLOBALS superglobal (sic). Also, global variables are, well, variable, so you could, in theory, change its value by accident or so.
To simplify deployment and not setting or unsetting the switch by accident, I'd recommend automatically setting it automatically by examining the properties of $_SERVER, like
// Turn on debugging code on local machine
define('MYPAGE_LOCAL_ON', $_SERVER['SERVER_NAME'] == 'my-dev-box');
Also, I don't see why you'd set the switch to a string or an integer for that matter. The boolean values true and false seem more appropriate.
In short terms, define is what you look for (for said reasons).
However, come the future development, you might look for something like a dependency for your whole application providing the context it is running in. This can not be done with constants, so then define but as well as global variables are both wrong.
Say I've got a global variable which I'm accessing inside a PHP block, which compares to a querystring... if the comparison is true I want to set the value for a global EE variable so that all the other template pages can recognise that the value is not what it normally is - is this possible, or are the global user-defined variables constants?
Thanks,
Dan
$this->EE->config->_global_vars['foo'] = 'bar';
But keep in mind that the variable may have already been parsed before you have a chance to change it, depending on where and how it's used (see EE2's parse order discusssion).
You can use the PHP $GLOBAL Superglobal Array, for such cases. Say you have written a variable in any block of a particular page as $a = 123;.
Now in the same page, but in another block, you can easily change it to something else as $GLOBALS['a'] = 456;.
Hope it helps.