+

Создаем свой PHP MVC framework. Часть 2.

Заметки, Программирование, Руководства

Метки (теги) : , ,

Автор: masdeft

В предыдущей статье я описал какая будет структура приложения, привел пример файла конфигураций main.php, который в дальнейшем может разрастаться до большого количества значений на Ваше усмотрение, а также реализацию входного скрипта index.php и файла Application.php. Давайте разберемся с классом Mof_Application.

Входной скрипт index.php создает экземпляр класса Mof_Application с помощью метода инстанции init(), атрибутом которого является значение пути к файлу config/main.php, и вызывает метод run(). Как мы знаем, при создании экземпляра класса срабатывает метод конструктор __construct() который в свою очередь вызывает метод  и тем самым регистрирует наш метод _load() как автозагрузчик классов, т.е. вызывается при обращении к классу, который не видно интерпретатором. Атрибутом метода _load() является имя класса к которому мы обращаемся,  и поэтому нашей задачей является подключить нужный нам класс любой ценой.
Как я уже говорил ранее, в нашем приложении все классы будут именоваться по соглашению , а это значит что имя класса будет подразумевать  путь к нему. Еще раз посмотрим на метод _load().

        private function _load($className)
        {     
                $length = strpos($className, '_');
                $classNameItems = explode('_', $className);
                $lowerFirstItem = strtolower($classNameItems[0]);
                if (isset(self::$_classMap[$classNameItems[0]])) {
                        $classCoreDir = APPLICATION_PATH . DIRECTORY_SEPARATOR . self::$_classMap[$classNameItems[0]];                                         
                } elseif (isset(self::$_classMap['modules'][$classNameItems[0]])) {
                        $classCoreDir = APPLICATION_PATH . DIRECTORY_SEPARATOR . 'modules'
                                                         . DIRECTORY_SEPARATOR . self::$_classMap['modules'][$classNameItems[0]]
                                                         . DIRECTORY_SEPARATOR . Mof_Application::$_classMap[$classNameItems[1]];
                        $className = str_replace($classNameItems[1] . '_', '', $className);                     
                } else {               
                        $classCoreDir = dirname(__FILE__);                                                
                }                     
                $classFile = $classCoreDir . strtr(substr($className, $length), '_', DIRECTORY_SEPARATOR) . '.php';              
                if (is_file($classFile)) {                         
                        require_once $classFile;                         
                }                                             
        }

Сперва мы проверяем первый элемент массива, состоящий и элементов имени класса разделенными символом ‘_’, не является ли он ключом массива $_classMap[]. Если же условие ложно, то проверяем массив $_classMap['modules'] который мы создали
в методе run(). Когда условие истино, переменной $classCoreDir мы присваиваем путь к директории в которой расположен наш класс(но возможно не в корне), и после чего остается совсем за малым, а именно в соответствии с именем класса подключить файл содержащий данный класс. Постарайтесь внимательно разобрать метод _load() и понять каким образом наше приложение будет подключать файлы.
Вернемся к методу run(). Первое что мы делаем – это проверяем наличие указанных модулей в наших конфигурациях, и если таковы есть, то добавляем в массив $_classMap ключ ‘modules’, значение которого будет массив имен модулей. Как Вы видите дальше мы создаем экземпляры следующих классов Mof_Template, Mof_Model и Mof_Router. Постарайтесь разобраться сами для чего это нужно из приведенного ниже кода этих классов.

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
#library/Mof/Template.php

class Mof_Template
{
        /**
         * @var array
         */
        private $_vars = array();
 
        /**            
         * @var string
         */
        private $_layout;
 
        public function __set($index, $value)
        {
                $this->_vars[$index] = $value;
        }
 
        /**
         * Render a view with layout
         * 
         * @param string $viewName
         * @param string $controllerName
         * @throws Exception
         * @return void
         */
        public function render($viewName, $controllerName)
        {             
                $layout = APPLICATION_PATH . DIRECTORY_SEPARATOR . 'views' . DIRECTORY_SEPARATOR . 'layouts' 
                                . DIRECTORY_SEPARATOR . $this->_layout . '.php';                  
                if (!file_exists($layout)) {
                        throw new Exception('Layout ' . $this->_layout . ' not found.');
                }             
                $view = APPLICATION_PATH . DIRECTORY_SEPARATOR . 'views' . DIRECTORY_SEPARATOR 
                                . $controllerName . DIRECTORY_SEPARATOR . $viewName . '.php';
                if (!file_exists($view)) {
                        throw new Exception('View ' . $viewName . ' not found.');
                }             
                foreach ($this->_vars as $key => $value) {
                        $$key = $value;
                }             
                ob_start();         
                include $view;
                $content = ob_get_contents();
                ob_end_clean();             
                include $layout;         
        }     
 
