Обо мне

PHP MVC With Database (Very Simple Beginner Example)

Welcome to a tutorial and example of an MVC application with PHP and MySQL. You have probably heard of MVC everywhere in different flavors – Framework, design pattern, concept, architecture, and much more. So just what is it? What does it do and what does it mean? How do we build a PHP application based on MVC!?

MVC stands for “model, view, controller”. When it comes to developing an MVC PHP-MYSQL web application:

  • M odel – Refers to the data structure. In this case, the database.
  • V iew – Refers to the user interface. The HTML and CSS.
  • C ontroller – The “middleman” doing the processing. Accepts input from the view, and works with the model. Self-explanatory, the PHP scripts and libraries themselves.

Yep, it’s that simple actually. But as some tech people love to do, they make simple things look difficult. Let us walk through a simple example in this guide – Read on!

Читайте также:  Php массивы в html

TLDR – QUICK SLIDES

Simple MVC Application Example With PHP MySQL

TABLE OF CONTENTS

PHP MVC EXAMPLE WITH MYSQL

All right, let us now get started with the example of a simple MVC application with PHP and MySQL – Doing a search for users.

DUMMY TABLE & DATA

CREATE TABLE `users` ( `id` bigint(20) NOT NULL, `name` varchar(255) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ALTER TABLE `users` ADD PRIMARY KEY (`id`), ADD KEY `name` (`name`); INSERT INTO `users` (`id`, `name`) VALUES (1, 'John Doe'), (2, 'Jane Doe'), (3, 'Rusty Terry'), (4, 'Peers Sera'), (5, 'Jaslyn Keely');

First, here is the dummy users table that we will be using. Very straightforward with only the user ID and name.

PART 1) MODEL (DATABASE)

pdo = new PDO( "mysql:host=".DB_HOST.";dbname=".DB_NAME.";charset=".DB_CHARSET, DB_USER, DB_PASSWORD, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]); > // (B) CLOSE CONNECTION function __destruct () < if ($this->stmt!==null) < $this->stmt = null; > if ($this->pdo!==null) < $this->pdo = null; > > // (C) RUN A SELECT QUERY function select ($sql, $data=null) < $this->stmt = $this->pdo->prepare($sql); $this->stmt->execute($data); return $this->stmt->fetchAll(); > > // (D) DATABASE SETTINGS - CHANGE TO YOUR OWN! define("DB_HOST", "localhost"); define("DB_NAME", "test"); define("DB_CHARSET", "utf8mb4"); define("DB_USER", "root"); define("DB_PASSWORD", ""); // (E) NEW DATABASE OBJECT $_DB = new DB();

Model refers to the data structure. So in the case of a PHP-MYSQL application, our “model” will be a database class that deals with all the “database stuff” – Connecting to the database, managing the connection, and doing SQL queries.

PART 2) CONTROLLER (PROCESS)

select( "SELECT * FROM `users` WHERE `name` LIKE ?", ["%%"] ); // (C) OUTPUT RESULTS echo json_encode(count($results)==0 ? null : $results);

The controller is a “middleman” that bridges the user input and model. In this case, it will be an endpoint that accepts a $_POST[«search»] from the user, uses the model (database) to search, and return the results.

Читайте также:  Java существует ли переменная

PART 3) VIEW (USER INTERFACE)

Finally, the view should be pretty self-explanatory. It is nothing more than HTML, CSS, Javascript to create the user interface.

DOWNLOAD & NOTES

Here is the download link to the example code, so you don’t have to copy-paste everything.

SUPPORT

600+ free tutorials & projects on Code Boxx and still growing. I insist on not turning Code Boxx into a «paid scripts and courses» business, so every little bit of support helps.

EXAMPLE CODE DOWNLOAD

Click here for the source code on GitHub gist, just click on “download zip” or do a git clone. I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

That’s it for the example, and here are a couple more bits that may be useful to you.

THE “WRONG” WAY

     
execute(["%%"]); $results = $stmt->fetchAll(); // (B4) OUTPUT if (count($results)>0) < foreach ($results as $r) < echo "
- "; >> > ?>

For the guys who are still confused, maybe a negative example of “not good MVC” will help – Putting all the MVC components into a single script.

THE CAVEAT – GOOD & BAD?

