Можно ли заставить ваши входные переменные PHP быть строго типизированными? - PullRequest
2 голосов
/ 02 декабря 2010

Когда я начинал с PHP, я был очень доволен тем, как PHP был свободно набран, и как легко было его изучать.Но когда я вырос в это, я понял, что слабая печать на самом деле усложняет мои сценарии, а не упрощает их.И теперь я ищу способы, которыми я мог бы строго ввести свои переменные PHP, в частности, входные переменные ($_POST, $_GET, $_COOKIE, $_REQUEST и некоторые $_SERVER переменные).

ТакжеЯ хотел бы, чтобы моя проверка и дезинфекция были скрыты в этом процессе, чтобы я мог «забыть» об SQL-инъекции и многих других подверженных ошибкам процессах проверки.У меня есть грубый набросок того, как я хочу, чтобы это было.

Сначала я объявляю переменную.Предпочтительно в ООП

$varClass->post->variable_name->type('STR', 'SQL', 'EMAIL');  

// or as an array  
$_MY_POST['variable_name'] = array('STR', 'SQL', 'EMIAIL');

Теперь я мог бы просто удалить все необъявленные переменные из предопределенных глобальных PHP-объектов и использовать тип переменной для проверки и санации их непосредственно в глобальных массивах.значения непроверенных переменных, таких как emaill, чтобы bool false, и необъявленные в null и использование их во время проверки данных.Однако, прежде чем я ушел и заново изобрел колесо, я надеялся:

кто-нибудь может направить меня в библиотеку, которая уже помогает решить мои проблемы?
если есть какие-то причины, почему я не долженпреследовать эту дикую фантазию?Лучшие и более ясные способы достижения этой цели?
и другие общие мысли, которые у вас могут возникнуть по поводу этой идеи?

Ответы [ 3 ]

4 голосов
/ 02 декабря 2010

http://sourceforge.net/p/php7framework/wiki/input/

Обертывает суперглобальные переменные по умолчанию, но вы также можете создавать экземпляры локальных объектов с помощью $postFilter = new input($_POST).Предполагается, что он будет использоваться вручную следующим образом:

 $_POST->email->sql["variable_name"]
 $_POST->array->int["order_list"]

И он жалуется, если видит какой-либо доступ $ _POST ["raw"].

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

 var $__rules = array(
      "variable_name" => "email,sql",
      "order_id" => "int,range:0:500",
      "order_list" => "array,int",
 );

Но я бы лично избегал -> sql убегает преждевременно.Если доступно, PDO и параметризованный SQL должны быть использованы.Но, конечно, центральная функция экранирования в любом случае лучше, чем осторожность.

Также вы можете определять пользовательские фильтры.Например, он выбирает глобальные функции.

4 голосов
/ 02 декабря 2010

PHP был набран свободно

Нет - он не печатается свободно, он динамически напечатан - есть небольшая разница.

фактически усложнил мои сценарии, а не упростил их

Мой опыт с точностью до наоборот.

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

Строгая типизация не способ справиться с проверкой ввода, особенно по средам, таким как HTTP (который свободно печатается). Просто непрактично иметь проверку типа для каждого возможного ввода - конечно, вы можете сохранить адрес электронной почты в строке - но это не значит, что адрес электронной почты отформатирован правильно, как вы гарантируете, что файл является изображением? Как строгая типизация гарантирует, что дата начала предшествует дате окончания?

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

Большая часть проверки может быть очень контекстной - например, 02/12/2010 в Великобритании через 10 месяцев после той же даты в США.

Если вы действительно хотите, чтобы PHP вел себя так, как будто он строго типизирован, взгляните на PHPLint

чтобы я мог "забыть" о SQL-инъекции

НЕТ! Вы проверяете / дезинфицируете входные данные и преобразовываете выходные данные в соответствии с тем, куда они выводятся! Правильное представление строки для записи в HTML отличается от записи ее в URL, которая отличается от записи в базу данных.

0 голосов
/ 02 декабря 2010

Я написал систему форм для нашего приложения, которая делает это в значительной степени;

  • Я определяю все поля, которые я ожидаю, и правила о них (тип данных, как минимум, нотакже минимумы, максимумы, перечисления и т. д.)
  • одноразовый номер используется для защиты формы, а также для определения, была ли она отправлена ​​
  • при восстановлении сеанса, каждая сериализованная форма проверяет,соответствующий одноразовый номер был отправлен и считает себя представленным, если это так
    • затем он проверяет каждое известное поле, получает отправленные данные и проверяет их
    • все поля могут быть сброшены к значениям по умолчанию, если они недействительны

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

К сожалению, это не открытый исходный код, и у меня нет разрешения открывать его;Я долго искал что-то подобное, но ничего не смог найти.Библиотека Pear Quickforms была самой близкой, но, казалось, не покрывала всю проверку и имела ужасную, ужасную документацию.

...