Всем привет! Я попытаюсь подробно описать процесс разработки базовой версии блога с использованием Yii 2(basic) в целях обучения.
Почему basic? По моему опыту basic версия лучше подходит для обучения.
Перед началом я расскажу о ПО:
- web-cервер c модулем PHP и SQL базой данных. В данном случае я рекомендую сборку web-сервера XAMPP, он прост в установки, удобный интерфейс управления..;
- Basic версия Yii 2. Для установки Yii 2, я рекомендую Composer(пакетный менеджер). Овладевая Composer-ом, в последствии вы сохраните целую кучу времени не только с yii, но и с другим ПО. Т.к. Composer загружает yii с GitHub, Composer просит token github, если у вас есть аккаун на GitHub, эта проблема решается очень быстро.
Рекомендации:
- знание PHP на уровне ООП;
- базовое знание SQL;
- вы можете сократить рабочий процесс используя IDE, я использую PhpStorm;
- если вы не знакомы с паттерном MVC, то перед изучением Yii 2 вы просто обязаны знать что это такое;
- я также рекомендую ознакомиться с документацией, самым важным будет «Первое Знакомство» и «Структура Приложения», остальное можно эффективно изучить в процессе.
1) Настройка БД и создание таблиц
Итак, вы так или иначе установили Yii 2 basic, вы проверили работу стандартного сценария.
Предлагаю начать с настройки БД, я буду использовать MySQL и phpMyAdmin.
Yii нужна информация о БД, заходим в один из файлов конфигурации приложения, а именно в basic\config\db.php:
return [ 'class' => 'yii\db\Connection', // Класс реализации подключения 'dsn' => 'mysql:host=localhost;dbname=yii2basic', // Имя базы данных, URL 'username' => 'root', // Логин пользователя этой ДБ 'password' => '', // Пароль пользователя этой ДБ 'charset' => 'utf8', // Кодировка ];
Стандартные параметры совпадают с теми, которые мне нужны. Эти данные будут использованы классом yii\db\Connection (тоже указанным в параметрах) для инициализации и создания экземпляра этого класса.
Создадим/используем БД:
В данном случае нам нужно несколько таблиц:
- таблица для пользователей, т.к. в basic версии стандартно не реализована регистрация/вход через БД;
- таблица для статей в блоге.
Добавлять новые таблицы в БД я буду через миграции, это не обязательно, но для вас это будет не плохой опыт. О том «зачем» нужны миграции можно узнать все в той же документации по этой ссылке.
Итак, чтобы создать миграцию нужно зайти в Командную строку и сменить директорию на папку с фреймворком, в этой директории находится файл yii.bat, он то нам и нужен.
Для смены директории вводим следующий код:
cd C:\xampp\htdocs\Yii2St\basic
(в основном использование командной строки интуитивно понятно)
Создаем миграцию для таблицы user и post(таблица для статей).
Вводим данный код после cd:
yii migrate/create create_post_table
(Для таблицы post)
yii migrate/create create_user_table
(Для таблицы user)
Yii создаст папку migrations если ее нет. Теперь там хранится 2 файла и класса для двух выше созданных миграций.
Зайдем в
basic\migrations\m170304_160410_create_user_table.
Вносим изменения в функцию «up», делаем такую же таблицу как в версии advanced:
public function up() //Событые создания таблицы { $tableOptions = null; if ($this->db->driverName === 'mysql') { $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB'; } $this->createTable('user', [ 'id' => $this->primaryKey(), 'username' => $this->string()->notNull()->unique(), 'auth_key' => $this->string(32)->notNull(), 'password_hash' => $this->string()->notNull(), 'password_reset_token' => $this->string()->unique(), 'email' => $this->string()->notNull()->unique(), 'status' => $this->smallInteger()->notNull()->defaultValue(10), 'created_at' => $this->integer()->notNull(), 'updated_at' => $this->integer()->notNull(), ], $tableOptions); }
Данный метод будет интуитивно понятен если вы знаете SQL и PHP на уровне ООП.
Также вносим изменения и для статей в basic\migrations\m170304_160323_create_post_table:
public function up() { $tableOptions = null; if ($this->db->driverName === 'mysql') { $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB'; } $this->createTable('post', [ 'id' => $this->primaryKey(), 'author' => $this->string()->notNull(), //Автор 'date' => $this->integer(32)->notNull(), 'category_id' => $this->integer()->notNull(), //Номер категории 'text' => $this->string(20000)->unique(), 'title' => $this->string()->notNull()->unique(), // Название статьи 'abridgment' => $this->string(767)->notNull(), // Сокращенный текст 'activity' => $this->integer()->notNull()->defaultValue(0), // Активность статьи ], $tableOptions); }
Далее просто выполняем этот код в консоли:
yii migrate
Если сказать проще, эта команда выполняет методы up в классах миграции + обновляет/добавляет таблицу ‘migration’, также можно и обратить изменения другой командой с помощью метода down в классах миграций(смотрите документацию).
Таблицы готовы.
2) Добавление функции регистрации/входа через ДБ
Для реализации регистрации/входа через ДБ нам потребуется:
- изменить стандартную модель User (models/User.php);
- добавить модель для регистрации (+models/SignupForm.php);
- добавить действие регистрации в контроллере (controllers/SiteController.php);
- добавить вид регистрации (views/site/signup.php);
- и добавить ссылку на регистрацию в навбар (views/layouts/main.php).
(О компоненте User и IdentityInterface)
В Yii есть компонент приложения User, он управляет статусом аутентификации пользователя, например:
Yii::$app->user->isGuest; // Возвращает true, если пользователь авторизован Yii::$app->user->logout(); // Производит логаут пользователя Yii::$app->user->identity->username // Возвращает username пользователя // и т.д.
Он требует, чтобы вы указали identity class, который будет содержать текущую логику аутентификации:
$config = [ ... 'components' => [ .... 'user' => [ 'identityClass' => 'app\models\User', // Эта моделать будет использована компонентом User ], .... ] ... ];
Начнем с изменения модели, класс User должен реализовывать IdentityInterface, по этому пишем примерно следующий код
basic\models\User:
namespace app\models; use Yii; use yii\base\NotSupportedException; use yii\db\ActiveRecord; use yii\web\IdentityInterface; class User extends ActiveRecord implements IdentityInterface { // Значения для сравнивания значений со значениями с БД, например const STATUS_DELETED = 0; // Если пользователь Заблокирован(Удален) const STATUS_ACTIVE = 10; // Если пользователь Активен const STATUS_ADMIN = 1; // Если пользователь Администратор // Переопределяем методы для интерфейса public static function findIdentity($id) { return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]); } public static function findIdentityByAccessToken($token, $type = null) { throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.'); } public static function findByUsername($username) { return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]); } public function getId() { return $this->getPrimaryKey(); } public function getAuthKey() { return $this->auth_key; } public function validateAuthKey($authKey) { return $this->getAuthKey() === $authKey; } public function validatePassword($password) { return Yii::$app->security->validatePassword($password, $this->password_hash); } public function setPassword($password) { $this->password_hash = Yii::$app->security->generatePasswordHash($password); } public function generateAuthKey() { $this->auth_key = Yii::$app->security->generateRandomString(); } }
Для реализации регистрации добавим модель
basic\models\SignupForm.php:
(О методе validate() и rules)
namespace app\models; use Yii; use yii\base\Model; class SignupForm extends Model { public $username; public $email; public $password; public function rules() // Эти правила будут использоваться при валидации: формы ввода, с помощью вызова метода validate() { return [ ['username', 'trim'], // обрезает пробелы и превращает в null если нечего не остается ['username', 'required'], // 'username' обязательно для заполнения ['username', 'unique', 'targetClass' => '\app\models\User', 'message' => 'This username has already been taken.'], // 'username' в модели \app\models\User(то есть в таблице user(вспоминаем ActivityRecords) должна быть уникальна) ['username', 'string', 'min' => 2, 'max' => 255], // 'username' это string переменная со значение от 2 до 255 символов ['email', 'trim'], ['email', 'required'], ['email', 'email'], ['email', 'string', 'max' => 255], ['email', 'unique', 'targetClass' => '\app\models\User', 'message' => 'This email address has already been taken.'], ['password', 'required'], ['password', 'string', 'min' => 6], ]; } public function attributeLabels() // Используется для локализации { return [ 'username' => 'Логин', 'email' => 'Электронная почта', 'password' => 'Пароль', ]; } public function signup() // Регистрация { if (!$this->validate()) { // Если валидация вернула false то возвращаем null return null; } $user = new User(); // Создаем новый экземпляр User $user->username = $this->username; // Определяем свойства класса $user->email = $this->email; $user->setPassword($this->password); $user->generateAuthKey(); $user->created_at() = time(); return $user->save() ? $user : null; // Сохраняем свойства в таблицу(метод ActivityRecord) user если переменная не равна null } }
Добавляем действие регистрации в модель
basic\controllers\SiteController.php:
//.... public function actionSignup() { $model = new SignupForm(); // Не забываем добавить в начало файла: use app\models\SignupForm; или заменить 'new SignupForm()' на '\app\models\SignupForm()' if ($model->load(Yii::$app->request->post())) { // Если есть, загружаем post данные в модель через родительский метод load класса Model if ($user = $model->signup()) { // Регистрация if (Yii::$app->getUser()->login($user)) { // Логиним пользователя если регистрация успешна return $this->goHome(); // Возвращаем на главную страницу } } } return $this->render('signup', [ // Просто рендерим вид если один из if вернул false 'model' => $model, ]); } //....
Далее нужно добавить вид signup для ввода формы
basic\views\site\signup.php:
use yii\helpers\Html; use yii\bootstrap\ActiveForm; $this->title = 'Регистрация'; $this->params['breadcrumbs'][] = ; // <-- Небольшая навигация ?> <div class="site-signup"> <h1><?= Html::encode($this->title) ?></h1> <p>Пожалуйста, заполните формы для регистрации:</p> <div class="row"> <div class="col-lg-5"> <?php $form = ActiveForm::begin(['id' => 'form-signup']); ?> <?= $form->field($model, 'username')->textInput(['autofocus' => true]) ?> <?= $form->field($model, 'email') ?> <?= $form->field($model, 'password')->passwordInput() ?> <div class="form-group"> <?= Html::submitButton('Signup', ['class' => 'btn btn-primary', 'name' => 'signup-button']) ?> </div> <?php ActiveForm::end(); ?> </div> </div> </div>
Изменяем навбар
basic\views\layouts
// Изменяем начиная с NavBar::begin(), заканчивая NavBar::end() NavBar::begin([ 'brandLabel' => 'My Company', // Надпись слева 'brandUrl' => Yii::$app->homeUrl, // Url который будет указ в гиперссылке на надписи 'options' => [ 'class' => 'navbar-inverse navbar-fixed-top', // Класс bootstrap class="navbar-inverse navbar-fixed-top" в HTML ], ]); $menuItems = [ // Те, которые будут отображаться всегда ['label' => 'Главная', 'url' => ['/site/index']], ['label' => 'Контакт', 'url' => ['/site/contact']], ]; if(Yii::$app->user->isGuest) // Если пользователь не авторизован { $menuItems[] = ['label' => 'Зарегистрироватся', 'url' => ['/site/signup']]; $menuItems[] = ['label' => 'Войти', 'url' => ['/site/login']]; } else { $menuItems[] = ['label' => 'Статьи', 'url' => ['/post']]; $menuItems[] = '<li>' . Html::beginForm(['/site/logout'], 'post') // Форма логаута, смотрим виджет ActiveForm . Html::submitButton( 'Выйти (' . Yii::$app->user->identity->username . ')', ['class' => 'btn btn-link logout'] ) . Html::endForm() . '</li>'; } echo Nav::widget([ // Выводим результат метода 'options' => ['class' => 'navbar-nav navbar-right'], 'items' => $menuItems // Элементы меню ]); NavBar::end();
Для локализации нужно указать в конфигурации такой код:
basic\config\web.php:
return [ 'id' => 'basic', 'basePath' => dirname(__DIR__), // ... 'language' => 'ru-RU', // <- Эту строку! // ... ]
3) Добавляем CRUD для статей
CRUD позволит добавить, редактировать, посмотреть и удалить статью. Самым быстрым способом добавления CRUD в нашем случае является gii. Gii автоматически генерирует код, после чего нужно будет просто изменить генерированный код.
Переходим по url с таким get ?r=gii
Для CRUD на нужна модель, я генерирую новую:
(Описание можно посмотреть просто наведя курсор на лейбл формы)
Далее заполняем формы и генерируем сам CRUD:
Проверить CRUD можно через такой get ?r=post
P.S. Конец первой части.
P.P.S. Первая статья, судите строго.
ссылка на оригинал статьи https://habrahabr.ru/post/324300/
Добавить комментарий