Форум программистов, компьютерный форум, киберфорум
PHP: ООП
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.88/8: Рейтинг темы: голосов - 8, средняя оценка - 4.88
 Аватар для Gcom
82 / 82 / 18
Регистрация: 03.02.2016
Сообщений: 564
Записей в блоге: 1

Ковыряем MVC

18.08.2016, 13:24. Показов 2009. Ответов 30
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Решил разобраться с концепцией MVC и понять как оно работает. За основу взял ЭТО
В общем немного упростил для лучшего восприятия и вот что получилось:
Файл index.php
Кликните здесь для просмотра всего текста
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<?php
header("Content-Type:text/html; charset=UTF-8");
ini_set('display_errors', 1);
error_reporting(E_ALL); # error_reporting(0); session_start();
function myprint($obj) { echo ('<pre>'); var_dump($obj); echo ('</pre><hr>'); }
# подключаем файлы ядра
#require_once 'application/core/model.php';
class Model {
}
#require_once 'application/core/view.php';
class View {
    function generate($content_view, $template_view, $data = null) {
        include_once 'application/views/'.$template_view;
    }
}
#require_once 'application/core/controller.php';
class Controller {
    function __construct() {
        $this->view = new View();
    }
}
#require_once 'application/core/route.php';
class Route {
    static function start() {
        # контроллер и действие по умолчанию
        $controller_name = 'Main';
        $action_name = 'index';
        
        $routes = explode('/', $_SERVER['REQUEST_URI']);
        # получаем имя контроллера
        if (!empty($routes[1])) {   
            $controller_name = $routes[1];
        }
        # получаем имя экшена
        if (!empty($routes[2])) {
            $action_name = $routes[2];
        }
        # добавляем префиксы
        $model_name      = 'Model_'.$controller_name;
        $controller_name = 'Controller_'.$controller_name;
        $action_name     = 'action_'.$action_name;
        # подцепляем файл с классом модели (файла модели может и не быть)
        $model_file = strtolower($model_name).'.php';
        $model_path = 'application/models/'.$model_file;
        #
        if (file_exists($model_path)) {
            include_once 'application/models/'.$model_file;
        }
        # подцепляем файл с классом контроллера
        $controller_file = strtolower($controller_name).'.php';
        $controller_path = 'application/controllers/'.$controller_file;
        #
        if (file_exists($controller_path)) {
            #echo ('Путь  '.$controller_path.' существует<br>');
            include_once 'application/controllers/'.$controller_file;
            # создаем контроллер
            $controller = new $controller_name;
            $action     = $action_name;
            #
            if (method_exists($controller, $action)) {
                # вызываем действие контроллера
                $controller->$action(); # В частности $Controller_Main->action_index();
            } else {
                # здесь также разумнее было бы кинуть исключение
                Route::ErrorPage404();
            }
 
        } else {
            # редирект на страницу 404
            Route::ErrorPage404();
        }
    }
 
    function ErrorPage404() {
        $sHost = 'http://'.$_SERVER['HTTP_HOST'].'/';
        header('HTTP/1.1 404 Not Found');
        header('Status: 404 Not Found');
        header('Location:'.$sHost.'404');
    }
}
 
Route::start(); # запускаем маршрутизатор
?>

Файл controller_404.php
PHP
1
2
3
4
5
6
7
8
<?php
class Controller_404 extends Controller {
    
    function action_index() {
        $this->view->generate('404_view.php', 'template_view.php');
    }
}
?>
Файл 404_view.php
HTML5
1
2
3
4
<div style="margin:5px;">
    <p>К сожалению при обработке вашего запроса произошла ошибка. Запрашиваемая вами страница не существует или была удалена администратором.</p>
    <p style="margin:5px;"><img src="/images/404.jpg"></p>
</div>
Файл template_view.php
PHP/HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Шаблон сайта</title>
</head>
<body>
<?php include_once 'application/views/'.$content_view; ?>
<div>
    <p>Тут будет footer</p>
</div>
</body>
</html>
Собственно в чем вопрос, не могу понять как выводить footer "по умолчанию" если его запихать в файл footer_view.php
HTML5
1
2
3
<div>
    <p>Тут будет footer</p>
</div>
На ум приходить просто:
PHP
1
<?php include_once 'application/views/footer_view.php'; ?>
Но хотелось бы его выводить используя контроллер, или я заморачиваюсь сильно?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
18.08.2016, 13:24
Ответы с готовыми решениями:

