What is the purpose of session_unset()? - php

As far as I am concerned session_unset() has no hidden features. The behavior is identical to $_SESSION = [];. Why was this function added to PHP 4? Why has it not been deprecated yet if its use is not recommended and there is no benefit to using it? Does it affect the GC in some way?
PHP C code where the function is defined: https://github.com/php/php-src/blob/master/ext/session/session.c#L2519

It would matter to you if you were using a deprecated session variable, namely $HTTP_SESSION_VARS.
Version Description
4.1.0 Introduced $_SESSION that deprecated $HTTP_SESSION_VARS.
1
session_unset() is used to clear all of the Session info $HTTP_SESSION_VARS contains without destroying the Session itself. However,
(Note that $HTTP_SESSION_VARS and $_SESSION are different variables and that PHP handles them as such)
Hence why session_unset() is useless when using the $_SESSION superglobal instead. I can't say it's that surprising that the session_unset() function is not deprecated while $HTTP_SESSION_VARS is, although I couldn't tell you exactly why that is.

Related

Is $HTTP_XXX_VARS different from $_XXX in PHP?

Does the following code make sense?:
$t_server = isset( $_SERVER ) ? $_SERVER : $HTTP_SERVER_VARS;
As I understand, $HTTP_XXX_VARS is same with $_XXX, except $HTTP_XXX_VARS is deprecated. Thus, I don't understand the code above.
Is there a case that two variables are different in an old system in which $HTTT_XXX_VARS is not considered as deprecated?
$HTTP_SERVER_VARS and $_SERVER are different variables (if both are set). They initially contain the same values but, being different, the changes that the script does on one of them do not affect the other.
The superglobals ($_GET, $_POST, $_SERVER etc) were introduced on PHP 4.1. The long named variables ($HTTP_GET_VARS, $HTTP_SERVER_VARS etc) were deprecated on PHP 4.1 and they were removed on PHP 5.4.
PHP 5.0 introduced the configuration setting register_long_arrays that was used to tell PHP to create (or not) the old long-named variables ($HTTP_GET_VARS and the rest). The setting was deprecated on PHP 5.3 and removed altogether on PHP 5.4 (together with the long-named arrays).
As you can see, between PHP 4.0 and PHP 5.4 one or both versions of these variables were available to the programmer.
The line:
$t_server = isset( $_SERVER ) ? $_SERVER : $HTTP_SERVER_VARS;
takes advantage of the new superglobal variable $_SERVER, if available (on PHP >= 4.1), but it falls back to the old $HTTP_SERVER_VARS if it runs on older PHP. It was probably written years ago, while PHP 4 was still in use on a lot of servers.
Except on the unlikely case when you are stuck with PHP 4.0, you can safely change the above line to:
$t_server = $_SERVER;
or just use $_SERVER instead of $t_server everywhere.

Is session_unset() deprecated?

In the PHP documentation for session_unset() there is no hint that this function is deprecated so I think it's fine to use it. But then I read through the documentation about session_destroy() where I found this hint:
Note:
Only use session_unset() for older deprecated code that does not use $_SESSION.
I know that the session_unset() function is an equivalent for $_SESSION = array();. So what should I use now? Why is on one site a hint that this function is deprecated but on the other hand in the documentation about the function itselfs there is not deprecated note. What's the truth about this function now?
I don't know the exact reason, too, but it can be found here I guess: https://github.com/php/php-src/blob/master/ext/session/session.c
PHP handles variables in ZVAL pointers and I think they just wanted the _SESSION superglobal to be handled the same way as any other variable, and not with a "special" command session_unset().
Another benefit is better garbage collection handling I think.
Sometimes, "deprecated" does not mean its a bad function, but you should not use it because code might be removed in future packages simply because it is not neccessary.
If you want to close the session you must use session_destroy().
session_destroy();
If you want to clear the variables of the session you must use:
$_SESSION = array();
And if you want to clear only one variable of the session you must use:
unset($_SESSION['example']);

PHP extracting without extract()

