За последние 24 часа нас посетили 18455 программистов и 1704 робота. Сейчас ищут 909 программистов ...

Плохо понимаю работу MVC

Тема в разделе "PHP для новичков", создана пользователем Dimon2x, 3 янв 2018.

  1. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.211
    Симпатии:
    186
    Есть страница с логином

    PHP:
    1. <?php include ROOT . '/views/layout/header.php'; ?>
    2.  
    3.  
    4.            <section class="content clearfix">
    5.  
    6.                 <?php if (isset($errors) && is_array($errors)): ?>
    7.                     <ul>
    8.                         <?php foreach ($errors as $error): ?>
    9.                             <li> - <?php echo $error; ?></li>
    10.                         <?php endforeach; ?>
    11.                     </ul>
    12.                 <?php endif; ?>
    13.  
    14.                 <div class="signup-form"><!--sign up form-->
    15.                     <h2>Вход на сайт</h2>
    16.                     <form action="#" method="post">
    17.                         <input type="input" name="name" placeholder="Логин" value="<?php echo $name; ?>"/> <!-- переменные берутся из UserController actionLogin() -->
    18.                         <input type="password" name="password" placeholder="Пароль" value="<?php echo $password; ?>"/>
    19.                         <input type="submit" name="submit" class="btn btn-default" value="Вход" />
    20.                     </form>
    21.                 </div><!--/sign up form-->
    22.              </section>  
    Переменные name и password находятся в классе User в методе actionLogin и я не понимаю, как они вызываются напрямую?

    Все действия обрабатывает роутер

    PHP:
    1. <?php
    2.  
    3.     class Router {
    4.         private $routes; //здесь будет массив, в котором будут храниться маршруты
    5.        
    6.         public function __construct() {
    7.             $routesPath = ROOT . '/config/routes.php';
    8.             $this->routes = include($routesPath);
    9.         }
    10.        
    11.        
    12.         //метод возвращает строку
    13.         private function getURI() {
    14.             if(!empty($_SERVER['REQUEST_URI'])) {
    15.                 return trim($_SERVER['REQUEST_URI'], '/');
    16.             }
    17.         }
    18.        
    19.         public function run() {
    20.             $uri = $this->getURI();
    21.            
    22.             echo '<pre>';
    23.                 print_r($uri);
    24.             echo '</pre>';
    25.            
    26.             echo '<pre>';
    27.                 print_r($this->routes);
    28.             echo '</pre>';
    29.                        
    30.            
    31.            
    32.             foreach($this->routes as $uriPattern => $path) {
    33.                
    34.                 if(preg_match("~$uriPattern~", $uri)) {
    35.                    
    36.                     $internalRoute = preg_replace("~$uriPattern~", $path, $uri);
    37.                    
    38.                     echo $internalRoute; //ввели в браузер catalog и изменили на catalog/index
    39.                     //echo '<br>';
    40.                    
    41.                     //echo '--------------------------';
    42.                     //echo '<br>';
    43.                    
    44.                     $segments = explode('/', $internalRoute); //разделили на catalog и index
    45.                    
    46.                     echo '<pre>';
    47.                         print_r($segments);
    48.                     echo '</pre>';
    49.                                        
    50.                    
    51.                     //берём первое значение массива, то есть catalog и присоединяем Controller
    52.                     //в итоге получается catalogController
    53.                     //после этого из массива этот элемент пропадает
    54.                     $controllerName = array_shift($segments).'Controller';
    55.                    
    56.                     //делаем первую букву большой и получается CatalogController
    57.                     $controllerName = ucfirst($controllerName);
    58.                     echo '<br>$controllerName: ' . $controllerName;
    59.                    
    60.                    
    61.                     //присоединяем action к первому элементу массива и это получится
    62.                     //метод в классе, который лежит в контроллере
    63.                     $actionName = 'action'.ucfirst(array_shift($segments));
    64.                     $parameters = $segments;
    65.                    
    66.                    
    67.                     //ищем этот контроллер файл
    68.                     $controllerFile = ROOT . './controllers/' . $controllerName . '.php';
    69.                     echo '<br>';
    70.                     echo '<br>' . $controllerFile;
    71.                    
    72.                     //если файл есть, то подключаем его
    73.                     if(file_exists($controllerFile)) {
    74.                         require_once($controllerFile);
    75.  
    76.                     }
    77.                    
    78.                         $controllerObject = new $controllerName;
    79.                        
    80.                         echo '<br>$actionName: ' . $actionName;
    81.                         echo '<br>';
    82.                        
    83.                         if(method_exists($controllerObject,$actionName)) {
    84.                             //$result = call_user_func_array([$controllerObject, $actionName], $parameters);
    85.                                                     $result = $controllerObject->$actionName(...$parameters);
    86.  
    87.                            
    88.                         }
    89.                        
    90.                        
    91.                        
    92.                        
    93.                         else {
    94.                             echo 404;
    95.                                                         $result = 0;
    96.                         }
    97.                         //
    98.                    
    99.                                                  
    100.                         print_r($controllerObject);
    101.                         echo '<pre>';
    102.                             print_r($parameters);
    103.                         echo '</pre>';
    104.                                                    
    105.                                                    
    106.                    
    107.                    
    108.                    
    109.                    
    110.                    
    111.                     //прекращаем цикл, потомуч то найден элемент, а дальше смысла искать нет
    112.                     //и посыпятся ошибки, будет перебирать каждую букву
    113.                    
    114.                     if($result != null) {
    115.                         break;
    116.                     }
    117.                    
    118.                    
    119.                 }
    120.             }
    121.         }
    122.     }
    PHP:
    1. <?php
    2. include_once ROOT. '/models/User.php';
    3. /**
    4. * Контроллер UserController
    5. */
    6. class UserController
    7. {
    8.  
    9.     /**
    10.      * Action для страницы "Вход на сайт"
    11.      */
    12.     public function actionLogin() //метод просто проверяет был ли нажат submit всё это делается в роутере
    13.     {
    14.         // Переменные для формы
    15.         $name = false;
    16.         $password = false;
    17.        
    18.         // Обработка формы
    19.        
    20.         if (isset($_POST['submit'])) {
    21.             // Если форма отправлена
    22.             // Получаем данные из формы
    23.             $name = $_POST['name'];
    24.             $password = $_POST['password'];
    25.             // Флаг ошибок
    26.             $errors = false;
    27.             // Валидация полей
    28.            
    29.             if (!User::checkPassword($password)) {
    30.                 $errors[] = 'Пароль не должен быть короче 6-ти символов';
    31.             }
    32.             // Проверяем существует ли пользователь
    33.             $userId = User::checkUserData($name, $password);
    34.             if ($userId == false) {
    35.                 // Если данные неправильные - показываем ошибку
    36.                 $errors[] = 'Неправильные данные для входа на сайт';
    37.             } else {
    38.                 // Если данные правильные, запоминаем пользователя (сессия)
    39.                 User::auth($userId);
    40.                 // Перенаправляем пользователя в закрытую часть - кабинет
    41.                 header("Location: /cabinet");
    42.             }
    43.        
    44.        
    45.         }
    46.         // Подключаем вид
    47.         require_once(ROOT . '/views/user/login.php');
    48.         return true;
    49.        
    50.        
    51.     }
    Я думаю, что эту магию, делает функция
    PHP:
    1. $result = call_user_func_array([$controllerObject, $actionName], $parameters);
    Но не знаю как?
    --- Добавлено ---
    Пробовал вывести напрямую, но почему-то не выводит

    PHP:
    1. <?php
    2.  
    3. class User {
    4.     public function actionLogin($a, $b) {
    5.         $name = false;
    6.         $password = false;
    7.        
    8.         $name = $a;
    9.         $password = $b;
    10.        
    11.         return [$name, $password];
    12.     }  
    13. }
    14.  
    15. $result = call_user_func_array([new User, 'actionLogin'], ['Dima', 123456]);
    16.  
    17. echo $name;
    18.  
    19. echo '<pre>';
    20.     print_r($result);
    21. echo '</pre>';
    --- Добавлено ---
    или это работает, потому что в метод подключён шаблон?
     
  2. Алекс8

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

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    так ты же инклудишь require_once(ROOT .'/views/user/login.php'); файл вот они там и видны...
    --- Добавлено ---
    не... она просто вызывает метод объекта и в качестве аргументов ставит данные из массива..
    --- Добавлено ---
    потому что область видимости тех переменых - внутри метода.. тебе что бы получить к ним доступ надо сделать их свойстами объекта - а оптом уже из объекта их достать..
    а по сабжу - ты внутри метода объявил дви переменные и тут же заинклудил файл.. вот тебе и видны переменные внутри файла, потому что одна область видимости. .
     
    Dimon2x нравится это.
  3. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    @Dimon2x, никакой магии. Ты забыл, что include и require в php буквально включают содержимое одного файла в другой.
    Т.е. если ты пишешь:
    PHP:
    1. <?php
    2. // a.php
    3. echo $a;
    4. echo $b;
    5. ?>
    6. <?php
    7. // b.php
    8. function f() {
    9.    $a = 5;
    10.    $b = 7;
    11.    require "a.php";
    12. }
    то это работает также, как если бы ты написал
    PHP:
    1. <?php
    2.  
    3. function f() {
    4.     $a = 5;
    5.     $b = 6;
    6.     echo $a;
    7.     echo $b;
    8. }
    Поэтому не надо лезть в MVC, пока не поняты основы PHP. Там тоже самое.
     
    Dimon2x нравится это.
  4. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.211
    Симпатии:
    186
    Просто придуманная структура MVC не моя, из-за этого не заметил
     
  5. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    они могут и записывать содержимое файла:
    PHP:
    1. $routesPath = ROOT . '/config/routes.php';
    2.             $this->routes = include($routesPath);
    return array(...) из файла просто не скопипастишь.
     
  6. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    @keren, другой случай. Для этого нужно, чтоб во включаемом файле был return. Но, как бы, форум - не замена документации, и я не обязан в каждом ответе про include пересказывать её полностью.