2010-08-16 7 views
8

Итак, я не родом из огромного PHP-фона, и мне было интересно, если в хорошо сформированном коде нужно использовать «суперглобалы» напрямую, например. в середине некоторой функции говорят $_SESSION['x'] = 'y'; или если, как я обычно делаю с переменными, то лучше отправить их в качестве аргументов, которые могут быть использованы оттуда, например:Является ли использование суперглобаллов прямо хорошим или плохим в PHP?

class Doer { 
    private $sess; 
    public function __construct(&$sess) { 
     $this->sess =& $sess; 
    } 
} 

$doer = new Doer($_SESSION); 

, а затем использовать версию Doer->sess из внутри Doer и тому подобное. (Преимущество этого метода состоит в том, что он ясно показывает, что Doer использует $ _SESSION.)

Каков приемлемый подход к разработке PHP для этой проблемы?

+5

Переведите нужные данные в переменные после их проверки, так как данные в нем есть подозрение до подтверждения. –

+0

Ваш подход необычен, и наложение суперглобала на локальный атрибут может смутить разработчиков кода. Но это, конечно, законно, и если ваш объект использует или фильтрует его (например, помощник конфигурации), вероятно, хорошая идея. – mario

ответ

13

Мне нравится обертывать $_SESSION, $_POST, $_GET и $_COOKIE в структуры ООП.

Я использую этот метод, чтобы централизовать код, который обрабатывает санитарию и проверки, все необходимых isset() проверок, одноразовые номера, setcookie параметров и т.д. Это также позволяет клиентский код более читаемым (и дает мне иллюзию, что это более ремонтопригодно).

Возможно, будет сложно обеспечить использование такого типа структуры, особенно если имеется несколько кодеров. С $_GET, $_POST и $_COOKIE (я считаю), ваш код инициализации может скопировать данные, а затем уничтожить суперглобал. Возможно, умный деструктор может сделать это возможным с помощью $ _SESSION (стереть $ _SESSION при загрузке, записать его обратно в деструктор), хотя я не пробовал.

Я обычно не использую ни одно из этих методов защиты. После привыкания к нему, видя $_SESSION в коде вне класса сеанса, просто выглядит странно, и я в основном работаю соло.

EDIT
Вот некоторый код клиента образец, в случае, если это помогает кому-то. Я уверен, глядя на любом из основных структур дадут вам лучшие идеи ...

$post = Post::load(); 
$post->numeric ('member_age'); 
$post->email ('member_email'); 
$post->match ('/regex/','member_field'); 
$post->required ('member_first_name','member_email'); 
$post->inSet ('member_status',array('unemployed','retired','part-time','full-time')); 
$post->money ('member_salary'); 
$post->register ('member_last_name'); // no specific requirements, but we want access 
if ($post->isValid()) 
{ 
    // do good stuff 
    $firstName = $post->member_first_name; 
} 
else 
{ 
    // do error stuff 
} 

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

Внутри класса хранится набор достоверных данных, извлеченных из $_POST при вызове методов проверки, а затем возвращает их как свойства с использованием магического метода __get. Невозможно получить доступ к полям с ошибкой.Мои методы проверки достоверности (кроме required) не сбрасываются при пустых полях, и многие из них используют func_get_args, чтобы позволить им работать с несколькими полями одновременно. Некоторые из методов (например, money) автоматически преобразуют данные в пользовательские типы значений.

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

Одним из способов улучшить это было бы сохранение информации о проверке в классе формы, которая используется для визуализации проверки формы и мощности на стороне клиента, а также для очистки данных после отправки.

+0

** Gimme! ** Вы опубликовали бы свои обертки OOP для входных массивов? Я использую нечто похожее и хотел бы сравнить подход с чем-то сопоставимым. – mario

+0

@mario: Я не могу опубликовать код, но я могу немного разобраться, чтобы дать вам представление. Теперь я отредактирую ответ. – grossvogel

+1

все в порядке. Но мой здесь для сравнения: https://sourceforge.net/p/php7framework/wiki/input/ - просто хотел узнать, какие утилиты вы используете, или какие фильтры вы считаете наиболее полезными. – mario

-3

Это нехорошее использование PHP.

получить $ _SESSION переменные непосредственно:

$id = $_SESSION['id']; 
$hash = $_SESSION['hash']; 

т.д.

+1

И получить хороший E_NOTICE, если переменная не существует в массиве ... -> -1 – ThiefMaster

+0

Как вы все равно получаете $ _SESSION? – Aziz

0

я бы не рекомендовал на всех проходящих суперглобальный по ссылке. В вашем классе неясно, что то, что вы изменяете, является переменной сеанса. Кроме того, имейте в виду, что $ _SESSION доступна везде вне вашего класса. Это так неправильно с объектно-ориентированной точки зрения, чтобы иметь возможность модифицировать переменную внутри класса извне этого класса, изменяя переменную, не связанную с классом. Наличие публичного атрибута считается плохой практикой, это даже хуже.

2

Изменение содержания суперглобалов считается плохой практикой. Хотя в этом нет ничего плохого, особенно если код на 100% под вашим контролем, это может привести к неожиданным побочным эффектам, особенно если вы рассматриваете смешанный исходный код. Например, если вы делаете что-то вроде этого:

$_POST['someval'] = mysql_real_escape_string($_POST['someval']); 

можно было бы ожидать, что везде PHP делает это «someval» доступны также изменяются, но это не так. Копия в $_REQUEST['someval'] не изменится и останется оригинальной «небезопасной» версией. Это может привести к непреднамеренной инъекционной уязвимости, если вы выполняете все ваши экраны в $ _POST, но в более поздней библиотеке используется $ _REQUEST и предполагается, что она уже сбежала.

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

2

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

классы mario для обработки входов являются удивительными.

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

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

Например,

Допустим, вы создали класс Session, специфичные для вашего приложения.

class Session 
{ 
    //some nice code 
} 

Вы могли бы написать что-то вроде следующего

$session = new Session(); 
if($session->isLoggedIn()) 
{ 
    //do some stuff 
} 

В отличие от этого

if($_SESSION['logged'] == true) 
{ 
    //do some stuff 
} 

Это кажется немного тривиально, но это большая проблема для меня. Скажите, что когда-нибудь в будущем я решаю, что хочу изменить имя индекса от «logged» до «loggedIn».

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

Или что, если я хочу проверить, что этот пользователь является администратором и выполнил вход?Для этого я могу проверить две разные переменные в сеансе. Но вместо этого я мог инкапсулировать его в один метод и сократить код.

Это помогает другим программистам смотреть на ваш код, потому что это становится легче читать, и им не нужно «думать» об этом, когда они смотрят на код. Они могут перейти к методу и увидеть, что есть только один способ иметь зарегистрированного пользователя. Это также помогает вам, потому что, если вы хотите, чтобы «зарегистрированный» был проверен более сложным, вам нужно только перейти в одно место, чтобы изменить его, а не пытаться делать глобальные находки с вашей IDE и пытаться изменить его таким образом.

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

 Смежные вопросы

  • Нет связанных вопросов^_^