Newer
Older
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
<?php
/**
*
*
* @author Taddeus Kroes
* @version 1.0
* @date 13-07-2012
*/
namespace Minimalistic;
require_once 'base.php';
/**
* Object that to automatically load classes within a root directory.
*
* An Autoloader instance can register itself to the SPL autoload stack.
*
* @package Minimalistic
*/
class Autoloader extends Base {
/**
* The root directory to look in.
*
* @var string
*/
private $root_directory;
/**
* The namespace classes in the root directory are expected to be in.
*
* This namespace is removed from loaded class names.
*
* @var string
* @todo implement this
*/
private $root_namespace = '';
/**
* Whether to throw an exception when a class file does not exist.
*
* @var bool
*/
private $throw_errors;
/**
* Create a new Autoloader instance.
*
* @param string $directory Root directory of the autoloader.
* @param bool $throw Whether to throw an exception when a class file does not exist.
*/
function __construct($directory, $throw=true) {
$this->set_root_directory($directory);
$this->set_throw_errors($throw);
}
/**
* Set whether to throw an exception when a class file does not exist.
*
* @param bool $throw Whether to throw exceptions.
*/
function set_throw_errors($throw) {
$this->throw_errors = !!$throw;
}
/**
* Whether an exception is thrown when a class file does not exist.
*
* @returns bool
*/
function get_throw_errors() {
return $this->throw_errors;
}
/**
* Set the root directory from which classes are loaded.
*
* @param string $directory The new root directory.
*/
function set_root_directory($directory) {
$this->root_directory = self::path_with_slash($directory);
}
/**
* Get the root directory from which classes are loaded.
*
* @returns string
*/
function get_root_directory() {
return $this->root_directory;
}
/**
* Append a slash ('/') to the given directory name, if it is not already there.
*
* @param string $directory The directory to append a slash to.
* @returns string
*/
static function path_with_slash($directory) {
return $directory[strlen($directory) - 1] == '/' ? $directory : $directory.'/';
}
/**
* Convert a class name to a file name.
*
* Uppercase letters are converted to lowercase and prepended
* by an underscore ('_').
*
* @param string $classname The class name to convert.
* @returns string
*/
static function classname_to_filename($classname) {
return strtolower(preg_replace('/(?<=.)([A-Z])/', '_\\1', $classname));
}
/**
* Create the path to a class file.
*
* Any namespace prepended to the class name is split on '\', the
* namespace levels are used to indicate directory names.
*
* @param string $classname The name of the class to create the file path of.
*/
function create_path($classname) {
$namespaces = array_filter(explode('\\', $classname));
$dirs = array_map('self::classname_to_filename', $namespaces);
$path = $this->root_directory;
if( count($dirs) > 1 )
$path .= implode('/', array_slice($dirs, 0, count($dirs) - 1)).'/';
$path .= end($dirs).'.php';
return strtolower($path);
}
/**
* Load a class.
*
* Any namespace prepended to the class name is split on '\', the
* namespace levels are used to indicate directory names.
*
* @param string $classname The name of the class to load, including pepended namespace.
* @param bool $throw Whether to throw an exception if the class file does not exist.
* @returns bool
* @throws FileNotFoundError If the class file does not exist.
*/
function load_class($classname, $throw=true) {
$path = $this->create_path($classname);
if( !file_exists($path) ) {
if( !$throw || !$this->throw_errors )
return false;
throw new FileNotFoundError($path);
}
require_once $path;
return true;
}
/**
* Register the autoloader object to the SPL autoload stack.
*
* @param bool $prepend Whether to prepend the autoloader function to
* the stack, instead of appending it.
*/
function register($prepend=false) {
spl_autoload_register(array($this, 'load_class'), true, $prepend);
}
}
?>