Avis MVC propre

Petit nouveau ! | 1 Messages

24 avr. 2019, 17:17

Bonjour,

je souhaite avoir un avis par rapport à un MVC que j'ai fait.

C'est une simple application d'affichage de voitures d'une base de donnée avec authentification à travers.

Cela ressemble à peux près à cela:
Image


L'index représente comme toujours le cœur ou plutôt le point de passage obligatoire:
<?php

define('URL_ROOT', 'http://' . $_SERVER['SERVER_NAME'] . dirname($_SERVER['SCRIPT_NAME']));

define('DS', DIRECTORY_SEPARATOR);
define('ROOT', dirname(__FILE__));

define('UTIL', ROOT . DS . 'utility');
define('MODELS', ROOT . DS . 'model');
define('VIEWS', ROOT . DS . 'view');
define('CONTROLLERS', ROOT . DS . 'controller');


require_once UTIL . DS . 'model_class.php';
require_once UTIL . DS . 'view_class.php';
require_once UTIL . DS . 'session_class.php';
require_once UTIL . DS . 'controller_class.php';

$url = isset($_GET['url']) ? explode('/', $_GET['url']) : null;
if (empty($url[0])) {
    $controller = 'home';
    $method = 'index';
    $id = 0;
} else {
    $controller = strtolower(trim($url[0]));
    if (empty($url[1])) {
        $method = 'index';
        $id = 0;
    } else {
        $method = strtolower(trim($url[1]));
        if (empty($url[2])) {
            $id = 0;
        } else {
            $id = strtolower(trim($url[2]));
        }
    }
}
$controllerfilename = $controller . '_controller.php';
if (!file_exists(CONTROLLERS . DS . $controllerfilename)) {
    echo 'Controller not existing';
}
include CONTROLLERS . DS . $controllerfilename;
$controllername = ucfirst($controller) . 'Controller';
$ctrl = new $controllername();
if (!method_exists($ctrl, $method)) {
    echo 'The given method does not exist';
}
If ($id)
    $ctrl->$method($id);
else
    $ctrl->$method();
?>

Suit à cela les classes du controller, du model et de la vue:

Controller:
<?php

class Controller {

    protected $session;

    function __construct() {
        $this->session = new Session();
    }

    function redirect($controller = 'home', $method = 'index') {
        header('Location:' . URL_ROOT . '/' . $controller . '/' . $method);
        die();
    }

    function loadModel($object) {
        require_once MODELS . DS . strtolower($object) . '_model.php';
        $classname = $object . 'Model';
        $model = new $classname();
        return $model;
    }

}

?>

Model:
<?php

class Model {

    private static $pdo = null;
    private static $id = null;

    public function __construct() {

        if (is_null(self::$pdo)) {
            $p = $this->getConfig();
            $params = $p['database'];
            $host = $params['host'];
            $db = $params['database'];
            $username = $params['user'];
            $password = $params['password'];
            try {
                $pdo = new PDO("mysql:dbname=$db;host=$host", $username, $password);
            } catch (Exception $e) {
                die('Could not connect to the DB' . $e->getMessage());
            }
            self::$pdo = $pdo;
        }
    }

    private function getConfig() {
        $ini = parse_ini_file(ROOT . DS . 'config.ini', true);
        return $ini;
    }

    protected function select($sql, $params = null, $ftechmethod = PDO::FETCH_OBJ) {
        try {
            $stmt = self::$pdo->prepare($sql);
            if (!is_null($params)) {
                foreach ($params as $key => $param) {
                    $stmt->bindParam($key, $param['value'], $param['type']);
                }
            }
            $stmt->execute();
            return $stmt->fetchAll($ftechmethod);
        } catch (PDOException $e) {
            die('Fail while selecting' . $e->getMessage());
        }
    }

    protected function insert($sql, $params) {
        try {
            $stmt = self::$pdo->prepare($sql);
            foreach ($params as $key => $param) {
                $stmt->bindParam($key, $param['value'], $param['type']);
            }
            $res = $stmt->execute();
            if ($res) {
                $this->id = self::$pdo->lastInsertId();
                $this->err = null;
            } else {
                $this->id = null;
                $this->err = $stmt->errorinfo();
            }
            return $res;
        } catch (PDOException $exception) {
            return false;
        }
    }

