+

TopPartner: www.BakersfieldCaInstallmentPayday.Loan

Создаем свой 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;
		}
	}
}

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

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

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

=