Создание блога

firep91613

Новичок
Эта книга какого года?
2021
Одного Зандстры не достаточно, для выхода на более высокий уровень есть другие книги (TDD, DDD и тд), и их тоже придётся читать.
Какие, к примеру? Я просмотрел содержание нескольких книг PHP, но там везде синтаксис, вот, только Зандстру нашел.
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
Вообще XML в современном мире мало кто где юзает добробольно при наличии везде json и подобного. Я бы подумал взять что-то посовременнее.
 

weregod

unserializer
Вообще XML в современном мире мало кто где юзает добробольно при наличии везде json и подобного. Я бы подумал взять что-то посовременнее.
ага, только в оригинальном JSON комментов не предусмотрели, а так-то да, парсится шустрее )
 

Valick

Новичок
Какие, к примеру?
Александр Швец - Погружение в паттерны проектирования.
Бек Кент - Экстремальное программирование. Разработка через тестирование.
Роберт Мартин - Чистый код
Роберт Мартин - Чистая архитектура
Влад Хононов - Изучаем DDD - предметно ориентированное программирование.
Метт Стауфер - Laravel. Полное руководство (сам не читал, только планирую)

Общую картину Вам по частям придётся собирать самому, кремлёвской таблетки тут нет.
Будьте готовы к тому, что не все книги будут с примерами на РНР и даже не все на русском языке.
Я лично книги очень люблю и всегда говорил, что начинать изучение надо именно с книг, но не стоит забывать про другие источники информации.
Книги дадут старт и научат отделять зёрна от плевел, дальше уже сами, либо полетел либо разбился, третьего не дано :)
 

firep91613

Новичок
Начал делать админку. Может кто-нибудь посмотреть нормально ли я делаю?
PHP:
<?php

namespace App\Controllers;

use App\Models\UserModel;
use App\Models\PostsModel;
use App\Views\View;
use App\Classes\FormValidator;

class AdminController
{
    private UserModel $userModel;
    private PostsModel $postModel;
    private View $view;
    private FormValidator $formValidator;
    private array $fillable = ['email', 'password'];

    public function __construct(UserModel $userModel, PostsModel $postModel, View $view, FormValidator $formValidator)
    {
        $this->userModel = $userModel;
        $this->postModel = $postModel;
        $this->view = $view;
        $this->formValidator = $formValidator;
    }

    public function index()
    {
        if (isset($_SESSION['user_id']) && $_SESSION['user_role'] === '4') {
            return $this->dashboard();
        } else {
            redirect('/admin/login');
        }
    }

    public function login()
    {
        if (isset($_SESSION['user_id']) && $_SESSION['user_role'] === '4') {
            redirect('/admin');
        }

        $errors = [];
        $old = [];

        $errors['flash'] = $_SESSION['errors']['flash'] ?? '';

        foreach ($this->fillable as $field) {
            $errors[$field] = $_SESSION['errors'][$field] ?? '';;
            $old[$field] = $_POST[$field] ?? $_SESSION['old'][$field] ?? '';
        }

        $this->view->render('admin/login', [
            'title' => "Вход в панель администратора",
            'errors' => $errors,
            'old' => $old
        ], 'admin');
    }

    public function loginStore()
    {
        $data = loadData($this->fillable);
        $rules = [
            'email' => [
                'required' => true,
                'min' => 5,
                'max' => 20,
                'email' => $data['email']
            ],
            'password' => [
                'required' => true,
                'min' => 5,
                'max' => 20
            ]
        ];
        
        $validation = $this->formValidator->validate($data, $rules);

        if ($validation->hasErrors()) {
            $_SESSION['errors'] = [];
            $_SESSION['old'] = [];
            $errorFields = array_keys($validation->getErrors());

            foreach ($this->fillable as $field) {
                if (in_array($field, $errorFields)) {
                    $_SESSION['errors'][$field] = $validation->listErrors($field);
                }
                
                $_SESSION['old'][$field] = $_POST[$field];
            }
            
            redirect('/admin/login');
        }

        $result = $this->userModel->auth($data['email'], $data['password']);
        
        if ($result) {
            if ($result->role === '4') {
                $_SESSION['user_id'] = $result->id;
                $_SESSION['user_name'] = $result->name;
                $_SESSION['user_role'] = $result->role;
                $_SESSION['errors']['flash'] = 'Вы успешно вошли в админку';
                redirect('/admin');
            } else {
                $_SESSION['errors']['flash'] = 'У вас нет прав доступа';
                redirect('/admin/login');
            }
        } else {
            $_SESSION['errors']['flash'] = 'Неверный email или пароль';
            redirect('/admin/login');
        }
    }

    public function logout()
    {
        unset($_SESSION['user_role']);
        redirect('/admin/login');
    }

    private function dashboard()
    {
        $users = $this->userModel->findAll();
        $posts = $this->postModel->findAll();

        return $this->view->render('admin/index', [
            'title' => "Добро пожаловать в админ-панель",
            'users' => $users,
            'posts' => $posts
        ], 'admin');
    }
}
 