    public function getLastId() {
        return $this->id;
    }

}

?>

Vue:
<?php

class View {

    public $allvars = array();

    public function addvar($name, $value) {
        $this->allvars[$name] = $value;
    }

    public function display($pagetitle, $dirname, $viewname, $connected = true) {
        extract($this->allvars);
        echo '<html>';
        include(VIEWS . DS . 'header.php');
        echo '<body>';
        if ($connected)
            include(VIEWS . DS . 'menu_logged.php');
        else
            include(VIEWS . DS . 'menu_public.php');
        include(VIEWS . DS . strtolower($dirname) . DS . $viewname . '_view.php');
        include(VIEWS . DS . 'footer.php');
        echo '</body>';
        echo '</html>';
    }

}

?>

Comme controlleur j'ai par exemple le controlleur de la voiture:
<?php

class CarController extends Controller {

    private $modelCar;

    public function __construct() {
        parent::__construct();
    }

    function index() {
        $this->listAll();
    }

    function listAll() {
        if (!$this->session->isLogged())
            $this->redirect('user', 'login');

        $modelCar = $this->loadModel('Car');
        $allCars = $modelCar->getAll();
        $theview = new View();
        $theview->addvar('allcars', $allCars);
        $theview->display('List of cars', 'car', 'listAll');
    }

    function add() {
        $theview = new View();
        $theview->display('Add a car', 'car', 'add');
    }

    function doAdd() {
        $Model = '';
        $Brand = '';
        $modelCar = $this->loadModel('Car');
        $modelCar->add($Model, $Brand);
        $this->redirect('car', 'listAll');
    }

    function edit() {
        
    }

    function delete() {
        
    }

}

?>

Le modèle n'est pas très intéressant, il n'y a que les SELECT de base et pour les INSERT j'utilise par exemple:
$querry = 'INSERT INTO `car` (Brand, Model) VALUES (:p_brand,:p_model)';
$params = array(
   ':p_brand' => array('value' => $brand, 'type' => PDO::PARAM_STR),
   ':p_model' => array('value' => $model, 'type' => PDO::PARAM_STR)
);
return($this->insert($querry, $params));

Enfin une des vues tels que la vue de toutes les voitures:
<div class="container">
    <h1><?= $pagetitle; ?></h1>
    <div class="row">
        <a class="btn btn-primary" href="<?php echo URL_ROOT; ?>/car/add" role="button">Add a car</a>
    </div>
    <br/>
    <div class="row">
        <?php if (isset($allCars)) { ?>

            <h3>Départments: <?php if (isset($allCars)) echo count($allCars); ?></h3>
            <table class="table table-sm">
                <thead>
                    <tr>
                        <th scope="col">#</th>
                        <th scope="col">Nom</th>
                        <th scope="col">Groupe</th>
                    </tr>
                </thead>
                <tbody>
                    <?php foreach ($allCars as $car) { ?>
                        <tr>
                            <td><?php if (isset($car->CarID)) echo $car->CarID; ?></td>
                            <td><?php if (isset($car->Brand)) echo $car->Brand; ?></td>
                            <td><?php if (isset($car->Model)) echo $car->Model; ?></td>
                        </tr>
                    <?php } ?>
                </tbody>
            </table>
        <?php } else {
            echo 'No car.';
        } ?>
    </div>
</div>
Qu'en pensez-vous? est-ce propre?

Merci beaucoup!

Avatar du membre
Mammouth du PHP | 1609 Messages

26 avr. 2019, 11:20

Salut, ma fois, sans avoir épluché chaque ligne de code, ça me paraît pas mal.
Un bémol sur la class de vue qui injecte les balises html et body depuis le php, ça je trouve que c'est moche.
A la place je mettrais en place un système de layout afin que tout le html soit dans des fichiers de vue.
Développeur web depuis + de 20 ans