PHP, как использовать строку как суперглобальный - PullRequest
0 голосов
/ 14 апреля 2009

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

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

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

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

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

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

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

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

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

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

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

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

Ответы [ 5 ]

2 голосов
/ 14 апреля 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.

2 голосов
/ 14 апреля 2009

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

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

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

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

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

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

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

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

eval('return $_GET;');

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

1 голос
/ 14 апреля 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};
0 голосов
/ 14 апреля 2009

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

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

Теперь вы можете получить $GLOBALS['test'] в любом месте.

0 голосов
/ 14 апреля 2009

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

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

$var = null;
if (isset($_GET["varname"]))
{
  $var = $_GET["varname"];
}
else
{
  $var = $_POST["varname"];
}
...