💻 آخرین فرصت یادگیری برنامه‌نویسی با آفر ویژه قبل از افزایش قیمت در ۱۵ آذر ماه (🎁 به همراه یک هدیه ارزشمند )
۰ ثانیه
۰ دقیقه
۰ ساعت
۲ جبار محمدی
Autoloading بدون namespace!
جامعه پی اچ پی ایجاد شده در ۲۱ خرداد ۱۳۹۹

سلام دوستان و همه دوره ای هایی عزیز 

همونطور که تو آموزش 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  اتولود کنید قطعا این بهترین راه حل نیست ولی خو شاید یه روزی یه جایی به درد یکی خورد. :)

موفق باشید اگه جایی چیزی رو اشتباه گفتم حتما بهم بگید

اینکه بدونی داری اشتباه میکنی ینی برنده ای بازم ولی اگر یه اشتباه رو به عنوان حقیقت باور کنی ...!(در همین حد بلد بودم !!!)

 

 

این نکته رو اضافه کنم که توصیه شده برای  Autoloading از استاندارد PSR-۴  استفاده بشه.

جبار محمدی ۲۱ خرداد ۱۳۹۹، ۲۳:۴۸

سلام آقای محمدی، دم شما گرم

این autoload زمانی فایل‌های ما رو لود میکنه که ما یک کلاس رو new کرده باشیم، یه سوال اگر من بخوام فایلی رو include داشته باشیم که ازش یک شئ نساختم اون موقع باید چیکار کنم؟ (اینم بگم یه پیکج گیر آوردم که این کارو برام میکنه ولی میخوام ببینم با همین تابع هم میشه این کار رو انجام داد؟)

امیر صالحی ۲۲ خرداد ۱۳۹۹، ۰۵:۴۱