MVC приложение на php. Часть 2

В этом уроке мы добавим MVC, db layer.

Итак, как мы помним наш bootstrap.php подключил некоторые биб-ки и ядро. В ядре мы не рассмотрели родительские классы M, V, C.

Базовый контроллер  не делает ничего кроме создает объект вьюхи с путем для вьюх (у нас папка client).

application/core/controller.php


namespace Core;

abstract class Controller {
    
    public $model;
    public $view;

    /**
     * @param string $controller_path_folder
     */
    function __construct($controller_path_folder = "")
    {
        $this->view = new View($controller_path_folder);
    }
}

Базовая модель оказалась еще проще.

application/core/model.php


namespace Core;

use Lib\Lib_DateBase;

class Model extends Lib_DateBase
{
    /**
     *
     */
    public function get_data()
    {
    }
}

Базовый класс вьюхи  поинтереснее.

application/core/view.php



namespace Core;

class View
{
    private $view_path_folder;
    private $class;

    /**
     * @param $controller_path_folder
     */
    public function __construct($controller_path_folder){
    // путь вида application/controllers/client заменяется на  application/views/client
        $this->view_path_folder = str_replace("controller", "view", $controller_path_folder);
    }

В конструкторе класса View назначается путь до директории вьюх. Потом допишем метод generate(), который вызовем в контроллере.


<?php 

namespace Client;

use Core\Controller;

class Controller_Articles extends Controller
{
    /**
     *
     */
    function action_index()
    {
        $data = array(
            'breadcrumb' => 'Главная',
        );
        $this->view->generate('main',  $data);
    }

Никаких данных он не получает, т.е. обращения к модели нет. Вызывается метод Вида generate(). Давайте напишем его


    /**
     * @param $content_view
     * @param null $data
     */
    function generate($content_view, $data = null)
    {
        
        if(is_array($data)) {
            extract($data);
        }

        /* ************** базовый шаблон */
        $template_view = 'template.php';
        if($content_view == null || $content_view == ''){
            /* ************ caller для дефолтной вьюхи если не задана */
            $trace = debug_backtrace();
            $caller = $trace[1]['function'];
            $template = str_replace("action_", "", $caller);
            $content_view = strtolower($template).".php";
        }else{
            // вьюха для контента
            $content_view = $content_view.".php";
        }
            $templ = $this->view_path_folder."/".$template_view;
            if(is_file($templ))
        	    include($templ);
            else
                die("template_view $templ not found!!");
    }

В комментариях все описано. Значит подключается базовый шаблон, далее если задана вьюха в параметре оперделяется она, если не задана цепляется по названию экшна. Массив с данными преобразуется в перменные, к-е далее используем в шаблоне.

application/lib/datebase.php


<?php

namespace Lib;

class Lib_DateBase {

    /**
     * @param $query
     * @return mixed
     */
	function query($query)
	{
		// получаем объект mysqli
		$mysqli = Lib_Registry::get('mysqli');
		// если запрос с параметрами
		if(($num_args = func_num_args()) > 1){
			$arg  = func_get_args();
			unset($arg[0]);
			// пробегаемся по параметрам для экранирования кавчек
			foreach($arg as $argument=>$value){
				$arg[$argument]= $mysqli->real_escape_string($value);
			}
			// форматирование запроса
			$query = vsprintf($query,$arg);	
		}
		// выполняем запрос
        $sql = Lib_Registry::get('mysqli')->query($query);
        if(preg_match('`^(INSERT|UPDATE|DELETE|REPLACE)`i',$query,$null)){
			if($sql = $mysqli->affected_rows){
				return $sql;
			}		
		}else{
			if(!$sql)return;
			if($sql->num_rows){
				return $sql;
			}
		}
		return $sql;	
	}

    /**
     * @param $query
     * @param $array
     * @param string $where
     * @param string $_devide
     * @return bool|mixed
     */
	function build_query($query,$array,$where = '', $_devide = ',')
	{
		if(is_array($array)){
			$part_query = '';
			$mysqli = Lib_Registry::get('mysqli');
			foreach($array as $index=>$value){
				$part_query .= sprintf(" %s = '%s'".$_devide,$index,$mysqli->real_escape_string($value));
			}
			$part_query = trim($part_query,$_devide);
			$query.=$part_query." ".$where;
			return $this->query($query);
		}
		return false;
	}

    /**
     * @param $object
     * @return mixed
     */
	function fetch_object($object)
	{
		return $object->fetch_object();
	}

    /**
     * @param $object
     * @return mixed
     */
	function num_rows($object)
	{
		return $object->num_rows;
	}

    /**
     * @param $object
     * @return mixed
     */
	function affected_rows($object)
	{
		return $object->affected_rows;
	}

    /**
     * @return mixed
     */
	function insert_id()
	{
		return Lib_Registry::get('mysqli')->insert_id;
	}
}

Запросы надо экранировать, для этого используется форматирование запроса с параметрами.
Выложил урок на гитхабе. Если вы клонировали 1-й урок (master), то достаточно сделать

git checkout lesson2

Далее ветки будут именоваться lessonX

Leave a comment

Your email address will not be published.


*