I am getting this error in Joomla:
Illegal variable `_files` or `_env` or `_get` or `_post` or `_cookie`
or `_server` or `_session` or `globals` passed to script
It's not an error PHP generates, it's an error that seems to belong to Joomla!. I found this page after 20 seconds of Googling for "Illegal variable".
The only solution that worked is to commnet out the following line in request.php file
Find the file /{your_joomla_folder}/libraries/joomla/environment/request.php
// $failed |= is_numeric( $key );
You'll see this error if you try to specify a URL parameter whose name consists solely of digits, e.g.
http://www.example.com/?1234567=test
or if you try to use a joomla-reserved variable, e.g.
http://www.example.com/?_files=test
It's not a great error message. If you have access to a unix terminal, you can debug these kind of problems with some command-line tools, e.g.
$ find /var/www/html -exec grep -l 'Illegal variable' {} \;
/var/www/html/libraries/joomla/environment/request.php
This is a fictional joomla installation, assuming a fairly standard DocumentRoot
. The result immediately confirms this is a Joomla error, and reports which file caused it. Extract from that file:
static $banned = array( '_files', '_env', '_get', '_post', '_cookie', '_server', '_session', 'globals' );
foreach ($array as $key => $value)
{
// PHP GLOBALS injection bug
$failed = in_array( strtolower( $key ), $banned );
// PHP Zend_Hash_Del_Key_Or_Index bug
$failed |= is_numeric( $key );
if ($failed) {
jexit( 'Illegal variable <b>' . implode( '</b> or <b>', $banned ) . '</b> passed to script.' );
}
...
}
Note that the error message is particularly misleading because, not only is in thrown in the case of a reserved variable name, but also if the parameter name is numeric.
I had to fix this for joomla 1.5
Here is how I did it
Find the file /{your_joomla_folder}/libraries/joomla/environment/request.php
And make the error friendlier
function clean()
{
JRequest::_cleanArray( $_FILES , false, 'FILES');
JRequest::_cleanArray( $_ENV , false, 'ENV' );
JRequest::_cleanArray( $_GET , false, 'GET' );
JRequest::_cleanArray( $_POST , false, 'POST' );
JRequest::_cleanArray( $_COOKIE , false, 'COOKIE' );
JRequest::_cleanArray( $_SERVER , false, 'SERVER' );
if (isset( $_SESSION )) {
JRequest::_cleanArray( $_SESSION , false, 'SESSION' );
}
$REQUEST = $_REQUEST;
$GET = $_GET;
$POST = $_POST;
$COOKIE = $_COOKIE;
$FILES = $_FILES;
$ENV = $_ENV;
$SERVER = $_SERVER;
if (isset ( $_SESSION )) {
$SESSION = $_SESSION;
}
foreach ($GLOBALS as $key => $value)
{
if ( $key != 'GLOBALS' ) {
unset ( $GLOBALS [ $key ] );
}
}
$_REQUEST = $REQUEST;
$_GET = $GET;
$_POST = $POST;
$_COOKIE = $COOKIE;
$_FILES = $FILES;
$_ENV = $ENV;
$_SERVER = $SERVER;
if (isset ( $SESSION )) {
$_SESSION = $SESSION;
}
// Make sure the request hash is clean on file inclusion
$GLOBALS['_JREQUEST'] = array();
}
function _cleanArray( &$array, $globalise=false, $type=null )
{
static $banned = array( '_files', '_env', '_get', '_post', '_cookie', '_server', '_session', 'globals' );
foreach ($array as $key => $value)
{
// PHP GLOBALS injection bug
$failed = in_array( strtolower( $key ), $banned );
$is_injection = false;
if($failed){
$is_injection = true;
}
// PHP Zend_Hash_Del_Key_Or_Index bug
$failed |= is_numeric( $key );
if ($failed) {
if($type){
$str = $type;
}else{
$str = implode( '</b> or <b>', $banned );
}
throw new Exception( 'Illegal variable <b>' . $str . '</b> passed to script.'.(($is_injection)?' (globals injection)': ' key "'.$key.'" is numeric in '.$str) );
//jexit( 'Illegal variable <b>' . implode( '</b> or <b>', $banned ) . '</b> passed to script.' );
}
if ($globalise) {
$GLOBALS[$key] = $value;
}
}
}
In my case an AJAX script was uploading files as
$_FILES = array(
0=>array(
[name] => 6767.bmp
[type] => image/bmp
[tmp_name] => /tmp/phpfbIzXU
[error] => 0
[size] => 12774
),
);
The 0 was causing problems, so because this was a minimal script I could simply transfer the info from $_FILES
to somewhere else before joomla loaded
for example like this:
$files = array();
foreach($_FILES as $f){
$files[] = $f;
}
$_FILES = array('files'=>$files);
... joomla launch code...
define( '_JEXEC', 1 );
define('JPATH_BASE', realpath(dirname(dirname(__FILE__).'/')));
define( 'DS', DIRECTORY_SEPARATOR );
require JPATH_BASE . DS . 'includes' . DS . 'defines.php';
require JPATH_BASE . DS . 'includes' . DS . 'framework.php';
Note that you can't use the variable $files
after including /includes/framework.php
as joomla will unhelpfully overwrite it with null