Introduction The goal of this project was to practice PHP, understand how frameworks work under the hood, and learn something new. ๐
MVC:
Every website consists of three parts: the first one is our frontend, element that the user sees and interact with, that is over View, the second one is our backend element that gets inputs/requests from frontend and executes logic Controller, and the last one is database Model. The flow goes like this: User presses button on our frontend/View to see products catalog, the request gets to our backend/Controller, Controller executes logic to handle this request then uses Model that represents the database, usually one of the tables in it, to get necessary data. Then it forwards this data to your View, and the user sees the content.
First, let's create three folders Models, Views and Controllers, and index.php
file.
In the Models folder, add our first Model Book.php
, and give it one method to simulate database requests.
<?php
class Book {
public function get() {
return [
'title' => 'Best Book',
'author' => 'Me',
'price' => 4.20
];
}
}
In the Views folder, let's add one file home.phtml
that will be used to display our data (I use .phtml
for PHP files that are mostly HTML)
<?php require_once './Models/Book.php' ?>
<!DOCTYPE html>
<html>
<head></head>
<body>
<?php var_dump((new Book)->get()); ?>
</body>
</html>
And in index.php
<?php
require_once './Views/home.phtml';
Serve it with PHP build-in serve php -S localhost:8000
and voila, we have MV part running.
Now let's add Controller, create file MainController.php
in Controllers folder and add one Home method to get data from Book Model and make it available to our View.
<?php
require_once './Models/Book.php';
class MainController
{
public function Home()
{
$books = (new Book)->get();
require_once './Views/home.phtml';
}
}
also in our home.phtml
now let's use $books
variable and remove require_once
statment
<!DOCTYPE html>
<html>
<head></head>
<body>
<?php var_dump($books); ?>
</body>
</html>
and edit index.php
to use Controller instead of directly calling View
<?php
require_once './Controllers/MainController.php';
(new MainController())->Home();
done and we have MVC flow ๐
Autoloader
If we had to use require_once
statements every time we need some class, it would be a complete mess and a pain to manage, so instead now we will be using an autoloader (composer has a built-in one, but we will make our own). The autoloader is invoked every time there is an underfunded class, so by providing it information on how/where it can find all necessary classes it can handle their inclusion on its own.
In our index.php
<?php
spl_autoload_register(
function ($class) {
$path = str_replace('\\', DIRECTORY_SEPARATOR, $class);
include_once __DIR__ . DIRECTORY_SEPARATOR . $path . '.php';
}
);
This method will use namespaces and class names to identify folders and filenames. It will take the class name with namespace, e.g. Models\Book
and turn it into a path, e.g. /models/Book.php
From now on, we don't need to require/include statements; instead, we need to start using namespaces
Now let's modify our file structure and add namespaces to it.
In Book.php
<?php
namespace Models;
class Book
In MainController.php
<?php
namespace Controllers;
use Models\Book;
class MainController
And in index.php
(new Controllers\MainController())->Home();
Now the flow of our system goes like so; request comes to index.php, autoloader finds necessary controller class, and we invoke Home
method on it, Home
method initializes Books model and gets data from it and responds with home
view.