سلام دوستان و همه دوره ای هایی عزیز
همونطور که تو آموزش Autoloading دیدیم وقتی بخوایم یه کلاسی که توی دایرکتوری هست انکولد کنیم از namespace استفاده میکردیم که نام کلاس و namespace ش که طبق استاندارد PSR-۴ نام گذاری کرده بودیم (مسیر دایرکتوری کلاس) به تابعی که نوشته بودم پاس داد میشود و ما اون تابع رو به عنوان پارامتر autoload_function به تابع spl_autoload_register پاس میدادیم به این صورت ما یه Autoloader داشتیم.
<?php
//Autoloader
function myAutoLoader($className)
{
$classFile = __DIR__ ."/$className.php";
if(file_exists($classFile) && is_readable($classFile)) {
require_once $classFile;
} else {
die("{$classFile} not found! \n");
}
}
spl_autoload_register('myAutoLoader');
ولی گاهی پیش میاد که ما یه پروژه داریم که میتونیم از namespace استفاده نکنیم ولی ساختار پروژه تقریبا به شکل MVC هست و کلاسا داخل دایرکتوریاشون هستن انوقت چی!(البته این مثال درستی نیست چون تو این ساختار میشه فقط دایرکتوری libraries رو prefix کرد قبل از نام کلاس!)
spl_autoload_register(function ($className) {
require_once APPROOT . '/libraries/' . $className . '.php';
});
قطعا خیلی کارا میشه انجام داد (دشواری نداریم!).
یکی از راه حلها استفاده از یه تابع و لوپِ!
(این کدُ تو یه سایت خارجی دیدم دقیق نمیدونم چه سایتی بود که منبعشو ذکر کنم مدیونش نشم!)
تو php یه تابع داریم به اسم glob()
تابع glob() طبق اسناد سایت php.net یه الگو بهش میدیم اونم برامون نام مسیرها و فایلهای که مطابق با اون الگو هستن و در قالب یه آرایه بهمون میده.(اگرم چیزی پیدا نکنه خروجیش False )
glob ( string $pattern [, int $flags = 0 ] ) : array
این تابع یه سری Special characters و یه سری flags میگیره, که تو دایکومنتش هست و میتونید مطالعه کنید اگه خواستید.
الگو و flag که میخوام به این تابع بدم به این صورته :
glob(__DIR__ . '/*', GLOB_ONLYDIR)
(میدونم که اضافه کاری و همتون میدونید که داره چیکار میکنه ولی خو من میگم بازم ;) )
به عنوان الگو ثابت جادویی __DIR__ و '/*' بهش میدیم که یعنی تو همین دایرکتوری که هستی همه فایلها و دایرکتوریها رو برگردون (آرایه) (که معادل همون app/* میشه تو پروژه ای که دیدیم تو اموزش)
but!
تو قسمت flag ما ازش میخوایم که فایلارو بیخیال شو و فقط دایرکتوریارو بهمون بده (GLOB_ONLYDIR
) بعدش چون یه آرایه برمیگردونه میزارمیش تو یه حلقه foreach و رو آرایه لوپ میزنیم.
اگر تو هر کدوم از دایرکتوریا کلاسی وجود داشت که اسمش مطابق با نام کلاسی بود که میخواد اجرا شه شرط برقرار میشه و فایل اینکلود میشه و ما یه بریک میکنم تمام!
function myAutoLoader($className)
{
foreach (glob(__DIR__ . '/*', GLOB_ONLYDIR) as $dir) {
if (file_exists("$dir/" . $className . '.php')) {
require_once "$dir/" . $className . '.php';
break;
}
}
}
spl_autoload_register('myAutoLoader');
میتونید با این کد بدون نیاز به namespace اتولود کنید قطعا این بهترین راه حل نیست ولی خو شاید یه روزی یه جایی به درد یکی خورد. :)
موفق باشید اگه جایی چیزی رو اشتباه گفتم حتما بهم بگید
اینکه بدونی داری اشتباه میکنی ینی برنده ای بازم ولی اگر یه اشتباه رو به عنوان حقیقت باور کنی ...!(در همین حد بلد بودم !!!)