Ok I cannot remember the details on this but on some servers you can use
$var instead of $_GET['var'] to access a variable in the URL, I know this is BAD but I can't remember why it is bad?
I think you mean Register Globals.
You shouldn’t use them because you cannot distinguish the source of that variable values since they can come from any source of the EGPCS variables (Environment, GET, POST, Cookie, Server).
So if you have a the $var, you cannot say if the value is either from $_ENV['var'], $_GET['var'], $_POST['var'], $_COOKIE['var'] or $_SERVER['var'].
The feature is called Register Globals and it allows people to inject variables into your code. See the documentation for examples; here's one:
<?php
// define $authorized = true only if user is authenticated
if (authenticated_user()) {
$authorized = true;
}
// Because we didn't first initialize $authorized as false, this might be
// defined through register_globals, like from GET auth.php?authorized=1
// So, anyone can be seen as authenticated!
if ($authorized) {
include "/highly/sensitive/data.php";
}
?>
You can use that if your server has register_globals set to 1 (or true) on the php.ini file.
At some point, this started to be off by default, and applications started to break, which is a reason why this is a bad practice.
You can see a list of php.ini variables here.
It's also bad because you can confuse yourself with the way that PHP will scope your variables. You may wind up overwriting data if you aren't careful. Also, using $_GET is much clearer as to what you are attempting to accomplish.
Because letting people inject values into arbitrary variables is a very bad thing. You could be storing anything there and they could overwrite some value that compromises your security. Remember to use isset to check that a value has been set before trying to use it.
It's bad because if you're not careful to initialize every variable before you use it (something that PHP won't force you to do), people can easily cause your code to do Very Bad Things with a request as simple as /myapp/index.php?admin_privileges=1.
The setting is called REGISTER_GLOBALS and it was discussed here:
Why is REGISTER_GLOBALS so bad?
If you can do that, then "register_globals" is turned on. This is bad because you won't know where a variable came from, and it mixes your variables with the ones any user can inject via the URL. Read more here: http://www.php.net/manual/en/security.globals.php
Once you get used to using $_POST, $_GET, etc your code's purpose will be easier to read and much, much easier to maintain.
Register globals would work but it's going to go away in a future version of PHP. Not to mention that it really is wrong to have it enabled.
You can use extract() for a more controlled behavior. It will extract the keys from an array (in this case, $_GET) into the local context as variables. You can give them a common prefix so that they don't collide with your existing variables. And you can filter the array beforehand to make sure you're only getting the expected variables.
int extract( $var_array [, $type = EXTR_OVERWRITE [, $prefix ]] )
Import variables from an array into the current symbol table.
Related
First of all, I heard some web-servers allow you to reach parameter with $a instead of $_GET[a], this is not the case here.
Anyway, I have to reach a multiple times, so instead of doing $a = $_GET[a], I instead use $_GET[a] everytime. In single php tag as in <?php ?>, is that an issue, should I absolutely use variables? does it matter?
Another thing is my php file is really scrambled in my html, I wonder if does it matter with multiple gets?(should not, im just worried)
Thanks.
What you refer of using just $a instead of $_GET['a'] (or $_POST['a'] too) is an old feature known as register_globals. This feature was dangerous and leading to messy code, so it was considered deprecated in PHP 5.3 and finally removed in PHP 5.4.
Then, using $_GET['a'] everywhere in your scripts may lead to problems, because you should never trust user input (all things coming from $_GET, $_POST, $_REQUEST, $_COOKIE and some from $_FILES or $_SERVER). It is recommended to do something like $a = sanitize($_GET['a']); (the sanitize function does not exist, depending on what type of value are you expecting, you should check that what you get is an integer, or a valid date, or whatever, depending on your needs). From now on you should stop referencing $_GET['a'] and use instead the new sanitized variable you have just created $a. Because if you were using always $_GET['a'], chances are that you forget to sanitize it someplace.
Also, before sending this sanitized variable into a SQL query, you should escape it or use it inside a prepared statement to avoid SQL injections. Before outputting it to an html for the user to see, use htmlspecialchars to avoid XSS attacks.
And finally, about having multiple php blocks mixed with html blocks, this is only bad for maintenance reasons, because in the long run it will be a complete mess. Try to separate the html you send the user from the php code. Try to read something about the MVC pattern (Model-View-Controller) (this link is probably too complicated or maybe you don't see the utility right now for you that are just beginning with php (at least I didn't see how it was way better than mixing html with php, for all the complexity needed), but try to grasp the idea behind it) .
First of all, I heard some web-servers allow you to reach parameter with $a instead of $_GET[a], this is not the case here.
This is a PHP config setting called register_globals. It is insecure and should NOT be used. See this question for more information.
You can access an element in the $_GET array as many times as you like, it will not cause problems. However if you are printing an element of the $_GET array (or any other user submitted data) to the page, you should run it through htmlspecialchars() or the like before printing it out to prevent XSS vulnerabilities.
using a variable is a preference for you to decide it does not matter. but variable is the way forward if you use the same one multiple times.
<?php echo htmlspecialchars($_GET['a']);?>
using a variable means that it reusable again especially if you have added extra code, which mean just editing one variable for all instances.
<?php $a = htmlspecialchars($_GET['a']);
echo $a;
echo $a;
echo $a;
echo $a;
?>
I have many session vars. Should I use this
$_SESSION[SessionHelper::ROUTING] = SessionHelper::MODULE_A;
class SessionHelper {
const ROUTING = 'SessionHelper.routing';
const MODULE_A = 1;
const MODULE_B = 2;
}
or this?
$_SESSION['routing'] = 1;
The first seems to be maintenanable but hard to read in some case. For example:
if(isset($_SESSION[SessionHelper::ROUTING]) &&
$_SESSION[SessionHelper::ROUTING] = SessionHelper::MODULE_A) {
....
The second is quite short but if there is a change, we must change everywhere the "routing" exist. Further more, it can pollute the session scope because the 'routing' string is so common.
If you really need a session helper (say: if you really need a class abstracting a PHP session), then use the $_SESSION superglobal only inside that class (and not outside). So you have the superglobal encapsulated and you can replace it with test-doubles.
Next to that, this depends on the use of the session store. I bet it's highly dynamic, so I don't see much value in specifying array keys as constants first w/o any futher use (e.g. valid/invalid key checks aren't done).
I hope this does not sound harsh, because it's not meant so. Please ask if something is unclear or you have further questions. As jprofitt wrote in his answer, preventing magic numbers is something very useful, but I'm not totally convinced, that you actually introduce them here or if it isn't just dynamic properties (especially if you create a session store class).
Magic strings and numbers are evil -- even if you're the only one who would need to use them. All it takes is forgetting to update them in one place and your entire application could malfunction.
As you mentioned with the maintainability of using constants, they can make implementing updates a lot simpler. Another benefit is you can document them and a lot of IDEs will pick that up and give help in case you forget what MODULE_A or MODULE_B is referring to (for example). While it might make you type in some extra characters, it's better than misspelling 'routing' somewhere and having to dig through your code to figure out why you're getting an error.
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.
I am trying to have a function that among other things declares global variables based on a variable that i give it.
the part that fails is making the variables global
function setGlobalVariable($name) {
global $name, $arrayname_{$name};
}
any idea?
thanks :)
Really, stop messing with global variables that way.
Anywaym here's your solution if you really want to do that:
function setGlobalVariable($name) {
$GLOBALS['arrayname_' . $name] = 'yourvalue';
}
You should not do that. Global variables are in general a sign of poor design. What is it that you are trying to achieve? I am sure that there is a better solution. Besides that, global does not work like that. global makes other variables outside your function locally available. Use $_GLOBAL to create globals.
Take a look at the Registry Pattern (http://martinfowler.com/eaaCatalog/registry.html).
A well-known object that other objects
can use to find common objects and
services.
There are various PHP implementations, for example Zend_Registry: http://framework.zend.com/manual/en/zend.registry.html
You're almost right, but not quite; a variable variable takes the form of ${"name"}, so what you're looking for is something like global ${"arrayname_$name"};.
http://www.reddit.com/r/programming/comments/dst56/today_i_learned_about_php_variable_variables/c12np38 is fascinating reading on the topic, if you feel so inclined.
It's likely a terrible idea, though, and if you're resorting to that sort of thing, it's a good indication that your code may be poorly designed. Consider refactoring it (for example, to keep a single known array that your other arrays are kept in, and may be referenced by key.)
I trying to understand if a isset is required during form processing when i check $_REQUEST["input_name"] if no value is passed it doesn't cry about it and php doesn't throw out an error if you are trying to access a array item which doesn't exist....i can use if($_REQUEST["input_name"])..
what about "empty" even in those cases i can use if()
THnks
I wouldn't recommend using the $_REQUEST superglobal for capturing form input, unless you're testing a form. Use $_GET or $_POST instead, unless you have a really good reason.
Also, isset() and array_key_exists() both do the same trick with regard to array keys, although array_key_exists() is clearer in an arrays context.
I recommend using:
error_reporting(E_ALL); //E_ALL - All errors and warnings
within your development environment, as that can expose where better practices might be applied, such failure to declare variables before they are used, etc.
There are different type of error levels. Checking a variable that is not set only throws a notice. Your error reporting is probably set to ignore those. It is best practice to always use isset when you want to check if a variable has been set, although it does have its gotchas.
Doing only what you are doing above, for example, if $_REQUEST["input_name"] is the string "0", it will evaluate to false. Also it is not a good idea to use $_REQUEST to begin with, as it can be affected by stuff like cookies and such and it's usually a code smell for bad architecture.
using $_REQUEST is pretty much a hack. You should be using $_POST or $_GET (depending on what you are doing) and you should use isset().
Every book I've read on PHP seems to say that.
Generally, at least for testing, set error reporting to E_ALL (all errors and warnings) either in your php.ini or in code using error_reporting(E_ALL); (Look into adding E_STRICT too.) Better to get an obvious notice about an error up front, than to have something subtle go wrong that you don't catch till later.
Avoid using $_REQUEST, which is too vague (it includes GET, POST AND cookie values), and use the $_POST or $_GET if those are what you really mean, and do check with isset($_POST["input_name"])
The short answer is "Yes." :)
if($_REQUEST["input_name"])
will throw a notice (error) if "input_name" doesn't exist, so isset() is recommended.