Actually, there is absolutely nothing wrong with putting everything into a single script. It is much more convenient and easier for small projects to do so. But if you think of it in “actual MVC terms”, the database (model), the retrieval of data (controller), and the display of data (view) are all in one script.

That is not what we want in MVC. The whole idea of MVC is to have a clear-cut separation of concern, and have individual scripts that deal with each component. I.E. Scripts that deal with the data model should be in an individual script, the controller in another, and the HTML view in yet another.

NOT THE ONLY WAY

I heard the “expert code trolls” scream – This is not MVC! MVC should be in the format of site.com/MODEL/ site.com/VIEW/ site.com/CONTROLLER/ . Well, feel free to stick to your “fixed idea of how MVC should be”. That is not wrong, but please come up with better arguments. True code ninjas know better – MVC is an abstract idea.

How you design a system around MVC is entirely up to you. This tutorial is only a simple example of endless possibilities. Even the “wrong example” above is MVC, it’s just that all 3 components are in a single script; We can create 3 functions and still call it “MVC” – One to connect to the database, one to do the search, and one to draw the HTML.

INFOGRAPHIC CHEAT SHEET

THE END

Thank you for reading, and we have come to the end of this guide. I hope that it has helped you to better understand what MVC is, and if you have anything to add to this guide, please feel free to comment below. Good luck and happy coding!

Источник

Простые MVC-приложения

Я хотел бы затронуть тему правильной архитектуры приложений на PHP. Статья будет посвящена паттерну проектирования MVC. Написать про MVC меня сподвиг именно тот факт, что понимание этого паттерна является ключевым в становлении PHP-программиста. Так что если вы новичок и хотите начать писать программы правильно, читайте дальше.

Теория

Если коротко, то MVC (model view controller) это такой способ написания программы, когда код отвечающий за вывод данных, пишется в одном месте, а код который эти данные формирует, пишется в другом месте. В итоге получается так, что если вам надо подправить вывод вы сразу знаете в каком месте искать. Сейчас все популярные фреймворки используют такую архитектуру.

Также стоит упомянуть тот факт, что существует два лагеря: один пишет логику в контроллерах, второй в моделях. В тех фреймворках, которые знаю я (yii, laravel) логику пишут в контроллерах, а модели являются просто экземплярами ORM. У yii кстати в мануале написано, что писать логику надо в моделях, а потом они сами в примерах пишут её в контроллерах, довольно забавно.

С бизнес-логикой определились, пишем в контроллерах. Также в методах контроллера происходит вызов моделей, которые у нас по сути экземпляры ORM, чтобы с их помощью получить данные из базы над которыми будут производить изменения. Конечный результат отправляется в виды. Виды cодержат HTML-разметку и небольшие вставки PHP-кода для обхода, форматирования и отображения данных.

Ещё можно упомянуть, что есть два вида MVC Page Controller и Front Controller. Page Controller’ом пользуются редко, его подход заключается в использовании нескольких точек входа (запросы к сайту осуществляются к нескольким файлам), и внутри каждой точки входа свой код отображения. Мы будем писать Front Controller с одной точкой входа.

Практика

Начать надо с настройки сервера для переадресации на нашу единую точку входа. Если у нас apache, то в файле .htaccess пишем следующее

RewriteEngine on RewriteCond % !-f RewriteCond % !-d RewriteRule .* index.php [L] 

Дальше в папке нашего проекта создаём папку, которую можно назвать App например. В ней будет следующее содержимое.

Наш Service Locator. Файл App.php

 public static function bootstrap() < static::$router = new App\Router(); static::$kernel = new App\Kernel(); static::$db = new App\Db(); >public static function loadClass ($className) < $className = str_replace('\\', DIRECTORY_SEPARATOR, $className); require_once ROOTPATH.DIRECTORY_SEPARATOR.$className.'.php'; >public function handleException (Throwable $e) < if($e instanceof \App\Exceptions\InvalidRouteException) < echo static::$kernel->launchAction('Error', 'error404', [$e]); >else< echo static::$kernel->launchAction('Error', 'error500', [$e]); > > > 

Сервис локатор нужен чтобы хранить в нём компоненты нашего приложения. Поскольку у нас простое mvc приложение, то мы не используем паттерн registry (как например в yii сделано). А просто сохраняем компоненты приложения в статические свойства, чтобы обращаться к ним было проще. Ещё App регистрирует автозагрузчик классов и обработчик исключений.