I have something like:
if(isset($_POST['submit']))
{
$linktitle=strtolower(str_replace(" ","-",$title));
etc.
$linktitle and $title are actually variables from $_POST - ie $_POST['linktitle'] and $_POST['title'].
Somehow, even though (as far as I can see!) I haven't extract()ed $_POST at this stage in the code, it is still working - PHP is understanding that $title is referring to $_POST['title']. Could anyone please explain why this might be?
Thanks!
ps. Sorry, but I really can't get this inline code quote formatting thing to work...!
register_globals is enabled in your PHP instance. See here for more info.
This is behaviour that should be relied upon as it's use is now deprecated. You will find that you can still use $_POST['keyname'] as well as $keyname, and that is what you should refer to in your code.
Your php.ini file must have register_globals enabled, so GPC variables are being added to the symbol table. This is why you see this behaviour. See the security risks of such a feature here
You have register globals activated in your webserver (php.ini), so PHP replace the unknoe variables with the corresponding GET or POST value. This option is deprecated and dangerous! Disable it if you can!

PHP 5.3 support for strange '${}' code?

I've just upgraded to PHP 5.3 and started supporting an old website for a new client. It seems to use rather odd PHP code which I've not come across before.
Whilst trying to access $_GET or $_REQUEST variables, the developer has used the following: ${"variable_name"}
I get notices generated due to undefined variables (presumably because PHP is not parsing the ${"variable_name"} style code).
Changing this to $_REQUEST['variable_name'] works as expected, but I can't go through all their code and change it as the site is massive and uses proprietry layout methods.
Does anyone know if it's possible to switch on support for these tags / codeblocks? I've taken a look in PHP.ini and there is a mention of ASP style tags and short tags but enabling these has no effect (they look totally different anyway, I just thought it was worth a shot).
I don't think there is anything new with that syntax :
$a = 10;
var_dump(${"a"});
Works just fine ;-)
You problem is probably due to the fact that, before, register_globals was enabled (by default, if PHP <= 4.something), and is now disabled -- and that is good for security !
With register_globals set to On, any variable in $_REQUEST is automatically injected as a vartiable in your application -- well, actually, this depends on the variables_order configuration option, but this one almost always includes Get, Post, and Cookie, at least.
For instance, if there is a variable like $_GET['my_var'], you will also have a $my_var variable... And this one can also be accessed with the syntax ${'my_var'}
Considering register_globals is Off by default since something like PHP 4.2, and should disappear in PHP 6 (if I remember correctly), I would advise against re-activating it... at least, if you have the time required to correct / test the code...
Curly brace syntax for variables is an embedded part of PHP, and has been around for quite awhile. The reason it exists is to resolve ambiguities with arrays and object syntaxes when using variable variables.
From the manual:
In order to use variable variables
with arrays, you have to resolve an
ambiguity problem. That is, if you
write $$a1 then the parser needs to
know if you meant to use $a1 as a
variable, or if you wanted $$a as the
variable and then the 1 index from
that variable. The syntax for
resolving this ambiguity is: ${$a1}
for the first case and ${$a}1 for
the second.
It's a very handy syntax in several situations, such as using array or object variables while outputting something using heredoc syntax.
I won't reiterate the advice by others about using register_globals, I just wanted to expound on this unusual syntax.
The ${"variable_name"} syntax is practically the same as $variable_name, except that the contents of the curly braces are evaluated first. It is supported by all recent versions of PHP, even the beta versions. What is not supported by recent versions of PHP though is the support of registering $_REQUEST (and other) variables as global variables. There's a setting for enabling it:
register_globals = on
It is NOT recommended for production use because of security issues though. It may be easier to run you source through some 'sed'-like tool and replace the usages with regular expression.
The old server probably has REGISTER_GLOBALS on. So the weird brackets aren't the problem.
REGISTER_GLOBALS puts all the variables in $_REQUEST as regular variables in the global scope, meaning you can access $_REQUEST['test'] can be accessed like $test or ${"test"}
The bracket syntax is on by default, and I don't believe you can turn it on/off.
register_globals was likely switched on. {$variable_name} syntax is always on, but register_globals turns things like $_REQUEST['variable_name'] into $variable_name.
Avoid switching it on if at all possible, though - there's a reason it's been long advised against, and it's going away entirely in PHP6.
register_globals is deprecated as of php 5.3 and will be removed as of php 6.0. What you want to do is use the Refactoring feature found in most PHP IDE's (zendo studio 6+) to rename the variable to something more appropriate, ie $_GET['variable_name'].

$var instead of $_GET['var'] in PHP?

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.

Categories