PHP: Какой лучший способ обработки данных формы? - PullRequest
3 голосов
/ 01 ноября 2011

На моем веб-сайте есть учетные записи пользователей, которые настраиваются с помощью форм, позволяющих пользователям обновлять все, начиная с имени и фамилии и заканчивая настройками конфиденциальности.Я использую следующую функцию для обновления базы данных с этим вводом.(Обратите внимание, что следующий код использует специфичные для WordPress функции.)

function update_account() {
    global $current_user; get_currentuserinfo();
    require_once( ABSPATH . WPINC . '/registration.php' );

    $uid = $current_user->ID;

    // First Name
    if(isset($_POST['first_name']) && $_POST['first_name'] <> $current_user->first_name) {
        wp_update_user( array( 
            'ID' => $uid, 'first_name' => esc_attr($_POST['first_name'])
        ));
    }

    // ...and so on 43 more times...

}

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

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

Какой лучший способ обработки данных формы?

Ответы [ 2 ]

4 голосов
/ 01 ноября 2011

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

// All the fields you wish to process are in this array
$fields = array('first_name', 'last_name', 'others',...'others99');

// Loop over the array and process each field with the same block
foreach ($fields as $field) {
    if(isset($_POST[$field]) && $_POST[$field] != $current_user->{$field}) {
        wp_update_user( array( 
            'ID' => $uid, $field => esc_attr($_POST[$field])
        ));
    }
}
1 голос
/ 02 ноября 2011

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

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

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

function update_account()
{
    // initialize a new form class
    $form = new UserAccountInfoForm();
    // give the form to your view for rendering 
    $this->view->form = $form;
    // check if form was posted [however your framework provides this check]
    if(!Is_Post())
        return $this->render('accountform.phtml');
    // check if posted form data validates
    if(!$form->isValid($_POST))
    {
         // if the form didn't validate re-display the form
         // the view takes care of displaying errors, with the help of its
         // copy of the $form object
         return $this->render('accountform.phtml');
    }

    // form validated, so we can use the supplied values and update the db
    $values = $form->getValues(); // returns an array of ['fieldname'=>'value']
    // escape the values of the array
    EscapeArrayValues($values);
    // update db
    wp_update_user($values);
    // inform the user of successful update via flash message
    $this->flashMessage('Successfully updated profile');
    // go back to main profile page
    $this->redirect('/profile');

Это делает ваш контроллер относительно чистым, с которым легко работать.Представление получает некоторую любовь и заботу, используя значение $ form для правильного отображения формы.Технически, вы можете реализовать метод в классе формы, чтобы дать вам html формы, но для простоты я просто собираюсь предположить, что html вашей формы вручную закодирован в accountform.phtml, и он просто использует $ form для получения информации о поле

<form action='post'>
<label>first name</label> <input class='<?=$this->form->getElement('first_name')->hasError() ? "invalid":""?>' type='text' name='first_name' value="<?=$this->form->getElement('first_name')->getValue()"/> <span class='errmsg'><?=$this->form->getElement('first_name')->getError()?></span><br/>

<label>last name</label> <input class='<?=$this->form->getElement('last_name')->hasError() ? "invalid":""?>' type='text' name='last_name' value="<?=$this->form->getElement('last_name')->getValue()"/> <span class='errmsg'><?=$this->form->getElement('last_name')->getError()?></span><br/>

<label>other</label> <input class='<?=$this->form->getElement('other')->hasError() ? "invalid":""?>' type='text' name='other' value="<?=$this->form->getElement('other')->getValue()"/> <span class='errmsg'><?=$this->form->getElement('other')->getError()?></span><br/>

<input type='submit' value='submit'/>
</form>

Здесь псевдокод опирается на метод класса формы "getElement", который возвращает экземпляр класса поля для указанного имени поля (который будет создан инициализированным в конструкторе класса вашей формы).Затем на поле класса методы «hasError» и «getError» проверяют, правильно ли проверено поле.Если форма еще не была отправлена, тогда они возвращают ложное и пустое значение, но если форма была опубликована и недействительна, тогда они будут установлены соответствующим образом в методе validate при его вызове.Также «getValue» будет возвращать либо значение, предоставленное пользователем, когда форма была отправлена, либо, если форма не была отправлена, значение по умолчанию, указанное при создании и инициализации класса поля.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...