За последние 24 часа нас посетили 49888 программистов и 1730 роботов. Сейчас ищут 653 программиста ...

MVC патерн

Тема в разделе "PHP для новичков", создана пользователем Dron-Boy, 2 авг 2018.

  1. Dron-Boy

    Dron-Boy Старожил

    С нами с:
    20 ноя 2014
    Сообщения:
    1.041
    Симпатии:
    126
    На основе видео урока я сделал каркас. Изначально все подключалось в index файле что не есть хорошо я сделал класс load который подключает контроллер, модель и классы исходя из запрошенного адреса. Но потом возникли потребности подключить в одном контроллере второй чтобы вызвать метод исходя из того что я когда инклудю контроллер допустим user.php в контроллере tasks.php то модель контроллера users.php подключена не будет, потому что как говорил выше она подключается в зависимости от урла. Решил изменить и инклудить модель не в классе load а в самом контроллере в методе __consturct.
    Вот как то так
    PHP:
    1. class c_Tasks{
    2.         protected $view;
    3.         protected $task;
    4.         protected $user;
    5.         public function __construct(){
    6.             $this->view =  new \View();
    7.             $routes = explode('/',$_SERVER['REQUEST_URI']);
    8.             if(!$routes[1]){
    9.                 $routes[1] = 'tasks';
    10.             }      
    11.             include_once 'models/'.$routes[1].'.php'; //Подключаю модель
    12.             include_once 'users.php'; //второй контроллер методы которого мне нужны
    13.             $this->task =  new \m_Tasks();
    14.             $this->user =  new c_Users();
    15. }
    16.         }
    И когда я запрашиваю допутим вот такой урл
    site.ru/tasks/getTodayTask
    получается подключается контроллер controller/tasks.php
    и вызывается метов getTodayTask
    в __construct подключается модель
    models/tasks.php
    и записывается в переменную
    PHP:
    1. $this->task =  new \m_Tasks();
    в итоге у меня ошибка
    Cannot redeclare class m_Tasks
    Подскажите почему.

    Так же в
    в видео мы прописывали namespace
    namespace App;
    Но я так и не понял для чего он.
    И если я не правильно делаю. Скажите как делать правильно.
     
  2. Dron-Boy

    Dron-Boy Старожил

    С нами с:
    20 ноя 2014
    Сообщения:
    1.041
    Симпатии:
    126
    И еще как правильно вот подключать в контроллере tasks контроллер users и вызывать метод контроллера users в котором обработаются полученные данные и вызовется модель. Либо подключать модель users напрямую в контроллере tasks ?
    --- Добавлено ---
    Так все я решил проблему. Но все же ответьте пожалуйста на вопросы. Что я оставил.
     
  3. villiwalla

    villiwalla Активный пользователь

    С нами с:
    14 дек 2016
    Сообщения:
    471
    Симпатии:
    70
    Не знаю что ты там за уроки смотришь, но судя по результату не очень хорошие. Я бы тебе порекомендовал вот их глянуть https://php-start.com/course/php-start-practice (не реклама).
    В тему автозагрузки классов https://php.ru/manual/ref.spl.html
    Про неймспейсы, будет у тебя два класса с одинаковым именем, но с разной логикой, и нужно из запустить в одном месте, а не получится т.к "Cannot redeclare", вот эту проблему они и решают, мягко говоря. А вообще про них подробней в PSR написано по мимо офф.документации.
     
    askanim нравится это.
  4. Dron-Boy

    Dron-Boy Старожил

    С нами с:
    20 ноя 2014
    Сообщения:
    1.041
    Симпатии:
    126
    А вот на это что скажаешь?
    И еще как правильно вот подключать в контроллере tasks контроллер users и вызывать метод контроллера users в котором обработаются полученные данные и вызовется модель. Либо подключать модель users напрямую в контроллере tasks ?
    --- Добавлено ---
    Ну с видеоурока я уловил саму суть.
     
  5. villiwalla

    villiwalla Активный пользователь

    С нами с:
    14 дек 2016
    Сообщения:
    471
    Симпатии:
    70
    На что?
    Тебе для начала нужно написать роутер который будет запускать нужный контроллер и метод в нем в зависимости от урла. А уже в методе реализует все что тебе нужно, логику в моделях соответственно. Кто как предпочитает тонкие или толствт контроллеры.
     
  6. Dron-Boy

    Dron-Boy Старожил

    С нами с:
    20 ноя 2014
    Сообщения:
    1.041
    Симпатии:
    126
    Роутер есть раньше подключал я в нем модель в зависиости от урла, потом поменял и модель подключаю в контроллере что бы если обратится к контроллеру не по урлу в адресной строке вызвать метод контроллера.
     
  7. smitt

    smitt Старожил

    С нами с:
    3 янв 2012
    Сообщения:
    3.166
    Симпатии:
    65
    не понял, что? Контроллер должен вызываться при обращении к нему через адресную строку в браузере
    --- Добавлено ---
    Чет не нравится как конструктор используешь... А можешь код на гит выложить?
     
  8. Dron-Boy

    Dron-Boy Старожил

    С нами с:
    20 ноя 2014
    Сообщения:
    1.041
    Симпатии:
    126
    не могу. Я выше спрашивал. Вот есть у меня контроллер tasks в нем нужно запросить данные помимо основной модели tasks также из модели users и что бы не обращаться к модели на прямую я инклудю контроллер users и вызываю метод который мне нужен. Или это не правильно? нужно инклудить нужную модель в нужном мне контроллере? например в том же контроллере task инклудить модель users и вызывать нужный мне метод?
     
  9. villiwalla

    villiwalla Активный пользователь

    С нами с:
    14 дек 2016
    Сообщения:
    471
    Симпатии:
    70
    Поставка этих вопросов и есть твоя проблема потому что:
    Как я понял, суть ты поймал, но материал изучил не до конца?

    [​IMG]

    1. Запрос отправляется на единую точку входа у которой есть автозагрузчик классов, ссылку уже давал
    2. Роутер разруливает url и вызывает нужный контроллер и дёргает нужный метод из контроллера
    например: url = domina.com/tasks/169321, что делает роутер, он ищет в роутах подходящий роут. Например находит он такой роут:
    PHP:
    1. ['tasks/<:id>' => 'tasks/show']
    2.1 Вызывает
    PHP:
    1. new TasksController()->show();
    3. В методе контроллера уже пишешь:
    PHP:
    1. $model = Tasks::find(['id' => $id]);
    Понятно ещё есть виьюхи и остаётся вопрос за передачей параметров в котроллер, но это уже другая тема немного для ТС ;)
     
  10. smitt

    smitt Старожил

    С нами с:
    3 янв 2012
    Сообщения:
    3.166
    Симпатии:
    65
    нужно использовать автозагрузку
    https://php.net/manual/ru/language.oop5.autoload.php
    --- Добавлено ---
    А можешь объяснить для чего ты protected используешь?
     
  11. villiwalla

    villiwalla Активный пользователь

    С нами с:
    14 дек 2016
    Сообщения:
    471
    Симпатии:
    70
    PHP:
    1. include_once 'users.php'; //второй контроллер методы которого мне нужны
    Контроллер не должен вызывать второй контроллер если не не перенаправляешь. Если у тебя получается так что есть методы в контроллере которые могут понадобится в другом контроллере, либо наследуй все контроллеры от суперКласс (основного контроллера) или используй трейты (trait) для общих методов, хелперы и т.д Аналогично для моделей через наследование и т.д
     
    mkramer нравится это.
  12. ElisDN

    ElisDN Активный пользователь

    С нами с:
    13 фев 2018
    Сообщения:
    605
    Симпатии:
    130
    Неправильно. Не инклюдьте контроллеры друг в друга. Инклюдьте обе и бращайтесь к двум моделям напрямую.
     
  13. Dron-Boy

    Dron-Boy Старожил

    С нами с:
    20 ноя 2014
    Сообщения:
    1.041
    Симпатии:
    126
    получается я могу прописать в роутах что то типо этого
    PHP:
    1. ['tasks/<:id>' => 'tasks/show','users/user']
    и тд. а когда подключаю подключать контроллер только первы элемент массива а модель это будут все элменты и уже с контроллера tasks смогу обращатся к моделе users. Так можно делать?
     
  14. smitt

    smitt Старожил

    С нами с:
    3 янв 2012
    Сообщения:
    3.166
    Симпатии:
    65
    Чего? Не понятно.
     
  15. villiwalla

    villiwalla Активный пользователь

    С нами с:
    14 дек 2016
    Сообщения:
    471
    Симпатии:
    70
    Ещё раз, да тех кто в танке. 1 URL = 1 Метод в 1 Контроллере, в Методе Контроллера уже создаёшь нужное количество нужных моделей.
    Ты на картинке видишь чтобы с роутов была модель?
    [​IMG]
    [​IMG]
     
  16. Dron-Boy

    Dron-Boy Старожил

    С нами с:
    20 ноя 2014
    Сообщения:
    1.041
    Симпатии:
    126
    Ок 1url = 1 контроллер с методом и 1 модель. то есть я беру иду по урлу
    /tasks/deleteTask
    Подключаю контроллер tasks и вызываю метод deleteTask и подключаю модель tasks.
    В этом методе (контроллера) нужно вызвать метод из другой модели (users) что бы получить данные о пользователи. Я же инклудить ее не буду в контроллере, так что тогда создавать еще один метод в моделе tasks как и в моделе users но будет два метода которые выполняют одни и теже действия.
     
  17. villiwalla

    villiwalla Активный пользователь

    С нами с:
    14 дек 2016
    Сообщения:
    471
    Симпатии:
    70
    "Научи дурака богу молится, он себе лоб расшибёт."
    Ну прогресс есть.
    1. Вы как внимание не теряете?
    2. Про автозагрузку читали?
    3. Видео о MVC посмотрели?
    4. С ООП на ВЫ или даже не заочно?
    Рука лицо....

    index.php
    PHP:
    1. spl_autoloader_registry(function($class) {
    2.   require_once $class.'.php';
    3. });
    4.  
    5. Router::init();
    Модели:
    Users.php
    PHP:
    1. namespace App\Model\Users;
    2. class Users extends Model {
    3.  .....
    4. }


    Tasks.php
    PHP:
    1. namespace App\Model\Tasks;
    2. class Tasks extends Controller {
    3.  .....
    4. }
    TasksController.php
    PHP:
    1. use App\Model\Users;
    2. use App\Model\Tasks;
    3. class TasksContrller.php {
    4.  public function delete() {
    5.    $user = new Users();
    6.    $tasks = new Tasks();
    7.  
    8.    $taskId = $_POST['task']['id'];
    9.    Tasks::delete($taskId);
    10.  
    11.  }
    12. }
    Пониме?
     
  18. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.860
    Симпатии:
    657
    @Dron-Boy, тролль?
     
  19. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.598
    Симпатии:
    1.764
    @Dron-Boy, тут важно понимать, что модель - это не только непосредственно работа с базой, и воспринимать модель только в этом контексте неправильно. Модель в MVC - это весь слой работы с данными, и рассчёты, и хранение, и пересечение. Потом, никто не запрещает создавать классы, которые не являются не являются контроллерами, а делают вспомогательные действия, если у тебя действительно нужно продублировать много кода в контроллере задач и пользователей, то можно вынести общий код в такой класс. А "инклюдить" класс модели ты можешь куда тебе нужно, это не называется повторяющимся кодом.
     
  20. Dron-Boy

    Dron-Boy Старожил

    С нами с:
    20 ноя 2014
    Сообщения:
    1.041
    Симпатии:
    126
    Нет не теряю, но просто не допонимаю.
    Почитал, но пока пытаюсь понять для чего она.
    Да посмотрел, вот это видео
    Немного знаю.
    Исходя из вашего кода впринципе все стало понятно кроме
    А почему метод статичный?
     
  21. villiwalla

    villiwalla Активный пользователь

    С нами с:
    14 дек 2016
    Сообщения:
    471
    Симпатии:
    70
    Название само за себя говорит!

    Посмотри полностью это https//php-start.com/course/php-start-practice

    Смотри видео читай про автозагрузку!

    Да хоть объект, это вопрос не к сути дела.
     
  22. Dron-Boy

    Dron-Boy Старожил

    С нами с:
    20 ноя 2014
    Сообщения:
    1.041
    Симпатии:
    126
    Когда задаешь namespace название файла должно быть как и название класса?
    Посмотрел пару видео по namespace вроде как понял.
    Щас посмотрю видео и буду дальше разбираться.
     
  23. villiwalla

    villiwalla Активный пользователь

    С нами с:
    14 дек 2016
    Сообщения:
    471
    Симпатии:
    70
    Что уже сразу по нормальному https://svyatoslav.biz/misc/psr_translation/
     
  24. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
    Оооооооооооооооооооооооооох..... @Dron-Boy тебе видео дали смотри иди !
    Вот я тебе его открыл!
     
  25. Dron-Boy

    Dron-Boy Старожил

    С нами с:
    20 ноя 2014
    Сообщения:
    1.041
    Симпатии:
    126
    Я разобрался с автолоадером и namespace и потихоньку меняю все в проекте. Но тут наткнулся на проблему у меня подключен Eloquent, делал ведь по тому видеоуроку.
    когда дошел до подключения модели вот как у меня написано


    PHP:
    1.   namespace models;
    2.     class tasks extends \Illuminate\Database\Eloquent\Model{
    3.      
    4.         public $timestamps = false;
    5.         public $table = 'tasks';
    6. }
    ну и там методы. Так вот мне сейчас выдает ошибку

    Warning: require_once(Doctrine/DBAL/Driver/PDOConnection.php): failed to open stream: No such file or directory in /home/cpinua/site.ru/index.php on line 7

    Fatal error: require_once(): Failed opening required 'Doctrine/DBAL/Driver/PDOConnection.php' (include_path='.:/opt/alt/php56/usr/share/pear:/opt/alt/php56/usr/share/php') in /home/cpinua/site.ru/index.php on line 7

    и я вот пока незнаю как исправить.

    Мне кажется неправильно наследуется класс.