如何检查文件夹中是否存在 一个类 再次从另一个文件夹中加载此类?
我有这个文件夹结构,例如,
index.php
code/
local/
我在code/
和local/
来自本地/
class Article
{
public function getArticle()
{
echo 'class from local';
}
}
来自核心,
class Article
{
public function getArticle()
{
echo 'class from core';
}
}
所以我需要一个脚本,可以检测local/
中的文章类 - 如果它已经退出该文件夹而不是从核心/再次加载该类文件夹。可能吗?
这是index.php
中用于加载类的自动加载功能
define ('WEBSITE_DOCROOT', str_replace('\\', '/', dirname(__FILE__)).'/');
function autoloadMultipleDirectory($class_name)
{
// List all the class directories in the array.
$main_directories = array(
'core/',
'local/'
);
// Set other vars and arrays.
$sub_directories = array();
// When you use namespace in a class, you get something like this when you auto load that class \foo\tidy.
// So use explode to split the string and then get the last item in the exloded array.
$parts = explode('\\', $class_name);
// Set the class file name.
$file_name = end($parts).'.php';
// List any sub dirs in the main dirs above and store them in an array.
foreach($main_directories as $path_directory)
{
$iterator = new RecursiveIteratorIterator
(
new RecursiveDirectoryIterator(WEBSITE_DOCROOT.$path_directory), // Must use absolute path to get the files when ajax is used.
RecursiveIteratorIterator::SELF_FIRST
);
foreach ($iterator as $fileObject)
{
if ($fileObject->isDir())
{
// Replace any backslash to '/'.
$pathnameReplace = str_replace('\\', '/', $fileObject->getPathname());
//print_r($pathnameReplace);
// Explode the folder path.
$array = explode("/",$pathnameReplace);
// Get the actual folder.
$folder = end($array);
//print_r($folder);
// Stop proccessing if the folder is a dot or double dots.
if($folder === '.' || $folder === '..') {continue;}
//var_dump($fileObject->getPathname());
// Must trim off the WEBSITE_DOCROOT.
$sub_directories[] = preg_replace('~.*?(?=core|local)~i', '', str_replace('\\', '/', $fileObject->getPathname())) .'/';
}
}
}
// Mearge the main dirs with any sub dirs in them.
$merged_directories = array_merge($main_directories,$sub_directories);
// Loop the merge array and include the classes in them.
foreach($merged_directories as $path_directory)
{
if(file_exists(WEBSITE_DOCROOT.$path_directory.$file_name))
{
// There is no need to use include/require_once. Autoload is a fallback when the system can't find the class you are instantiating.
// If you've already included it once via an autoload then the system knows about it and won't run your autoload method again anyway.
// So, just use the regular include/require - they are faster.
include WEBSITE_DOCROOT.$path_directory.$file_name;
}
}
}
// Register all the classes.
spl_autoload_register('autoloadMultipleDirectory');
$article = new Article();
echo $article->getArticle();
当然我收到了这个错误,
Fatal error: Cannot redeclare class Article in C:\wamp\...\local\Article.php on line 3
class_exists似乎是我应该研究的答案,但我如何将其与上述函数一起使用,特别是与spl_autoload_register
。或者,如果你有更好的想法?
答案 0 :(得分:2)
好的,我误解了你的问题。这应该可以解决问题。
<?php
function __autoload($class_name) {
static $core = WEBSITE_DOCROOT . DIRECTORY_SEPARATOR . "core";
static $local = WEBSITE_DOCROOT . DIRECTORY_SEPARATOR . "local";
$file_name = strtr($class_name, "\\", DIRECTORY_SEPARATOR):
$file_local = "{$local}{$file_name}.php";
require is_file($file_local) ? $file_local : "{$core}{$file_name}.php";
}
使用命名空间可以轻松解决这个问题。
您的核心文件转到/Core/Article.php
:
namespace Core;
class Article {}
您的本地文件转到/Local/Article.php
:
namespace Local;
class Article {}
然后使用一个非常简单的自动加载器,例如:
function __autoload($class_name) {
$file_name = strtr($class_name, "\\", DIRECTORY_SEPARATOR);
require "/var/www{$file_name}.php";
}
PHP按需加载您的类,不需要预先加载文件!
如果您想使用文章,请执行以下操作:
<?php
$coreArticle = new \Core\Article();
$localArticle = new \Local\Article();