Итак, я не из огромного PHP-фона, и мне было интересно, если в хорошо сформированном коде нужно использовать «суперглобалы» напрямую, например, в середине некоторой функции говорят $_SESSION['x'] = 'y';
или если, как я обычно делаю с переменными, лучше отправить их в качестве аргументов, которые можно использовать оттуда, например:
class Doer { private $sess; public function __construct(&$sess) { $this->sess =& $sess; } } $doer = new Doer($_SESSION);
а затем используйте Doer->sess
из Doer->sess
и т. д. (Преимущество этого метода заключается в том, что он ясно Doer
что Doer
использует $ _SESSION.)
Каков приемлемый подход к разработке PHP для этой проблемы?
Мне нравится обертывать $_SESSION
, $_POST
, $_GET
и $_COOKIE
в структуры ООП.
Я использую этот метод для централизации кода, который обрабатывает санитарию и валидацию, все необходимые проверки isset ()
, nonces, параметры setcookie
и т. Д. Он также позволяет setcookie
код клиента (и дает мне иллюзию, что он более удобен в обслуживании).
Может быть трудно обеспечить использование такого типа структуры, особенно если есть несколько кодеров. С $_GET
, $_POST
и $_COOKIE
(я считаю), ваш код инициализации может скопировать данные, а затем уничтожить суперглобал. Возможно, умный деструктор может сделать это возможным с помощью $ _SESSION (стереть $ _SESSION при загрузке, записать его обратно в деструктор), хотя я не пробовал.
Однако я обычно не использую ни одну из этих методов обеспечения. После привыкания к этому, видя $_SESSION
в коде вне класса сеанса, просто выглядит странно, и я в основном работаю соло.
РЕДАКТИРОВАТЬ
Вот пример кода клиента, если он помогает кому-то. Я уверен, что поиск любой из основных рамок даст вам лучшие идеи …
$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 }
Post и его друзья все получают из базового класса, который реализует код проверки подлинности ядра, добавляя свои собственные функциональные возможности, такие как токены форм, конфигурацию cookie сеанса, что угодно.
Внутренне класс содержит набор достоверных данных, извлеченных из $_POST
мере того, как вызываются методы проверки, а затем возвращает их как свойства с помощью магического метода __get
. Невозможно получить доступ к полям с ошибкой. Мои методы проверки (кроме required
) не сбой в пустых полях, и многие из них используют func_get_args
чтобы позволить им работать с несколькими полями одновременно. Некоторые из методов (например, money
) автоматически переводят данные в пользовательские типы значений.
В случае ошибки у меня есть способ преобразовать данные в формат, который можно сохранить в сеансе и использовать для предварительного заполнения формы и выделения ошибок после перенаправления на исходную форму.
Одним из способов улучшить это было бы сохранение информации проверки в классе Form, которая используется для визуализации проверки формы и мощности на стороне клиента, а также для очистки данных после отправки.
Изменение содержания суперглобалов считается плохой практикой. Хотя в этом нет ничего плохого, особенно если код на 100% под вашим контролем, это может привести к неожиданным побочным эффектам, особенно если вы рассматриваете смешанный исходный код. Например, если вы сделаете что-то вроде этого:
$_POST['someval'] = mysql_real_escape_string($_POST['someval']);
вы можете ожидать, что везде PHP сделает доступным «someval» также, но это не так. Копия в $_REQUEST['someval']
останется неизменной и останется оригинальной «небезопасной» версией. Это может привести к непреднамеренной инъекционной уязвимости, если вы выполняете все ваши экраны в $ _POST, но в более поздней библиотеке используется $ _REQUEST и предполагается, что она уже сбежала.
Таким образом, даже если вы можете их модифицировать, лучше всего использовать суперглобалы только для чтения. Если вам нужно возиться со значениями, поддерживайте свои собственные параллельные копии и выполняйте любые методы обертки / доступа, необходимые для сохранения этой копии.
Я знаю, что этот вопрос старый, но я бы хотел добавить ответ.
классы mario для обработки входных данных являются удивительными.
Мне очень нравится обертывать суперглобалы каким-то образом. Это может сделать ваш код намного проще для чтения и привести к лучшей ремонтопригодности.
Например, есть какой-то код на моей текущей работе, я ненавижу! Переменные сеанса используются так сильно, что вы не можете реалистично изменить реализацию, не оказывая существенного влияния на весь сайт.
Например,
Предположим, вы создали класс сеанса, специфичный для вашего приложения.
class Session { //some nice code }
Вы могли бы написать что-то вроде следующего
$session = new Session(); if( $session->isLoggedIn() ) { //do some stuff }
В отличие от этого
if( $_SESSION['logged'] == true ) { //do some stuff }
Это кажется немного тривиальным, но для меня это очень важно. Скажите, что когда-нибудь в будущем я решаю, что хочу изменить имя индекса от «logged» до «loggedIn».
Теперь я должен перейти к каждому месту приложения, чтобы переменная сеанса использовалась для его изменения. Или я могу оставить его и найти способ сохранить обе переменные.
Или что, если я хочу проверить, что этот пользователь является пользователем admin и входит в систему? Для этого я могу проверить две разные переменные в сеансе. Но вместо этого я мог инкапсулировать его в один метод и сократить код.
Это помогает другим программистам смотреть на ваш код, потому что он становится легче читать, и им не нужно «думать» об этом, когда они смотрят на код. Они могут перейти к методу и увидеть, что есть только один способ иметь зарегистрированного пользователя. Это также помогает вам, потому что, если вы хотите, чтобы «зарегистрированный» был проверен более сложным, вам нужно только перейти в одно место, чтобы изменить его, а не пытаться делать глобальные находки с вашей IDE и пытаться изменить его таким образом.
Опять же, это тривиальный пример, но в зависимости от того, как вы используете сеанс, этот способ использования методов и классов для защиты доступа может сделать вашу жизнь намного легче жить.
Я бы не стал рекомендовать вообще прохождение суперглобала по ссылке. В вашем классе неясно, что то, что вы изменяете, является переменной сеанса. Кроме того, имейте в виду, что $ _SESSION доступна везде вне вашего класса. Это так неправильно с объектно-ориентированной точки зрения, чтобы иметь возможность модифицировать переменную внутри класса извне этого класса, изменяя переменную, не связанную с классом. Наличие публичного атрибута считается плохой практикой, это даже хуже.
Это плохое использование PHP.
непосредственно получить переменные $ _SESSION:
$id = $_SESSION['id']; $hash = $_SESSION['hash'];
и т.п.