PHP 自动加载器 class 从两个或三个不同的路径加载文件
PHP autoloader class to load files from two or three different path
我正在学习使用 php autuoloader
...
据我了解,我们可以使用 __autoloader
或 spl_autoloader_*
来自动加载文件。
假设这是我的目录结构:
ROOT
|
|
ADMIN
| |
| |
| DIST
| |
| SOME_FOLDER
| SOME_FOLDER
| TPL
| |
| |
| SOME_FOLDER1
| |
| test.php
| SOME_FOLDER2
| |
| example1.php
| example2.php
| example3.php
|
|
CLASSES
|
basics.php
class1.php
class2.php
class3.php
class4.php
|
index.php
我为 CLASSES
目录中的自动加载文件做了这个 class :
basics.php :
class MyAutoLoader
{
public function __construct()
{
spl_autoload_register( array($this, 'load') );
}
function load( $file )
{
//spl_autoload( 'load1' );
echo 'Try to call ' . $file . '.php inside ' . __METHOD__ . '<br>';
require( $file . '.php' );
}
}
并且在 index.php
中我将包括 basics.php
一切都很好,因为文件存储在 CLASSES
文件夹中...
require_once("CLASSES/basics.php");
$loaderObject = new MyAutoLoader();
使用此代码,我可以声明 class1
...
class3
现在我想要一个可以在 SOME_FOLDER2
中加载文件的自动加载器,在这种情况下是 example1.php
, example2.php
和 example3.php
我尝试了一些情况,但 SOME_FOLDER2
中的文件不会使用自动加载器加载。
我的尝试:
我在 MyAutoLoader
class 中创建了一个名为 load2
的函数,它试图包含来自 SOME_FOLDER2
的文件
function load2( $file )
{
//spl_autoload_register('load2');
echo 'Inside LOADER2 ' . __METHOD__ . '<br>';
require ( 'ADMIN/TPL/' . $file . '.php' );
}
我在 MyAutoLoader
构造函数中更改了 spl_autoload_register
:
$allMethods = get_class_methods( 'MyAutoLoader' );
$allMethods = array_splice( $allMethods, 1 );
foreach( $allMethods as $method )
{
spl_autoload_register( array($this, $method) );
}
但是 none 对我不起作用...
你能告诉我我的代码有什么问题或者我对 auloader 有什么误解吗?
Thanks in Advance
我认为你的问题基本上归结为在 require
之前没有检查文件是否存在...如果你尝试的第一个文件夹中不存在该文件,这将产生致命错误包括来自。
我不知道你的用例,但这里有一些建议:
你能只使用一个自动加载器吗?
function my_autoload($class_name) {
if (is_file('CLASSES/' . $class_name . '.php')) {
require_once 'CLASSES/' . $class_name . '.php';
} else if (is_file('ADMIN/TPL/SOME_FOLDER2/' . $class_name . '.php')) {
require_once 'ADMIN/TPL/SOME_FOLDER2/' . $class_name . '.php';
}
}
spl_autoload_register("my_autoload");
或者如果您需要独立声明它们(即两个或多个自动加载器):
function classes_autoload($class_name) {
if (is_file('CLASSES/' . $class_name . '.php')) {
require_once 'CLASSES/' . $class_name . '.php';
}
}
spl_autoload_register("classes_autoload");
function admin_autoload($class_name) {
if (is_file('ADMIN/TPL/SOME_FOLDER2/' . $class_name . '.php')) {
require_once 'ADMIN/TPL/SOME_FOLDER2/' . $class_name . '.php';
}
}
spl_autoload_register("admin_autoload");
或者使您的自动加载器 class 通用:
class MyAutoLoader {
private $path;
public function __construct($path) {
$this->path = $path;
spl_autoload_register( array($this, 'load') );
}
function load( $file ) {
if (is_file($this->path . '/' . $file . '.php')) {
require_once( $this->path . '/' . $file . '.php' );
}
}
}
$autoloader_classes = new MyAutoLoader('CLASSES');
$autoloader_admin = new MyAutoLoader('ADMIN/TPL/SOME_FOLDER2');
如果您不想手动更新 ADMIN/TPL
中的子文件夹列表,您甚至可以执行类似这样的操作以从其中任何一个自动加载(这显然假设 ADMIN/TPL
包含 classes):
function my_autoload($class_name) {
if (is_file('CLASSES/' . $class_name . '.php')) {
require_once 'CLASSES/' . $class_name . '.php';
} else {
$matching_files = glob('ADMIN/TPL/*/' . $class_name . '.php');
if (count($matching_files) === 1) {
require_once $matching_files[0];
} else if (count($matching_files) === 0) {
trigger_error('Could not find class ' . $class_name . '!', E_USER_ERROR);
} else {
trigger_error('More than one possible match found for class ' . $class_name . '!', E_USER_ERROR);
}
}
}
spl_autoload_register("my_autoload");
你的问题其实可能就这么简单:
您的 basics.php
位于文件夹 CLASSES
中,因此当您 include
或 require
文件来自 basics.php
时,它会在该文件夹中启动。
因此,如果您想包含来自 ADMIN/TPL/SOME_FOLDER2
的文件,您实际上需要先 "jump" 上一级,即 require '../ADMIN/TPL/SOME_FOLDER2/' . $file . '.php';
为了避免这种混淆,我建议在 index.php
的开头添加一个常量,如下所示:
define('BASEPATH', __DIR__);
...然后将其添加到所有 require
和 include
语句之前 - 即:
class MyAutoLoader {
public function __construct() {
spl_autoload_register( array($this, 'load') );
spl_autoload_register( array($this, 'load2') );
}
function load( $file ) {
echo 'Try to call ' . $file . '.php inside ' . __METHOD__ . '<br>';
$classfile = BASEPATH . '/CLASSES/' . $file . '.php';
if ( is_file( $classfile ) ) {
require( $classfile );
}
}
function load2( $file ) {
echo 'Try to call ' . $file . '.php inside ' . __METHOD__ . '<br>';
$classfile = BASEPATH . '/ADMIN/TPL/SOME_FOLDER2/' . $file . '.php';
if ( is_file( $classfile ) ) {
require( $classfile );
}
}
}
我正在学习使用 php autuoloader
...
据我了解,我们可以使用 __autoloader
或 spl_autoloader_*
来自动加载文件。
假设这是我的目录结构:
ROOT
|
|
ADMIN
| |
| |
| DIST
| |
| SOME_FOLDER
| SOME_FOLDER
| TPL
| |
| |
| SOME_FOLDER1
| |
| test.php
| SOME_FOLDER2
| |
| example1.php
| example2.php
| example3.php
|
|
CLASSES
|
basics.php
class1.php
class2.php
class3.php
class4.php
|
index.php
我为 CLASSES
目录中的自动加载文件做了这个 class :
basics.php :
class MyAutoLoader
{
public function __construct()
{
spl_autoload_register( array($this, 'load') );
}
function load( $file )
{
//spl_autoload( 'load1' );
echo 'Try to call ' . $file . '.php inside ' . __METHOD__ . '<br>';
require( $file . '.php' );
}
}
并且在 index.php
中我将包括 basics.php
一切都很好,因为文件存储在 CLASSES
文件夹中...
require_once("CLASSES/basics.php");
$loaderObject = new MyAutoLoader();
使用此代码,我可以声明 class1
...
class3
现在我想要一个可以在 SOME_FOLDER2
中加载文件的自动加载器,在这种情况下是 example1.php
, example2.php
和 example3.php
我尝试了一些情况,但 SOME_FOLDER2
中的文件不会使用自动加载器加载。
我的尝试:
我在 MyAutoLoader
class 中创建了一个名为 load2
的函数,它试图包含来自 SOME_FOLDER2
function load2( $file )
{
//spl_autoload_register('load2');
echo 'Inside LOADER2 ' . __METHOD__ . '<br>';
require ( 'ADMIN/TPL/' . $file . '.php' );
}
我在 MyAutoLoader
构造函数中更改了 spl_autoload_register
:
$allMethods = get_class_methods( 'MyAutoLoader' );
$allMethods = array_splice( $allMethods, 1 );
foreach( $allMethods as $method )
{
spl_autoload_register( array($this, $method) );
}
但是 none 对我不起作用...
你能告诉我我的代码有什么问题或者我对 auloader 有什么误解吗?
Thanks in Advance
我认为你的问题基本上归结为在 require
之前没有检查文件是否存在...如果你尝试的第一个文件夹中不存在该文件,这将产生致命错误包括来自。
我不知道你的用例,但这里有一些建议:
你能只使用一个自动加载器吗?
function my_autoload($class_name) {
if (is_file('CLASSES/' . $class_name . '.php')) {
require_once 'CLASSES/' . $class_name . '.php';
} else if (is_file('ADMIN/TPL/SOME_FOLDER2/' . $class_name . '.php')) {
require_once 'ADMIN/TPL/SOME_FOLDER2/' . $class_name . '.php';
}
}
spl_autoload_register("my_autoload");
或者如果您需要独立声明它们(即两个或多个自动加载器):
function classes_autoload($class_name) {
if (is_file('CLASSES/' . $class_name . '.php')) {
require_once 'CLASSES/' . $class_name . '.php';
}
}
spl_autoload_register("classes_autoload");
function admin_autoload($class_name) {
if (is_file('ADMIN/TPL/SOME_FOLDER2/' . $class_name . '.php')) {
require_once 'ADMIN/TPL/SOME_FOLDER2/' . $class_name . '.php';
}
}
spl_autoload_register("admin_autoload");
或者使您的自动加载器 class 通用:
class MyAutoLoader {
private $path;
public function __construct($path) {
$this->path = $path;
spl_autoload_register( array($this, 'load') );
}
function load( $file ) {
if (is_file($this->path . '/' . $file . '.php')) {
require_once( $this->path . '/' . $file . '.php' );
}
}
}
$autoloader_classes = new MyAutoLoader('CLASSES');
$autoloader_admin = new MyAutoLoader('ADMIN/TPL/SOME_FOLDER2');
如果您不想手动更新 ADMIN/TPL
中的子文件夹列表,您甚至可以执行类似这样的操作以从其中任何一个自动加载(这显然假设 ADMIN/TPL
包含 classes):
function my_autoload($class_name) {
if (is_file('CLASSES/' . $class_name . '.php')) {
require_once 'CLASSES/' . $class_name . '.php';
} else {
$matching_files = glob('ADMIN/TPL/*/' . $class_name . '.php');
if (count($matching_files) === 1) {
require_once $matching_files[0];
} else if (count($matching_files) === 0) {
trigger_error('Could not find class ' . $class_name . '!', E_USER_ERROR);
} else {
trigger_error('More than one possible match found for class ' . $class_name . '!', E_USER_ERROR);
}
}
}
spl_autoload_register("my_autoload");
你的问题其实可能就这么简单:
您的 basics.php
位于文件夹 CLASSES
中,因此当您 include
或 require
文件来自 basics.php
时,它会在该文件夹中启动。
因此,如果您想包含来自 ADMIN/TPL/SOME_FOLDER2
的文件,您实际上需要先 "jump" 上一级,即 require '../ADMIN/TPL/SOME_FOLDER2/' . $file . '.php';
为了避免这种混淆,我建议在 index.php
的开头添加一个常量,如下所示:
define('BASEPATH', __DIR__);
...然后将其添加到所有 require
和 include
语句之前 - 即:
class MyAutoLoader {
public function __construct() {
spl_autoload_register( array($this, 'load') );
spl_autoload_register( array($this, 'load2') );
}
function load( $file ) {
echo 'Try to call ' . $file . '.php inside ' . __METHOD__ . '<br>';
$classfile = BASEPATH . '/CLASSES/' . $file . '.php';
if ( is_file( $classfile ) ) {
require( $classfile );
}
}
function load2( $file ) {
echo 'Try to call ' . $file . '.php inside ' . __METHOD__ . '<br>';
$classfile = BASEPATH . '/ADMIN/TPL/SOME_FOLDER2/' . $file . '.php';
if ( is_file( $classfile ) ) {
require( $classfile );
}
}
}