Autoloading بدون namespace!

پرسیده شده
فعالیت 1421 روز پیش
دیده شده 1233 بار
2

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

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

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

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

 

 

فایل پیوست

جبار محمدی
جبار محمدی

21 خرداد 99

1
حذف شده

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

فایل پیوست

جبار محمدی

توسط

جبار محمدی

21 خرداد 99

0
حذف شده

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

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

فایل پیوست

امیر صالحی

توسط

امیر صالحی

22 خرداد 99

حذف شده
سلام امیر جان.ممنون از شما.دقیقا حق با شماست چون php تا یه کلاس use نشه به هرطریقی تابع spl رو فراخوانی نمیکنه.با این تابع که الان نمیشه این کارو کرد.جواب سوالتون نمیدونم یه حدسایی میزنم که چطوری میشه هندلش کرد!باید تستش کنم اگه به جوابش رسیدی حتما تو انجمن بزارش
جبار محمدی

22 خرداد 99

حذف شده
چشم حتما
امیر صالحی

23 خرداد 99