        /**    
         * layout setter
         * 
         * @param string $layoutName
         * @return void
         */
        public function setLayout($layoutName)
        {
                $this->_layout = $layoutName;
        }
}
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#library/Mof/Router.php

class Mof_Router
{
        /**    
         * @var string
         */
        private $_path;
 
        /**    
         * @var string
         */
        private $_controller;
 
        /**    
         * @var string
         */
        private $_action;
 
        /**    
         * @var string
         */
        private $_module;
 
        /**
         * @var array
         */
        private static $_params = array();
 
        public function __construct()
        {
                $request = '';
                if (isset($_GET['request'])) {
                        $request = $_GET['request'];
                }
                $split = explode('/',trim($request,'/'));         
                if ($split) {
                        foreach ($split as $index => $part) {
                                if (!$index && isset(Mof_Config::get()->modules->$part)) {
                                        $this->_module = $part;
                                } elseif (!$this->_controller) {
                                        $this->_controller = ucfirst($part);                                 
                                } elseif (!$this->_action) {
                                        $this->_action = $part;                     
                                } else {                                       
                                        if (!self::$_params || end(self::$_params) !== null) {
                                                self::$_params[$part] = null;                                                                                                                                
                                        } else {
                                                self::$_params[end(array_keys(self::$_params))] = $part;
                                        }                                     
                                }                             
                        }                     
                }
                if (!$this->_controller) {
                        $this->_controller = Mof_Config::get()->defaultController;
                }     
                if (!$this->_action) {
                        $this->_action = 'index';
                }     
        }     
 
        /**
         * Get array of params
         * 
         * @return array
         */
        public static function getParams()
        {
                return self::$_params;
        }
 
        /**    
         * Router
         * 
         * @param Mof_Application $registry
         */
        public function route(Mof_Application $registry)
        {             
                if (!$this->_module) {
                        $file = APPLICATION_PATH . DIRECTORY_SEPARATOR . 'controllers'
                                        . DIRECTORY_SEPARATOR . $this->_controller . 'Controller.php';
                } else {                       
                        $file = APPLICATION_PATH . DIRECTORY_SEPARATOR . 'modules' 
                                        . DIRECTORY_SEPARATOR . $this->_module 
                                        . DIRECTORY_SEPARATOR . 'controllers' 
                                        . DIRECTORY_SEPARATOR . $this->_controller . 'Controller.php';
                }             
                if (is_file($file)) {
                        include $file;
                        $class = $this->_controller . 'Controller';
                } else {
                        include APPLICATION_PATH . DIRECTORY_SEPARATOR . 'controllers' 
                                        . DIRECTORY_SEPARATOR . 'ErrorController.php';
                        $class = 'ErrorController';
                }
                $controller = new $class($registry);         
                if (is_callable(array($controller, $this->_action . 'Action'))) {
                        $action = $this->_action . 'Action';
                } else {
                        $action = 'indexAction';
                }
                $controller->$action();
        }
 
}
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#library/Mof/Model.php

class Mof_Model extends Mof_IModel
{     
        const NO_ERROR = 0;
        const ERROR_CONNECT = 1;
 
        /**
         * @var PDO
         */
        private $_db; 
 
        /**    
         * @var boolean
         */
        private $_error;
 
        /**    
         * @var string
         */
        private $_errorMessage;
 
        protected $_vars = array();
 
        /**
         * Set db connection
         * call __construct()
         */
        public function __construct() 
        {
                try {
                        $this->_db = new PDO(
                                'mysql:host=' . Mof_Config::get()->db->dsn. ';dbname=' . Mof_Config::get()->db->database, 
                                Mof_Config::get()->db->username, 
                                Mof_Config::get()->db->password
                        );
                } catch (Exception $e) {                     
                        $this->_error = self::ERROR_CONNECT;
                        $this->_errorMessage = $e->getMessage();                     
                }     
        }
 
        public function __set($index, $value)
        {
                $this->_vars[$index] = $value;
        }
 
        public function __get($index)
        {
                return $this->_vars[$index];
        }
 
        /**   
         * Get error status
         * 
         * @return boolean
         */
        public function getError()
        {
                return $this->_error;
        }
 
        public function getErrorMessage()
        {
                return $this->_errorMessage;
        }
 
        /**   
         * Set query
         * 
         * @return string
         */
        protected function setQuery()
        {
                $query = $this->query;
                $this->query = '';
 
                return $this->db->query($query);
        }
 
        /**
         * Execute query
         * 
         * @return string
         */
        protected function execQuery()
        {
                return $this->db->exec($this->query);
        }
 
        /**
         * Prepare
         * 
         * @return string
         */
        protected function prepare()
        {
                return $this->db->prepare($this->query);
        }
 
        public function attributes(Array $data)
        {
                foreach ($data as $name => $value) {
                        $this->$name = $value;
                }
        }
}

Приведенные классы опишу в следующих статьях, а пока все. Спасибо.

Комментарии:

Оставить комментарий

=