Ковыряем SWF файлы
управление SWF из вне. Задача: Есть игра на одном хххххх сайте, она написана на Flash. Хочу написать программу на c++ которая...

Как широко применяется MVC в программировании на Java? Стоит ли изучать MVC?
Здравствуйте. Начинающий java-программист. Буквально недавно только закончил изучать Core. Теперь готовлюсь к собеседованиям и своей первой...

связь MVC и MVVM. Трудно ли освоить mvc параллельно с изучением ASP.NET
Здравствуйте, начал изучать ASP.NET для курсовой работы. Начал читать &quot;Мак-Дональд М., Фримен А., Шпушта М. Microsoft ASP.NET 4 с примерами...

30
 Аватар для Gcom
82 / 82 / 18
Регистрация: 03.02.2016
Сообщений: 564
Записей в блоге: 1
20.08.2016, 09:11  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Para bellum Посмотреть сообщение
У большинства популярных движков код вообще омерзительный.
Ну вот я не хочу сделать подобное

Почему пришел к выводу что нужно четко определиться со структурой и логикой работы контроллеров на этапе проектирования. Но прочитав "тонны" статей, в голове только каша, мало чего годного есть, что можно взять за основу.
0
Эксперт PHP
3900 / 3238 / 1353
Регистрация: 01.08.2012
Сообщений: 10,914
20.08.2016, 09:49
Цитата Сообщение от Gcom Посмотреть сообщение
а почему бы не наследовать его от базового контролера, там же все равно будут использоваться тоже базовые методы
Повторюсь, для каждой страницы админки нужна авторизация. Не авторизован - редирект на форму логина, или просто на главную. Это "поведение" можно указать в C_Admin_Base.

В C_Base этого делать не нужно, поскольку каталог товаров должны видеть все. Зато на каждой странице нужно отображать корзину с кол-вом товаров и итоговой суммой заказа. Соответственно, здесь можно получить корзину и передать её в базовый шаблон вместе с остальными данными.

Но для админки корзина не нужна. Вот и получается, что в одном контроллере мы делаем что-то общее для админки, в другом - что-то общее для публичной страницы.

Добавлено через 2 минуты
Цитата Сообщение от Para bellum Посмотреть сообщение
Я вот ни один движок не изучил до сих пор.
Та же ситуация... мельком видел Симплу, чуть-чуть Престу, и пару сайтов делал на Опенкарте... в итоге забил на это дело. Слишком они жуткие внутри.
0
 Аватар для Gcom
82 / 82 / 18
Регистрация: 03.02.2016
Сообщений: 564
Записей в блоге: 1
20.08.2016, 09:55  [ТС]
Цитата Сообщение от Jodah Посмотреть сообщение
Но для админки корзина не нужна.
Ну это понятно что не нужна.
Цитата Сообщение от Jodah Посмотреть сообщение
Повторюсь, для каждой страницы админки нужна авторизация.
Дак для каждого пользователя тоже нужна авторизация (да бы оформить тот же заказ)
Цитата Сообщение от Jodah Посмотреть сообщение
Не авторизован - редирект на форму логина, или просто на главную.
А зачем редирект? Не проще ли, конечный контент формировать с помощью контроллеров таким образом:
Если пользователь не авторизован - выводим "контент" №1
Если пользователь авторизован, но не админ - выводим "контент" №2
Если пользователь авторизован и он админ - выводим "контент" №3
Чем плоха такая схема?
0
Эксперт PHP
3900 / 3238 / 1353
Регистрация: 01.08.2012
Сообщений: 10,914
20.08.2016, 10:20
Цитата Сообщение от Gcom Посмотреть сообщение
Дак для каждого пользователя тоже нужна авторизация (да бы оформить тот же заказ)
Далеко не всегда. Некоторым магазинам авторизация и ЛК изначально не нужны, к тому же есть быстрые заказы.

Цитата Сообщение от Gcom Посмотреть сообщение
Чем плоха такая схема?
Иногда права нужно настраивать более гибко, чем гость/не админ/админ. Скажем, менеджер может просматривать информацию о товаре, но не может менять. А контент-менеджер может менять товары, но не может просматривать заказы.

Поэтому имхо правильней сделать в C_Admin_Base просто проверку на авторизацию, а в конечном контроллере уже проверять, есть ли у авторизованного юзера права на конкретное действие.
0
 Аватар для Gcom
