Skip to content

Commit dd8d8cd

Browse files
committed
Автоматическая загрузка классов.
1 parent 7e7252b commit dd8d8cd

File tree

4 files changed

+138
-9
lines changed

4 files changed

+138
-9
lines changed

app/App.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<?php
2-
namespace app;
32

4-
require __DIR__ . '/../vendor/liw/core/Application.php';
3+
namespace app;
54

65
use liw\core\Application;
76

app/Loader.php

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<?php
2+
3+
namespace app;
4+
5+
class Loader
6+
{
7+
/**
8+
* Ассоциативный массив.
9+
* Ключи содержат префикс пространства имён,
10+
* значение — массив базовых директорий для классов в этом пространстве имён.
11+
*
12+
* @var array
13+
*/
14+
protected $prefixToPath = [];
15+
16+
/**
17+
* Регистрируем автозагрузчик
18+
* @return void
19+
*/
20+
public function register()
21+
{
22+
// регистрирует в качестве функции автозагрузчика метод данного класса loadClass
23+
spl_autoload_register([$this, 'loadClass'], true);
24+
}
25+
26+
/**
27+
* Добавляем соответствующие префиксам базовые директории
28+
* @param $prefix
29+
* @param $base_dir
30+
* @param bool|false $prepend
31+
* @return void
32+
*/
33+
public function addNamespace($prefix, $base_dir, $prepend = false)
34+
{
35+
// нормализуем префикс пространства имён
36+
$prefix = trim($prefix, '\\') . '\\';
37+
38+
// нормализуем базовую директорию так, чтобы всегда присутствовал разделитель в конце
39+
$base_dir = rtrim($base_dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
40+
41+
// инициализируем массив префиксов пространства имён
42+
if (isset($this->prefixToPath[$prefix]) === false) {
43+
$this->prefixToPath[$prefix] = array();
44+
}
45+
46+
// сохраняем базовую директорию для префикса пространства имён
47+
if ($prepend) {
48+
array_unshift($this->prefixToPath[$prefix], $base_dir);
49+
} else {
50+
array_push($this->prefixToPath[$prefix], $base_dir);
51+
}
52+
}
53+
54+
/**
55+
* Загружаем файл, соответствющий классу.
56+
* @param $class
57+
* @return bool|string
58+
*/
59+
public function loadClass($class)
60+
{
61+
// начальное значение префикса пусть будет пустой строкой
62+
$prefix = '';
63+
64+
// разобьем название класса на массив строк, используя в качестве разделителя "\"
65+
$arr = explode('\\', $class);
66+
67+
// пока в нашем массиве еще есть элементы, пытаемся найти и загрузить файл
68+
while(count($arr) > 0){
69+
// добавляем в конец префикса первый элемент из массива
70+
$prefix .= array_shift($arr) . '\\';
71+
72+
// пытаемся загрузить файл
73+
$file = $this->loadMappedFile($prefix, $arr);
74+
75+
// если удалось загрузить файл - возвращаем файл
76+
if($file){
77+
return $file;
78+
}
79+
}
80+
81+
// если не нашли класс - возвращаем false
82+
return false;
83+
}
84+
85+
/**
86+
* @param $prefix
87+
* @param $arr
88+
* @return bool|string
89+
*/
90+
protected function loadMappedFile($prefix, $arr)
91+
{
92+
// если в массиве, сопоставляющем префикс и базовую директорию отсутствует текущий префикс
93+
// то возвращаем false
94+
if(isset($this->prefixToPath[$prefix]) === false){
95+
return false;
96+
}
97+
98+
// проходим по всем базовым директориям, соответсвующим текущему префиксу
99+
// и пытаемся загрузить файл
100+
foreach($this->prefixToPath[$prefix] as $base_dir){
101+
$file = $base_dir . implode($arr, DIRECTORY_SEPARATOR) . '.php';
102+
// если нам удается загрузить файл - возвращаем этот файл
103+
if($this->requireFile($file)){
104+
return $file;
105+
}
106+
}
107+
108+
return false;
109+
}
110+
111+
/**
112+
* @param $file
113+
* @return bool
114+
*/
115+
protected function requireFile($file)
116+
{
117+
if(file_exists($file)){
118+
require_once $file;
119+
return true;
120+
}
121+
return false;
122+
}
123+
}

vendor/liw/core/Application.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<?php
2+
23
namespace liw\core;
34

45
/**

web/index.php

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,18 @@
88
error_reporting(E_ALL); // устанавливает уровень отслеживаемых ошибок интерпретатором php
99
ini_set('display_errors', 1); // дает команду интерпретатору php выводить все отслеживаемые ошибки в браузере
1010

11-
// Подключили файл из папки app
12-
require __DIR__ . '/../app/App.php';
11+
// Подключаем файл, где храниться автозагрузчик классов
12+
require __DIR__ . '/../app/Loader.php';
1313

14-
// создали новый объект класса из папки vendor
15-
$app = new app\App();
14+
// создаем экземпляр класса автозагрузчика
15+
$loader = new \app\Loader();
1616

17-
// Попытка создать экземпляр абстрактного класса вызовет ошибку.
18-
// Раскомментируйте строку ниже, чтоб убедиться.
19-
//$app2 = new liw\core\Application();
17+
// добавляем соответствующие нэймспэйсу директории
18+
$loader->addNamespace('app', realpath(__DIR__ . '/../app'));
19+
$loader->addNamespace('liw\\core', realpath(__DIR__ . '/../vendor/liw/core'));
20+
21+
// регистрируем автозагрузчик
22+
$loader->register();
23+
24+
// создали новый объект класса, теперь соответствующий файл загрузится автоматически
25+
$app = new \app\App();

0 commit comments

Comments
 (0)