AmdY

Пью пиво
Команда форума
Это совсем плохо. Ты сейчас потрать немного времени и разберись с юнит тестами и попробуй написать тест на свой контроллер, увидишь большинство архитектурных проблем.
 

Valick

Новичок
потрать немного времени и разберись с юнит тестами
firep91613 , я бы даже рекомендовал потратить ещё чуть больше времени и разобраться с TDD и писать сначала тест, а потом код.
Жаль мне такой совет не дал никто 15 лет назад.
 

miketomlin

Новичок
Может кто-нибудь посмотреть нормально ли я делаю?
Зачем ты все в один контроллер запихал? Даже если у тебя админка в одной ветке морды (а не на отдельном хосте), используй группу роутов. Можно и один контроллер, но только такой, который будет заниматься только доп. роутингом (ну, и авторизацией, если не выносить ее во фронт).
 

firep91613

Новичок
firep91613 , я бы даже рекомендовал потратить ещё чуть больше времени и разобраться с TDD и писать сначала тест, а потом код.
Жаль мне такой совет не дал никто 15 лет назад.
Будет сделано.
Зачем ты все в один контроллер запихал?
Не знаю, слабоум наверно.
Даже если у тебя админка в одной ветке морды (а не на отдельном хосте), используй группу роутов
Исходя из того, что можно и один контроллер, подразумевается несколько? Группа роутов - это типо есть URI /admin и все остальные маршруты сгруппированы и разделены на отдельные контроллеры? Контроллер авторизации, контроллер самой админ панели? Так типо?
PHP:
$router->group('/admin', function () use ($router) {
    $router->get('/', [AdminDashboardController::class, 'index']);
    $router->get('/login', [AdminAuthController::class, 'login']);
    $router->post('/login', [AdminAuthController::class, 'loginStore']);
    $router->get('/logout', [AdminAuthController::class, 'logout']);
 });
У меня сейчас контроллер User отвечает за все, регистрацию и аутентификацию. Я так понимаю это то же все не правильно. Нужен отдельный класс аутентификации? Ну типо извлекать инстансы User'a и т.д.
 

miketomlin

Новичок
Группа роутов - это типо есть URI /admin и все остальные маршруты сгруппированы и разделены на отдельные контроллеры?
Да.

Контроллер авторизации, контроллер самой админ панели?
Лучше говорить «аутентификации». «Контроллер самой админ панели» при использовании группы роутов – это фигня. Дели его примерно так же, как и для морды.

Нужен отдельный класс аутентификации?
Да. Тут как раз-таки лучше говорить «авторизации». Аутентификация может быть его частью или отдельным классом. Короче в основе должна быть такая модель. Продумай набор ее ф-ций (методов). Сам принцип действия аутентификации и авторизации хорошо понимаешь?
 

miketomlin

Новичок
$router->get('/logout', [AdminAuthController::class, 'logout']);
Основное действие по выходу должно запускаться POST'ом. Ну, точно не GET'ом. GET может «по дороге» кешироваться!

Страничку или всплывающее окошко выхода можешь в ответ на GET выводить, если у тебя не только кнопка в общем шаблоне используется.
 
Последнее редактирование:

firep91613

Новичок
Сам принцип действия аутентификации и авторизации хорошо понимаешь?
Ну аутентификация это типо подтверждение личности. Авторизация, сложно сформулировать, ну пользователь прошел аутентификацию и он авторизован, может пользоваться сайтом, дополнительные возможности открываются.
 

miketomlin

Новичок
Ну аутентификация это типо подтверждение личности. Авторизация, сложно сформулировать, ну пользователь прошел аутентификацию и он авторизован, может пользоваться сайтом, дополнительные возможности открываются.
Ну, в общем правильно. Авторизация – это тоже прохождение проверки (на доступ к ресурсам юзера), только здесь в основе не логин и пароль (и т.п. персональные данные), а идентификатор пользователя и периодически изменяющийся ключ (или только ключ, а идентификатор хранится на стороне сервера и выбирается ключом). Для лучшего понимания авторизации можно попробовать реализовать ее самому без PHP-сессий.

AdminUsersController, AdminPostsController, AdminSettingsController?
Угу, если это не какой-нибудь универсальный CRUD. Можно даже без приставки Admin.
 

firep91613

Новичок
@miketomlin, как лучше?

1. RegisterController: регистрация нового пользователя.
LoginController: аутентификация.
LogoutController: выход.

UserModel: занимается данными пользователей (поиск, создание, обновление).
AuthModel: отвечает за аутентификацию (проверка пароля, создание сессий, удаление сессий).

2. Просто UserController. И две модели UserModel и AuthModel

Еще вот есть PostController. Я слизал все методы у Ларавеля (index, show, create, store, edit, update, destroy), но контроллер вышел почти на 250 строк. Подозреваю, что это тоже ерунда вышла...
 
Сверху