Is $HTTP_XXX_VARS different from $_XXX in PHP? - 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.

Related

What is the purpose of session_unset()?

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.

HTTP_POST_ARRAYS long variables not working in php5.4

I have some legacy code to modify in PHP5.4, the script was originally written in PHP4.0.
The problem arises when we try to login.
HTTP_POST_VARS is not recognized and these post and get variables need changing to $_POST and $_GET in the entire script which is worth 30-40 script files.
Could someone share any ideas on how to change all the long variables to short $_POST kind.
I tried to turn on register_long_arrays in php.ini file, but it is already on and not sure what else to be done.
The register_long_arrays directive does no longer exist:
This directive became available in PHP 5.0.0. [...] This feature has
been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0.
Any decent editor out there should provide a "Replace in files" menu item (which is normally under "Edit", "Search" or a similar location). With that, it should be a 2 minute task because HTTP_POST_VARS is a long name that won't cause much ambiguity.
You appear to be using phpDesigner. You can find a screen-shot in their site (scroll down to "Advanced search and replace").
Edit: You seem to have panic to text editors so another alternative is to create the missing variables yourself:
$HTTP_GET_VARS = &$_GET;
$HTTP_POST_VARS = &$_POST;
$HTTP_POST_FILES = &$_FILES;
$HTTP_SERVER_VARS = &$_SERVER;
$HTTP_SESSION_VARS = &$_SESSION;
$HTTP_ENV_VARS = &$_ENV;
$HTTP_COOKIE_VARS = &$_COOKIE;
You can place this code on top of your application's main settings file, which you hopefully have (otherwise, and considering that search & replace is apparently not an option, you'd need to put the stuff in a new *.php file and get it magically loaded with the auto_prepend_file PHP directive).
Please note we're using & to assign references so paired variables remain in sync (that's specially important to make $HTTP_SESSION_VARS actually work).
Of course, $HTTP_... variables were not superglobals. If you don't really understand the code, you can get faced to subtle bugs.
`$HTTP_GET_VARS = &$_GET;
$HTTP_POST_VARS = &$_POST;
$HTTP_POST_FILES = &$_FILES;
$HTTP_SERVER_VARS = &$_SERVER;
$HTTP_SESSION_VARS = &$_SESSION;
$HTTP_COOKIE_VARS = &$_COOKIE;`
put them all in config(settings) file before database valid functions start and its applicable to all the scripts belonging to the folder.

PHP ignoring returned reference from function considered harmful?

Derick Rethans has an old article that says:
Please do note that it is harmful not to accept a reference from a
function that returns a reference. In some cases, PHP will get
confused and cause memory corruptions which are very hard to find and
debug. It is also not a good idea to return a static value as
reference, as the PHP engine has problems with that too. In PHP 4.3,
both cases can lead to very hard to reproduce bugs and crashes of PHP
and the web server. In PHP 5, this works all a little bit better. Here
you can expect a warning and it will behave “properly”.
Does it mean that in PHP 5 we are allowed to ignore the returned reference from a function?
By that, I mean this:
function &GetRef(&$array){
$item =& $array[0];
return $item;
}
$array = array(0, 1, 2);
$item =& GetRef($array); /* Normal usage of the function using assign by reference
also known as "accepting" the reference. */
$item = GetRef($array); /* Notice that here we didn't assign by reference.
Are we allowed to ignore the returned reference
and simply do normal assignment? */
The PHP Manual states:
Unlike parameter passing, here [return by reference] you have to use &
in both places - to indicate that you want to return by reference, not
a copy, and to indicate that reference binding, rather than usual
assignment, should be done for $myValue.
It doesn't explicitly say that we must accept the returned reference.
Does it mean that we are free to ignore returned references?
As discussed in the comments, you should generally ignore at least that section in the linked article, if not the entire thing.
The article talks about references in the context of PHP 4.3, released in December, 2002 and EOL'd at the end of 2007. PHP 4 should never be used today. As a general rule, when it comes to learning about working with PHP, you should not trust any article that targets PHP versions older than 5.2 (as of mid-2013).
PHP 5.0 features Zend Engine 2, a new virtual machine on which PHP runs. This is where references are implemented. 5.1 introduces some backwards-incompatible changes with regard to manipulation of return values. 5.3 introduces real garbage collection and deprecates both call-time pass-by-reference and assigning new by reference. These important changes are not addressed by that prehistoric article.
Does it mean that in PHP 5 we are allowed to ignore the returned reference from a function?
Yes. Modern PHP versions have no problem with discarding the return value of any function, reference or not. If you encounter behavior that seems to contradict this expectation, create a reduced test case and file a bug with the PHP maintainers.
Also, think twice before using references in your code. Passing around references will not save time, will not save memory and will not increase performance except in rare cases. Use them sparingly to keep complexity under control.

PHP 5.2 permitted object syntax to call array index?

We recently had a disaster and had to move our php web application from PHP Version 5.2.6-1+lenny16 to PHP Version 5.3.3-7+squeeze15 and found a seemingly important difference.
In our application, there were instances where we incorrectly called an array's index using object syntax:
echo $array->index;
However, 5.2.6 seemed to forgive this, and correctly treat it as if $array['index'] was written.
Upon further testing, what 5.2.6 is specifically doing is disagreeing with 5.3.3 as to whether $array->index is empty();
Here is the test code I've run on both servers:
<?php
echo phpversion() . '<br>';
$array = array(
'x' => 1,
'y' => 2
);
if (!empty($array->x))
{
echo "not empty";
}
else
{
echo "empty";
}
?>
Here are the two different outputs:
5.2.6-1+lenny16
not empty
5.3.3-7+squeeze15
empty
Naturally, there are now a few outbreaks of broken functionality because we were never alerted to these errors during development. Is there a way we can configure php 5.3 to permit this incorrect syntax while we take a bit more time to find all the incorrect instances of it?
I don't think it's a configuration issue, is it? Was something changed in the way empty() works in between versions?
I just have put your example code to a general test across PHP versions (test) and it shows that you are correct, there are differences:
From PHP 5.0.0 up to 5.2.11 (and also early 5.3.0 to 5.3.1), this "undefined property" was reported as not empty which does qualify as a flaw or bug.
The related change in 5.2.12 (17 Dec 2009) was (ref):
Fixed bug #50255 (isset() and empty() silently casts array to object). (Felipe)
Technically this is not a backwards incompatible change from PHP 5.2 to 5.3 because it was a flaw in both branches and also fixed in both. Those are harder to spot if you migrate, because the standard migration guide does not cover them. Instead you need to go through the changes of the software and look for notes and references to tickets.
So to answer your question: This is a configuration issue because the PHP version used counts as configuration. You changed the configuration and then you had the issue.
Also as the report shows, this is limited to empty() and isset(), not general object/array access. As you can imagine, if that would have been the case, you would have found much more reference about it.

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'].

Categories