Роутер. Файл Router.php

 $route = is_null($route) ? $_SERVER['REQUEST_URI'] : $route; $route = explode('/', $route); array_shift($route); $result[0] = array_shift($route); $result[1] = array_shift($route); $result[2] = $route; return $result; > > 

В простом mvc приложении роутер содержит всего один метод. Он парсит адрес из $_SERVER[‘REQUEST_URI’]. Я ещё не сказал, что все наши ссылки на страницы сайта должны быть вида www.ourwebsite.com/%controller%/%action%, где %controller% — имя файла контроллера, а %action% — имя метода контроллера, который будет вызван.

Файл Db.php

getPDOSettings(); $this->pdo = new \PDO($settings['dsn'], $settings['user'], $settings['pass'], null); > protected function getPDOSettings() < $config = include ROOTPATH.DIRECTORY_SEPARATOR.'Config'.DIRECTORY_SEPARATOR.'Db.php'; $result['dsn'] = ":host=;dbname=;charset="; $result['user'] = $config['user']; $result['pass'] = $config['pass']; return $result; > public function execute($query, array $params=null) < if(is_null($params))< $stmt = $this->pdo->query($query); return $stmt->fetchAll(); > $stmt = $this->pdo->prepare($query); $stmt->execute($params); return $stmt->fetchAll(); > > 

Этот класс юзает файл конфига, который возврашает массив при подключении

Файл Config/Db.php

 'mysql', 'host' => 'localhost', 'dbname' => 'gotlib', 'charset' => 'utf8', 'user' => 'root', 'pass' => '' ];

Наше ядро. Файл Kernel.php

resolve(); echo $this->launchAction($controllerName, $actionName, $params); > public function launchAction($controllerName, $actionName, $params) < $controllerName = empty($controllerName) ? $this->defaultControllerName : ucfirst($controllerName); if(!file_exists(ROOTPATH.DIRECTORY_SEPARATOR.'Controllers'.DIRECTORY_SEPARATOR.$controllerName.'.php')) < throw new \App\Exceptions\InvalidRouteException(); >require_once ROOTPATH.DIRECTORY_SEPARATOR.'Controllers'.DIRECTORY_SEPARATOR.$controllerName.'.php'; if(!class_exists("\\Controllers\\".ucfirst($controllerName))) < throw new \App\Exceptions\InvalidRouteException(); >$controllerName = "\\Controllers\\".ucfirst($controllerName); $controller = new $controllerName; $actionName = empty($actionName) ? $this->defaultActionName : $actionName; if (!method_exists($controller, $actionName)) < throw new \App\Exceptions\InvalidRouteException(); >return $controller->$actionName($params); > > 

Ядро обращается к роутеру, а потом запускает действия контроллера. Ещё ядро может кинуть исключение, если нет нужного контроллера или метода.

Файл Controller.php

Ещё нам нужно создать базовый класс для наших контроллеров, чтобы потом наследоваться от него. Наследовать методы нужно для того, чтобы вы могли рендерить (сформировать вывод) виды. Методы рендеринга поддерживают использование лэйаутов — шаблонов, которые содержат общие для всех видов компоненты, например футер и хэдер.

 public function render ($viewName, array $params = []) < $viewFile = ROOTPATH.DIRECTORY_SEPARATOR.'Views'.DIRECTORY_SEPARATOR.$viewName.'.php'; extract($params); ob_start(); require $viewFile; $body = ob_get_clean(); ob_end_clean(); if (defined(NO_LAYOUT))< return $body; >return $this->renderLayout($body); > >

Файл index.php

Не забываем создать индексный файл в корне:

Создаём контроллеры и виды

Работа с нашим приложением (можно даже сказать минифреймворком) теперь сводится к созданию видов и контроллеров. Пример контроллера следующий (в папке Controllers):

 my_photo

Привет

Меня зовут Глеб и я - веб-разработчик.

Мои контакты:
8-912-641-3462
goootlib@gmail.com

В папке Views/Layout создаём Layout.php:

         

Заключение

Если решите пользоваться кодом приложения, которое описал я, не забудьте создать контроллер Error с методами error404 и error500. Класс для работы с бд, описанный мной, подходит для написания запросов руками, вместо него можно подключить ORM и вас будут настоящие модели.

Источник

Оцените статью