82 / 82 / 18
Регистрация: 03.02.2016
Сообщений: 564
Записей в блоге: 1
20.08.2016, 10:31  [ТС]
Цитата Сообщение от Jodah Посмотреть сообщение
Иногда права нужно настраивать более гибко, чем гость/не админ/админ. Скажем, менеджер может просматривать информацию о товаре, но не может менять. А контент-менеджер может менять товары, но не может просматривать заказы.
Дак что мешает эти виды ролей указать в БД
гость/не гость/пользователь/ не пользователь/админ/не админ/менеджер/не менеджер/(да хоть собака/кошка/корова)
и сделать для них привилегии гнать/держать/смотреть/видеть/дышать/слышать/ненавидеть/зависеть/вертеть/обидеть/терпеть
ну сделать таблицу прав (кто на что имеет права)
это и расширять удобно, появился пользователь зарегистрировался, по умолчанию проставила система ему права в таблице прав.
добавилось новая привилегия, добавил ее нужным пользователям.
0
Эксперт PHP
3900 / 3238 / 1353
Регистрация: 01.08.2012
Сообщений: 10,914
20.08.2016, 10:47
Gcom, ничего не мешает, я и имел ввиду, что нужно использовать подобную систему.

Мне только непонятно, как вы предлагаете делать проверку прав на конкретное действие в C_Admin_Base (или C_Controller?). Получается, базовый контроллер должен посмотреть на URL и пришедшие GET/POST данные и, в зависимости от них, проверить наличие прав. Предполагаю, что получится трудномасштабируемый столб текста.
0
 Аватар для Gcom
82 / 82 / 18
Регистрация: 03.02.2016
Сообщений: 564
Записей в блоге: 1
20.08.2016, 11:01  [ТС]
Цитата Сообщение от Jodah Посмотреть сообщение
Получается, базовый контроллер должен посмотреть на URL и пришедшие GET/POST данные и, в зависимости от них, проверить наличие прав.
Да я и сам пока что мало чего понимаю, как это будет выглядеть в конечном виде, когда это все дело будет реализовано через классы и паттерн MVC, пока на локальном сервере есть наброски с авторизацией (рабочей) и она как раз реализована по тому принципу который я описал выше используя сессии, как это дело будет работать с классами я не очень пока понимаю.
Но мысли все же есть: думаю возложить все эти проверки на "роутер", так сказать роутер как раз и будет анализировать входящие запросы и уже на основе этого вызывать нужные классы. Может я и не на правильном пути, но пока другого я не вижу
0
Эксперт PHP
5755 / 4134 / 1508
Регистрация: 06.01.2011
Сообщений: 11,276
20.08.2016, 11:17
Можно так организовать проверку доступа к контроллерам:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
<?php
    
    /**
     * Посредник запросов к контроллерам.
     * Само собой, нужно оптимизировать
     */
    class Middleware {
        
        /**
         * Метод должен ничего не возвращать, если проверка прошла успешно
         * 
         * @return mixed
         */
        public function admin(){
            if(!$user->isAdmin())
                return redirect('/');
        }
        
        /**
         * Запуск нужного метода проверки
         * 
         * @param string $name 
         * 
         * @return void
         * @throws MiddlewareException
         */
        public function make($name){
            $result = $this->$name();
            
            # Если проверка прошла неудачно
            if(!is_null($result))
                throw new MiddlewareException($result);
        }
    }
    
    
    /**
     * Базовый класс Application Controllers.
     * Так же нужно оптимизировать.
     */
    class Controller {
    
        /**
         * Вызов посредника
         * @param string $name 
         * 
         * @return void
         */
        protected function middleware($name){
            $middleware = new Middleware;
            
            $middleware->make($name);
        }
    }
    
    class ProductController extends Controller {
        public function __construct(){
            /**
             * При создании объекта класса контроллера вызовется посредник и либо допустит к работе с контроллером, либо
             * перенаправит, куда нужно или заблокирует с кодом 403.
             */
            $this->middleware('admin');
        }
    }
    
    try{
        $controller = new ProductController;
    }
    catch(MiddlewareException $e){
        # Тут, в зависимости от того, что вернул посредник, производим какие-то действия.
    }
2
 Аватар для Gcom
