PHP, как использовать строку как суперглобальную

Я создаю небольшой абстрактный класс, который должен упростить определенные задачи.

Например: $var = class::get('id'); будет запускать проверку наличия идентификатора указателя в $_GET, возвращая строку или массив в соответствии с параметрами. Это также должно работать для сообщений и запросов и многое другое.

Я делаю это так, как есть функция для всех суперглобалов. Я использую get в качестве примера:

Функция get получает указатель в качестве параметра, вызывает функцию fetchdata и использует указатель и "$_GET" в качестве параметров.

Предполагается, что fetchdata просто слепо использует полученную строку как суперглобальную и указывает на нее другим параметром. Затем проверьте, существует ли он там, и верните либо значение, либо ложь, чтобы получить функцию, которая возвращает значение/ложь вызывающей стороне.

Единственная проблема состоит в том, чтобы заставить строку работать как суперглобальную, когда вы не знаете, что это такое. Я сделал это раньше с помощью переключателя, который проверял параметр, и в случае, если он был «получен», он устанавливал $_GET в значение другой переменной. Однако я не хочу делать это так, я хочу, чтобы было легко добавлять дополнительные функции, не касаясь fetchdata.

Я попробовал $method = eval($method), но это не сработало. ($method = "$_GET"), есть предложения?

РЕДАКТИРОВАТЬ: Извините, если я недостаточно ясно выразился. У меня есть переменная X со строковым значением "$_GET", как мне сделать так, чтобы X получала значения из источника, описанного в строке?

Так просто это

$X = $_GET, если X имеет значение "$_GET"

$X = $_POST, если X имеет значение "$_POST"

Я просто не знаю, какое значение имеет X, но ему нужно получить данные из суперглобала с тем же именем, что и его значение.


person Removed_account    schedule 14.04.2009    source источник


Ответы (5)


Согласно этой странице руководства:

Примечание. Переменные переменные

Суперглобальные переменные нельзя использовать в качестве переменных переменных внутри функций или методов класса.

Это означает, что вы не можете сделать это внутри функции или метода (что вы могли бы сделать с другими переменными):

$var = '_GET';
${$var}[$key]

Вместо того, чтобы передавать строку в fetchdata(), не могли бы вы передать саму $_GET? Я думаю, что PHP не будет копировать переменную, если вы ее не измените («копировать при записи»), поэтому это не должно излишне использовать память.

В противном случае существует только девять суперглобальных переменных, поэтому случай переключения, как вы предложили, не является необоснованным.

Вы можете сделать это с помощью eval(), если вам действительно нужно, что-то вроде:

eval('return $_GET;');

Я думаю, что это было бы ненужным и плохой идеей; это медленно, и вы должны быть чрезвычайно осторожны, чтобы не допустить рядом с ним ненадежные строки.

person Tom Haigh    schedule 14.04.2009

Не используйте eval. Просто используйте ссылку.

//test value for cli
$_GET['test'] = 'test';

/**
 * @link http://php.net/manual/en/filter.constants.php reuse the filter constants
 */
function superglobalValue($key, $input = null) {
    if ($input === INPUT_POST)
        $X = &$_POST;
    else
        $X = &$_GET;
    return (isset($X[$key]) ? $X[$key] : false);    
}

function getArrayValue(&$array, $key) {
    return (array_key_exists($key, $array) ? $array[$key] : false); 
}

//test dump
var_dump(
    superglobalValue('test', INPUT_GET),
    superglobalValue('test', INPUT_POST),
    getArrayValue($_GET, 'test'),
    getArrayValue($_POST, 'test')
);

$_GET, $_POST и $_REQUEST по умолчанию не имеют нулевых значений, только строки или массивы. Поэтому я использовал там isset вместо array_key_exists.

Порядок параметров: я всегда ставлю обязательные параметры перед необязательными, когда могу, и объекты данных перед параметрами манипуляции/субъективными параметрами. Вот почему ключ является первым параметром для superglobalValue и вторым параметром для getArrayValue.

person OIS    schedule 14.04.2009

Я не совсем уверен, чего вы пытаетесь достичь, но вы могли бы взглянуть на магический метод __callStatic

class example{
 protected static $supers = array('GET', 'POST', 'SERVER', 'COOKIE');
 public static function __callStatic($functionName, $arguments){
  $index = arguments[0];
  $desiredSuper = strtoupper($functionName);
  if(in_array($desiredSuper, self::$supers)){
   doStuff ( $_{$desiredSuper}[$index] );
  }
  else{
    throw new Exception("$desiredSupper is not an allowed superGlobal");
  }
 }
} 

вы могли бы сделать:

 example::get('id'); //wo do stuff to $_GET['id']
 example::server('REQUEST_METHOD'); //Will do stuff to $_SERVER['REQUEST_METHOD']
 example::foo('bar'); //throws Exception: 'FOO is not an allowed superGlobal'

Руководство Php по магическим методам: http://ca.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.methods

Изменить
Я только что заметил ваше изменение, вы можете попробовать:

 $X  = {$X};
person Pim Jager    schedule 14.04.2009

Вы можете использовать $_REQUEST["var"] вместо $_GET["var"] или $_POST["var"].

Более сложным способом было бы проверить, существует ли переменная в массиве GET, если нет, то ее POST. Если это так, GET.

$var = null;
if (isset($_GET["varname"]))
{
  $var = $_GET["varname"];
}
else
{
  $var = $_POST["varname"];
}
person SvenFinke    schedule 14.04.2009

Если вы хотите, чтобы переменная была доступна глобально, вы можете добавить ее в массив $GLOBALS.

$GLOBALS['test']='test';

Теперь вы можете получить $GLOBALS['test'] где угодно.

person Ali    schedule 14.04.2009