Arhn - архитектура программирования

Экранирование переменных в массиве и динамическое присвоение экранированных значений исходным значениям переменных

Обычно я просто использую mysql_real_escape_string для каждой переменной перед вставкой в ​​мою базу данных, например:

    $first_name = mysql_real_escape_string($first_name); // Bill
    $last_name  = mysql_real_escape_string($last_name);  // O'Rielly
    $email      = mysql_real_escape_string($email);      // [email protected]

    $insert = mysql_query("
                  INSERT INTO `users` (first_name, last_name, email)
                  VALUES ('$first_name', '$last_name', '$email')
              ") or die(mysql_error());

Но в некоторых формах у меня может быть 20 разных переменных, которые я хочу экранировать, поэтому я надеялся, что есть способ использовать массив, запустить его через функцию, чтобы экранировать каждую. Затем сделайте так, чтобы исходные переменные ($first_name, $last_name, $email) имели значение экранированной строки из массива. Я придумал следующее, но это, насколько я понял.

    $form_array = array($first_name, $last_name, $email);

    print_r($form_array);
    echo("<br />".$last_name."<br />");

    function cleanInput($array) {
        return array_map('mysql_real_escape_string', $array);
    }

    $clean_array = cleanInput($form_array); 

    print_r($clean_array);
    echo("<br />".$clean_array[1]."<br />");

Что выводит следующее:

    Array ( [0] => Bill [1] => O'Rielly [2] => [email protected] ) 
    O'Rielly
    Array ( [0] => Bill [1] => O\'Rielly [2] => [email protected] ) 
    O\'Rielly

Итак, мы можем видеть, что он экранируется правильно, но я в тупике, когда $first_name имеет значение $clean_array[0], $last_name имеет значение $clean_array[1] и т. д.

Я знаю, конечно, что мог бы просто написать:

    $first_name = $clean_array[0];
    $last_name = $clean_array[1];

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

Потому что тогда, когда дело доходит до проверки в будущем, я могу просто

  • Назначить все данные $_POST переменным
  • Поместите их переменные в массив
  • Запустите массив через функцию, и все исходные переменные $_POST теперь будут иметь экранированное значение из функции.
  • Используйте метод вставки, упомянутый в начале, используя исходные имена переменных $first_name, $last_name и т. д.

Скорее тогда:

    $insert = mysql_query("
                  INSERT INTO `users` (first_name, last_name, email)
                  VALUES ('$clean_array[0]', '$clean_array[1]', '$clean_array[2]')
              ") or die(mysql_error());

Это возможно?

Обновить

Из сообщения hakre о функциях compact и extract я пришел к следующему:

    $array = compact(array("first_name", "last_name", "email"));
    echo("<strong>Before:</strong><br />First Name: ".$first_name."<br />Last Name: ".$last_name."<br />Email: ".$email."<br /><br />");

    extract(array_map('mysql_real_escape_string', $array), EXTR_OVERWRITE);
    echo("<strong>After:</strong><br />First Name: ".$first_name."<br />Last Name: ".$last_name."<br />Email: ".$email."");

Который выводит следующие детали, как я хотел бы:

До:

Имя: Билл

Фамилия: О’Райли

Электронная почта: имя@домен.com

После:

Имя: Билл

Фамилия: О'Райли

Электронная почта: имя@домен.com

Я пытался поместить extract в функцию, но это не работает?

    function cleanInput($array) {

        $clean_array = extract(array_map('mysql_real_escape_string', $array), EXTR_OVERWRITE);
        return $clean_array;

    }

    $array = compact(array("first_name", "last_name", "email"));
    echo("<strong>Before:</strong><br />First Name: ".$first_name."<br />Last Name: ".$last_name."<br />Email: ".$email."<br /><br />");

    cleanInput($array);
    echo("<strong>After:</strong><br />First Name: ".$first_name."<br />Last Name: ".$last_name."<br />Email: ".$email."");

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


Ответы:


1

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

Пример:

$vars = array('first_name', 'last_name', 'email');

$first_name = $last_name = $email = 'just some init value';

$array = compact($vars);

foreach($array as &$value)
    $value = str_shuffle($value);
unset($value);

extract($array);

printf("First: %s; Last: %s; Email: %s", $first_name, $last_name, $email); 

Выход:

First:  sjivus enta metluoi; Last: i evounes tliuat smj; Email: tleetnumav siuijo s 
06.11.2011
  • Просто быстро прочитайте документацию по ним, так как я немного занят в эту минуту, но это похоже на то, что мне нужно! Я свяжусь с вами, когда у меня будет беспорядок позже, спасибо! 07.11.2011
  • hakre, я повозился с compact и extract, и у меня есть рабочий пример, но не на 100%, как я хочу, я обновил свой вопрос тем, что у меня есть до сих пор, не могли бы вы посмотреть, и не могли бы вы дать мне немного больше информации о том, куда идти отсюда? +1 за то, что показал мне эти две функции! 07.11.2011
  • Вы используете это неправильно, потому что у функции есть собственная таблица переменных. Compact и Extract предлагают некоторые базовые функции обработки переменных. Вы должны использовать их с умом, чтобы заставить их делать то, что вы хотите. Я не имел в виду, что это полностью решает вашу проблему или проблему дизайна, с которой вы сталкиваетесь. 07.11.2011

  • 2
    function dbSet($fields, $source = array()) {
      $set = '';
      if (!$source) $source = &$_POST;
    
      foreach ($fields as $field) {
        if (isset($source[$field])) {
          $set.="`$field`='".mysql_real_escape_string($source[$field])."', ";
        }
      }
      return substr($set, 0, -2); 
    }
    

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

    Таким образом, имея эту функцию в вашем конфигурационном файле, вам нужно будет ввести всего лишь

    $fields = explode(" ","name surname lastname address zip fax phone");
    $query  = "INSERT INTO table SET ".dbSet($fields);
    

    обратите внимание на массив $files. Я надеюсь, что это самоочевидно, хотя

    Что ж, после некоторых разъяснений в комментариях я могу расширить свой ответ.

    Лучший способ избавиться от постоянного бегства — избавиться от него. Либо создайте свою собственную, либо используйте какую-либо существующую библиотеку абстракции БД, которая сделает все за вас.

    Скажем, код для проверки существующего имени пользователя будет выглядеть так:

    $username_exists=$db->getOne("SELECT id FROM users WHERE name=?",$_POST['name']);
    if ($username_exists) // do stuff.
    

    где $_POST['name'] будет правильно отформатирован либо с использованием собственных подготовленных операторов, либо с помощью правильного экранирования/приведения/внесения в белый список.

    Таким образом, не нужно вообще заботиться о ручном экранировании.
    Это также точный смысл функции, которую я опубликовал вначале.

    06.11.2011
  • Разве это не делает то, что уже делает мой? За исключением того, что вы просто вставляете его немного иначе, чем в БД? Извините, если я неправильно понял это! Просто я хочу, чтобы каждая переменная проходила через функцию, но возвращалась с экранированным значением под исходным именем этой переменной. Потому что я хочу иметь возможность продолжать и выполнять другие проверки с каждой переменной по отдельности, поэтому я хочу, чтобы они были разделены. 07.11.2011
  • вы не можете делать какие-либо проверки после побега. экранирование должно быть самой последней операцией перед вставкой данных в базу данных. 07.11.2011
  • Извините, я должен был объяснить, что я имел в виду, я хочу выполнять проверки, такие как запрос, чтобы увидеть, не используется ли электронная почта другим участником, и тому подобное, поэтому требуется, чтобы я мог как-то их разделить. Потому что я не хочу проверять их все, такие как имена и фамилии, поскольку они могут быть дубликатами, но электронные письма, имена пользователей и т. д. не могут. Так что, конечно, для моего запроса проверки электронной почты его нужно экранировать заранее? 07.11.2011
  • Я добавил к своему ответу возможное решение. Тем не менее, вы все равно можете идти своим путем, используя идею внесения имен полей в белый список. 07.11.2011
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..