Yii2. Запись данных в БД. Часть 1

27.03.2019

Теги: ActiveFormWeb-разработкаYii2БазаДанныхЗапросТеорияФреймворк

Обычно для записи данных в БД используется метод save(), также можно использовать метод update(). Но метод save() используется чаще, потому что он более универсален. С ним можно как вставлять новые данныеб так и обновлять уже существующие данные. То есть, можно выполнять как запрос INSERT, так и запрос UPDATE.

У нас уже есть форма обратной связи, которую мы создали, когда работали с классом ActiveForm:

<?php
namespace app\controllers;

use Yii;
use yii\web\Controller;
use app\models\FeedbackForm;

class PageController extends Controller {
    public function actionIndex() {
        return $this->render('index');
    }

    public function actionFeedback()
    {
        $model = new FeedbackForm();
        // если пришли post-данные...
        if ($model->load(Yii::$app->request->post())) {
            // ...проверяем эти данные
            if ($model->validate()) {
                // данные прошли валидацию, отмечаем этот факт
                Yii::$app->session->setFlash(
                    'success',
                    true
                );
                // перезагружаем страницу, чтобы избежать повтороной отправки формы
                return $this->refresh();
            } else {
                // данные не прошли валидацию, отмечаем этот факт
                Yii::$app->session->setFlash(
                    'success',
                    false
                );
                // не перезагружаем страницу, чтобы сохранить пользовательские данные
            }
        }
        return $this->render('feedback', ['model' => $model]);
    }
}
<?php
namespace app\models;

use yii\base\Model;

/**
 * Модель для формы обратной связи
 */
class FeedbackForm extends Model
{
    public $name, $email, $body;

    public function attributeLabels() {
        return [
            'name' => 'Ваше имя',
            'email' => 'Ваш email',
            'body' => 'Сообщение',
        ];
    }

    public function rules() {
        return [
            // удалить пробелы для полей name и email
            [['name', 'email'], 'trim'],
            // поле name обязательно для заполнения
            ['name', 'required', 'message' => 'Поле «Ваше имя» обязательно для заполнения'],
            // поле email обязательно для заполнения
            ['email', 'required', 'message' => 'Поле «Ваш email» обязательно для заполнения'],
            // поле email должно быть корректным адресом почты
            ['email', 'email', 'message' => 'Поле «Ваш email» должно быть адресом почты'],
            // поле body обязательно для заполнения
            ['body', 'required', 'message' => 'Поле «Сообщение» обязательно для заполнения'],
        ];
    }
}
<?php
/* @var $this yii\web\View */

use yii\widgets\ActiveForm;
use yii\helpers\Html;

$this->title = 'Обратная связь';
?>

<?php if (Yii::$app->session->hasFlash('success')): ?>
    <?php if (Yii::$app->session->getFlash('success')): ?>
        <p>Данные формы прошли валидацию</p>
    <?php else: ?>
        <p>Данные формы не прошли валидацию</p>
    <?php endif; ?>
<?php endif; ?>

<div class="page-feedback">
    <h1><?= Html::encode($this->title) ?></h1>

    <?php $form = ActiveForm::begin(['id' => 'feedback-form', 'options' => ['novalidate' => '']]); ?>
        <?= $form->field($model, 'name')->textInput(); ?>
        <?= $form->field($model, 'email')->textInput(); ?>
        <?= $form->field($model, 'body')->textarea(['rows' => 5]); ?>
        <?= Html::submitButton('Отправить', ['class' => 'btn btn-primary']); ?>
    <?php ActiveForm::end(); ?>
</div>

Создадим таблицу feedback в базе данных, чтобы сохранять сообщения:

CREATE TABLE `feedback` (
  `id` int(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT 'Уникальный идентификатор',
  `name` varchar(100) NOT NULL COMMENT 'Имя автора сообщения',
  `email` varchar(100) NOT NULL COMMENT 'Почта автора сообщения',
  `body` text NOT NULL COMMENT 'Текст сообщения'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Теперь внесем изменения в код модели, контроллера и представления:

<?php
namespace app\models;

use yii\db\ActiveRecord;

/**
 * Модель для формы обратной связи
 */
class Feedback extends ActiveRecord
{
    public function attributeLabels() {
        return [
            'name' => 'Ваше имя',
            'email' => 'Ваш email',
            'body' => 'Сообщение',
        ];
    }

    public function rules() {
        return [
            // удалить пробелы для полей name и email
            [['name', 'email'], 'trim'],
            // поле name обязательно для заполнения
            ['name', 'required', 'message' => 'Поле «Ваше имя» обязательно для заполнения'],
            // поле email обязательно для заполнения
            ['email', 'required', 'message' => 'Поле «Ваш email» обязательно для заполнения'],
            // поле email должно быть корректным адресом почты
            ['email', 'email', 'message' => 'Поле «Ваш email» должно быть адресом почты'],
            // поле body обязательно для заполнения
            ['body', 'required', 'message' => 'Поле «Сообщение» обязательно для заполнения'],
        ];
    }
}
<?php
namespace app\controllers;

use Yii;
use yii\web\Controller;
use app\models\Feedback;

class PageController extends Controller {
    public function actionIndex() {
        return $this->render('index');
    }

    public function actionFeedback()
    {
        $model = new Feedback();
        // если пришли post-данные...
        if ($model->load(Yii::$app->request->post())) {
            // ...проверяем и сохраняем эти данные
            if ($model->save()) {
                // данные прошли валидацию, отмечаем этот факт
                Yii::$app->session->setFlash(
                    'success',
                    true
                );
                // перезагружаем страницу, чтобы избежать повтороной отправки формы
                return $this->refresh();
            } else {
                // данные не прошли валидацию, отмечаем этот факт
                Yii::$app->session->setFlash(
                    'success',
                    false
                );
                // не перезагружаем страницу, чтобы сохранить пользовательские данные
            }
        }
        return $this->render('feedback', ['model' => $model]);
    }
}
<?php
/* @var $this yii\web\View */

use yii\widgets\ActiveForm;
use yii\helpers\Html;

$this->title = 'Обратная связь';
?>

<?php if (Yii::$app->session->hasFlash('success')): ?>
    <?php if (Yii::$app->session->getFlash('success')): ?>
        <p>Данные формы записаны в базу данных</p>
    <?php else: ?>
        <p>Данные формы не прошли валидацию</p>
    <?php endif; ?>
<?php endif; ?>

<div class="page-feedback">
    <h1><?= Html::encode($this->title) ?></h1>

    <?php $form = ActiveForm::begin(['id' => 'feedback-form', 'options' => ['novalidate' => '']]); ?>
        <?= $form->field($model, 'name')->textInput(); ?>
        <?= $form->field($model, 'email')->textInput(); ?>
        <?= $form->field($model, 'body')->textarea(['rows' => 5]); ?>
        <?= Html::submitButton('Отправить', ['class' => 'btn btn-primary']); ?>
    <?php ActiveForm::end(); ?>
</div>

Мы изменили имя класса модели на Feedback (по имени таблицы БД) и теперь класс наследует ActiveRecord. Нам больше не нужно объявлять свойства класса, потому что Yii сам их объявит, выполнив служебный запрос к таблице БД feedback:

SHOW FULL COLUMNS FROM `feedback`

Метод save() не только сохраняет данные, но и проверяет их. Если данные не прошли валидацию, метод возвращает false и запись в БД не происходит.

Поиск: PHP • POST • Web-разработка • Yii2 • База данных • Запрос • Фреймворк • save • UPDATE • INSERT • ActiveRecord • ActiveForm

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.