82 / 82 / 18
Регистрация: 03.02.2016
Сообщений: 564
Записей в блоге: 1
20.08.2016, 11:51  [ТС]
А поясните мне такой момент, попалась мне на глаза такая функция:
PHP
1
2
3
4
5
6
7
8
/** 
* Автоматически подгружает запрошенные классы. 
* @param type $className наименование класса. 
* @return void */
function __autoload($className){
  $path = str_replace('_', '/', strtolower($className));
  return include_once $path.'.php';
}
не как не могу понять как ею пользоваться зачем она вообще нужна?
0
Эксперт PHP
3900 / 3238 / 1353
Регистрация: 01.08.2012
Сообщений: 10,914
20.08.2016, 12:05
Gcom, тыц, 13 сообщение
1
 Аватар для Gcom
82 / 82 / 18
Регистрация: 03.02.2016
Сообщений: 564
Записей в блоге: 1
20.08.2016, 12:27  [ТС]
Цитата Сообщение от Jodah Посмотреть сообщение
Когда вы пытаетесь обратиться к несуществующему классу, например new ROUTER(), функция автолоадер запускается автоматически, а в переменную $class попадает само название 'ROUTER'.
Создавать объекты внутри лоадера не нужно. Нужно только подключить файл с нужным классом, если он существует.
Ну вот я нашел что искал, хоть и не в 13 сообщении, с function __autoload разобрался.
Да и в той теме есть что почитать и поучиться
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
20.08.2016, 12:27

ASP.net MVC против MVC обычного
Здраствуйте, читая книгу &quot;Сандерсон С - ASP.NET MVC3 Framework с примерами на C# для профессионалов&quot; я заметил что описание...

Стоит ли изучать asp.net mvc 4 из за скорого выхода asn.net mvc vNext ?
Доброго вечера! Как я узнал, Microsoft скоро планирует выпустить новый веб-фреймворк с названием vNext который позиционируется как...

Разница между MVC 4 и MVC 5
Подскажите пожалуйста основные различия между 4 и 5 версией. В наличии есть книга Фримана по MVC 4ой версии, возможно ли по ней обучаться...

Перенос кода с MVC 2 на MVC 4
Здравствуйте! Переношу код с проекта написанного на MVC 2 на MVC 4. Столкнулся с компонентом. Сперва идет его объявление, затем...

ASP.NET MVC 4,ASP.NET MVC 4.5 и ASP.NET MVC 5 большая ли разница между ними?
Начал во всю осваивать технологию,теперь хочу с книжкой посидеть и вдумчиво перебрать всё то что увидел,услышал и набил...в общем какую...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
31
Ответ Создать тему
Новые блоги и статьи
Море в объективе
kumehtar 06.07.2026
Хотел написать много проникновенных слов, но передумал. Оно само - говорит. Кто слышит тот слышит.
Оказывается, Unreal Engine позволяет качество на порядки выше, чем было в Lineedge
Etyuhibosecyu 05.07.2026
Жаль, конечно, что я не узнал об этом, пока Lineedge существовала, а то бы Noname2331 написал, что волки превращаются в пиксельную кашу, а я бы его попросил скачать какую-нибудь бриллиантовую или Pro. . .
Doom для терминала без стрельбы и монстров. 3D Raycasting на ascii.
dcc0 05.07.2026
Попросил нейронную сеть deepai. org написать рейкастинг 3D с библиотекой ncurses для Linux. Чтобы можно было ходить на стрелочки. Чтобы стены были отрисованы символами. Справилась. Первый вариант. . .
Установка статуса документа по условию
Maks 05.07.2026
Алгоритм из решения ниже реализован на нетиповом документе "НарядПутевка" разработанного в КА2. Задача: в табличной части "Материалы" документа при записи автоматически устанавливать статус. . .
Сезонность и суточность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет. Но обычно это 50 лет и более. Наверное, закисление почвы происходит сезонно в средней. . .
В чем ценность человеческого опыта в глобальном смысле?
kumehtar 03.07.2026
Возможно, ценность человека не в том, что он однажды достигает мудрости, а в том, что он становится носителем карты пути. Он знает не только истину, но и последовательность внутренних изменений,. . .
интеграция AnyLogic с самописным REST API и переход на Odoo
anaschu 03.07.2026
Успешная интеграция AnyLogic с самописным REST API и переход на промышленную Odoo WMS Сегодня проделал огромный путь от простой симуляции физических процессов до построения полноценной. . .
Поиск всех путей на ориентированном графе. Linux
dcc0 02.07.2026
Переработка старого кода из моей статьи. Через несколько переработок от PHP кода к C89 (надеюсь, 89). Но довольно запутанно получилось. Код для Linux. Но если убрать time и то, что с ним. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru