Models - uniqcle/Yii2 GitHub Wiki
Models реализует логику и работает с данными
Расширяемся от базового класса yii\base\Model
Создаем frontend/models/Stuff.php
namespace frontend\models;
//Подключаем базовый класс Model
use yii\base\Model;
class Stuff extends Model
{
//Атрибуты - публичные св-ва
public $firstName;
public $lastName;
public $middleName;
public $salary;
}
Доступ к элементам объекта
Создаем frontend/controllers/StuffController.php
namespace frontend\controllers;
use yii\web\Controller;
use frontend\models\Stuff;
class StuffController extends Controller
{
public function actionIndex(){
$stuff1 = new Stuff();
$stuff1 -> firstName = 'Kirill';
$stuff1 -> lastName = 'Anuchkin';
$stuff1 -> middleName = 'Andreevich';
$stuff1 -> salary = 120000;
//Если к единичному свойству
echo $stuff1->firstName;
//1. Реализация интерфейса ArrayAccess.
//Обеспечивает к объектам как к массиву.
echo $stuff1['firstName'];
echo $stuff1['lastName'];
echo $stuff1['middleName'];
echo $stuff1['salary'];
//2. Реализация интерфейса Traversable
//Можно обходить с помощью чикла foreach
foreach($stuff1 as $attribute => $value):
echo "$attribute : $value";
endforeach;
echo '<hr>';
foreach($stuff1 as $value):
echo $value;
endforeach;
//3. Реализация интерфейса Arrayable
//С помощью метода toArray() представление атрибутов stuff в ввиде массива
$array = $stuff1->toArray();
debug($array);
//4. Получить список всех атрибутов, обратившись к методу getAttributes()
$attrArray1 = $stuff1->getAttributes();
debug($attrArray1);
//5. Получить список всех аттрибутов из св-ва attributes
$attrArray2 = $stuff1->attributes;
debug($attrArray2);
//6. Получить список все аттрибутов из метода attributes()
$attrArray3 = $stuff1->attributes();
debug($attrArray3);
}
}
В Controller frontend/controllers/NewsletterController.php
namespace frontend\controllers;
use yii\web\Controller;
use Yii;
use frontend\models\Newsletter;
class NewsletterController extends Controller
{
//Страница подписки
public function actionSubscribe(){
$formData = Yii::$app->request->post(); //Загружает данные из глобального массива POST
$model = new Newsletter();
if( Yii::$app->request->isPost ){ //isPost - переменная. Post запрос был или нет.
//Загружаем данные в модель
$model->email = $formData['email'];
//Процедура валидации по правилам и сохранение в БД
if( $model->validate() && $model->save() ){
//Устанавливаем Flash сообщение
Yii::$app->session->setFlash('subscribeStatus', 'Вы успешно подписались!');
}
}
return $this->render('subscribe', [
'model' => $model
]);
}
}
Для защиты подделки запроса Bad Request (#400). Необходимо внести изменения в файл frontend/config/main.php
'components' => [
'request' => [
'csrfParam' => '_csrf-frontend',
'enableCsrfValidation' => false, //Отключить Csrf валидацию
],
...
В Model frontend/models/Newsletter.php
namespace frontend\models;
use Yii;
use yii\base\Model;
class Newsletter extends Model
{
public $email;
public function attributeLabels(){
return [
'name' => 'Ваше имя...',
'email' => 'Ваш email: ',
'text' => 'Напишите нам здесь...'
];
}
//Правила валидации
public function rules(){
return [
//[['поле'], 'валидатор']
[['email'], 'required'],
[['email'], 'email']
];
}
//Сохранение данных в БД
public function save(){
$sql = "INSERT INTO subscribers (id, name, email) VALUES (null, null, '{$this->email}'); ";
return Yii::$app->db->createCommand($sql)->execute();
}
}
Во View frontend/views/newsletter/subscribe.php
//Если есть ошибки
if( $model->hasErrors() ){
//Если валидация не прошла. В модель записываются ошибки валидации
//Эти ошибки можно вызвать методом getErrors() это массив
$errors = $model->getErrors();
}
//Проверяем записано ли Flash сообщение
if( Yii::$app->session->hasFlash('subscribeStatus') ){
echo Yii::$app->session->getFlash('subscribeStatus');
}
?>
<form method = "post">
<div class="form-group row">
<label for="inputName" class="col-sm-2 col-form-label">Your name</label>
<div class="col-sm-10">
<input type="name" name = "name" class="form-control" id="inputName" placeholder="John Doe">
</div>
</div>
<div class="form-group row">
<label for="inputEmail3" class="col-sm-2 col-form-label">Email</label>
<div class="col-sm-10">
<input type="email" name = "email" class="form-control" id="inputEmail3" placeholder="[email protected]">
</div>
</div>
<div class="form-group row">
<div class="col-sm-10">
<button type="submit" class="btn btn-primary">Subscribe</button>
</div>
</div>
</form>
В контроллере frontend/controllers/EmployeeController.php
namespace frontend\controllers;
use Yii;
use yii\web\Controller;
use frontend\models\Employee;
class EmployeeController extends Controller
{
// Регистрация сотрудника
public function actionRegister(){
$model = new Employee();
$model->scenario = Employee::SCENARIO_EMPLOYEE_REGISTER;
$formData = Yii::$app->request->post();
if( Yii::$app->request->isPost ){
//Безопасное массовое присваивание. Согласно сценариям
$model->attributes = $formData;
if( $model->validate() && $model->register() ){
Yii::$app->session->setFlash('success', 'Вы успешно зарегестрированы');
}
}
return $this->render('register', [
'model' => $model
]);
}
//Обновление информации по сотруднику
public function actionUpdate(){
$model = new Employee();
$model->scenario = Employee::SCENARIO_EMPLOYEE_UPDATE;
$formData = Yii::$app->request->post();
if( Yii::$app->request->isPost ){
$model->attributes = $formData;
if( $model->validate() && $model->update() ){
Yii::$app->session->setFlash('success', 'Вы успешно обновили информацию!');
}
}
return $this->render('update', [
'model' => $model
]);
}
}
В модели frontend/models/Employee.php
namespace frontend\models;
use Yii;
use yii\base\Model;
class Employee extends Model
{
//Имя сценариев - их лучше поместить в константы
const SCENARIO_EMPLOYEE_REGISTER = 'employee_register';
const SCENARIO_EMPLOYEE_UPDATE = 'employee_update';
public $firstName;
public $lastName;
public $middleName;
public $salary;
public $email;
public $bday;
public $startday;
public $city;
public $position;
public $idcode;
//Возвращает массив, в котором перечислены сценарии и атрибуты, которые в них используются
public function scenarios(){
return [
self::SCENARIO_EMPLOYEE_REGISTER => ['firstName', 'lastName', 'middleName', 'salary', 'email', 'bday', 'startday', 'city', 'position', 'idcode'],
self::SCENARIO_EMPLOYEE_UPDATE => ['firstName', 'lastName', 'middleName', 'salary']
];
}
public function rules(){
return [
[['email'], 'email'],
[['firstName', 'lastName', 'salary', 'email', 'startday', 'position', 'idcode'], 'required'],
['firstName', 'string', 'min' => 2],
[['lastName', 'middleName'], 'string', 'min' => 3],
[['salary'], 'number', 'min' => 20000, 'max' => 100000],
[['bday', 'startday'], 'date', 'format' => 'php:Y-m-d'],
['middleName', 'required', 'on' => self::SCENARIO_EMPLOYEE_UPDATE]
];
}
public function register(){
$sql = "INSERT INTO employee (id, firstName, lastName, middleName, salary, email, bday, startday, city, position, idcode ) VALUES (null, '{$this->firstName}', '{$this->lastName}', '{$this->middleName}', '{$this->salary}', '{$this->email}', '{$this->bday}', '{$this->startday}', '{$this->city}', '{$this->position}', '{$this->idcode}'); ";
return Yii::$app->db->createCommand($sql)->execute();
}
public function update(){
return true;
}
}
Во вью frontend/views/employee/register.php
//Если есть ошибки
if( $model->hasErrors() ){
//Если валидация не прошла. В модель записываются ошибки валидации
//Эти ошибки можно вызвать методом getErrors() это массив
$errors = $model->getErrors();
foreach($errors as $error):
foreach($error as $item):
echo $item.'</br>';
endforeach;
endforeach;
}
?>
<h3>Register employee</h3>
<form method = "POST">
<div class="form-group row">
<label for="firstName" class="col-sm-2 col-form-label">Your first name*</label>
<div class="col-sm-10">
<input type="text" name = "firstName" class="form-control" id="firstName" placeholder="min 2 symbols">
</div>
</div>
<div class="form-group row">
<label for="lastName" class="col-sm-2 col-form-label">Your last name*</label>
<div class="col-sm-10">
<input type="text" name = "lastName" class="form-control" id="lastName" placeholder="min 3 symbols">
</div>
</div>
<div class="form-group row">
<label for="middleName" class="col-sm-2 col-form-label">Your middle name*</label>
<div class="col-sm-10">
<input type="text" name = "middleName" class="form-control" id="middleName" placeholder="min 3 symbols">
</div>
</div>
<div class="form-group row">
<label for="email" class="col-sm-2 col-form-label">email*</label>
<div class="col-sm-10">
<input type="email" name = "email" class="form-control" id="email" placeholder="[email protected]">
</div>
</div>
<div class="form-group row">
<label for="salary" class="col-sm-2 col-form-label">Salary*</label>
<div class="col-sm-10">
<input type="number" name = "salary" class="form-control" id="salary" placeholder="от 20 000 до 10 0000">
</div>
</div>
<div class="form-group row">
<label for="salary" class="col-sm-2 col-form-label">Start Day*</label>
<div class="col-sm-10">
<input type="text" name = "startday" class="form-control" id="salary" placeholder="2019-03-28">
</div>
</div>
<div class="form-group row">
<label for="bday" class="col-sm-2 col-form-label">Birth Day *</label>
<div class="col-sm-10">
<input type="text" name = "bday" class="form-control" id="bday" placeholder="1984-05-27">
</div>
</div>
<div class="form-group row">
<label for="city" class="col-sm-2 col-form-label">City </label>
<div class="col-sm-10">
<select class="form-control" name="city" id="city">
<option>Выбрать город</option>
<option value = "1">Москва</option>
<option value = "2">Новосибирск</option>
<option value = "3">Барнаул</option>
<option value = "4">Омск</option>
</select>
</div>
</div>
<div class="form-group row">
<label for="position" class="col-sm-2 col-form-label">Position*</label>
<div class="col-sm-10">
<input type="text" name = "position" class="form-control" id="position" placeholder="manager">
</div>
</div>
<div class="form-group row">
<label for="position" class="col-sm-2 col-form-label">ID Code*</label>
<div class="col-sm-10">
<input type="text" name = "idcode" class="form-control" id="idcode" placeholder="74532">
</div>
</div>
<div class="form-group row">
<div class="col-sm-10">
<button type="submit" class="btn btn-primary">Register</button>
</div>
</div>
</form>