ऑटोलॉडिंग क्या है; आप spl_autoload, __autoload और spl_autoload_register का उपयोग कैसे करते हैं?


203

मैं उन्नत PHP मानकों को सीख रहा हूं और नए और उपयोगी तरीकों को लागू करने की कोशिश कर रहा हूं। पहले मैं __autoloadप्रत्येक पृष्ठ पर एकाधिक फ़ाइलों सहित बचने के लिए उपयोग कर रहा था , लेकिन हाल ही में मैंने एक टिप देखी है__autoload manual

spl_autoload_register () ऑटोलॉडिंग कक्षाओं के लिए अधिक लचीला विकल्प प्रदान करता है। इस कारण से, __autoload () का उपयोग करना हतोत्साहित किया जाता है और भविष्य में इसे हटाया या हटाया जा सकता है।

लेकिन मैं वास्तव में यह नहीं पता लगा सकता कि कैसे लागू किया जाए spl_autoloadऔरspl_autoload_register

जवाबों:


334

spl_autoload_register() आपको कई कार्यों (या अपने स्वयं के ऑटोलॉड वर्ग से स्थिर तरीकों) को पंजीकृत करने की अनुमति देता है, जब PHP एक "नया वर्ग" घोषित होने पर एक स्टैक / कतार में डाल देगा और क्रमिक रूप से कॉल करेगा।

उदाहरण के लिए:

spl_autoload_register('myAutoloader');

function myAutoloader($className)
{
    $path = '/path/to/class/';

    include $path.$className.'.php';
}

//-------------------------------------

$myClass = new MyClass();

ऊपर दिए गए उदाहरण में, "MyClass" उस क्लास का नाम है जिसे आप इंस्टेंट करने की कोशिश कर रहे हैं, PHP इस नाम को एक स्ट्रिंग के रूप में पास करता है spl_autoload_register(), जो आपको वेरिएबल को लेने और उपयुक्त क्लास / फाइल को "शामिल" करने के लिए उपयोग करने की अनुमति देता है। । एक परिणाम के रूप में आपको विशेष रूप से उस वर्ग को शामिल करने / कथन की आवश्यकता नहीं है ...

बस उस वर्ग को कॉल करें जिसे आप ऊपर दिए गए उदाहरण की तरह त्वरित करना चाहते हैं, और जब से आपने spl_autoload_register()अपना स्वयं का एक फ़ंक्शन (थ्रू ) पंजीकृत किया है जो यह पता लगाएगा कि आपकी सभी कक्षा कहाँ स्थित है, PHP उस फ़ंक्शन का उपयोग करेगा।

उपयोग करने spl_autoload_register()का लाभ यह है कि इसके विपरीत __autoload()आपको अपने द्वारा बनाई गई प्रत्येक फ़ाइल में एक ऑटोलॉड फ़ंक्शन को लागू करने की आवश्यकता नहीं है। spl_autoload_register()आपको ऑटोलैडिंग को गति देने और इसे और भी आसान बनाने के लिए कई ऑटोलॉड कार्यों को पंजीकृत करने की अनुमति देता है।

उदाहरण:

spl_autoload_register('MyAutoloader::ClassLoader');
spl_autoload_register('MyAutoloader::LibraryLoader');
spl_autoload_register('MyAutoloader::HelperLoader');
spl_autoload_register('MyAutoloader::DatabaseLoader');

class MyAutoloader
{
    public static function ClassLoader($className)
    {
         //your loading logic here
    }


    public static function LibraryLoader($className)
    {
         //your loading logic here
    }

Spl_autoload के संबंध में , मैनुअल बताता है:

यह फ़ंक्शन डिफ़ॉल्ट कार्यान्वयन के रूप में उपयोग करने के लिए लक्षित है __autoload()। यदि कुछ और निर्दिष्ट नहीं है और spl_autoload_register()बिना किसी पैरामीटर के बुलाया जाता है, तो इस फ़ंक्शन का उपयोग किसी भी बाद में कॉल करने के लिए किया जाएगा __autoload()

अधिक व्यावहारिक शब्दों में, यदि आपकी सभी फाइलें एक ही निर्देशिका में स्थित हैं और आपका एप्लिकेशन न केवल .php फाइलों का उपयोग करता है, बल्कि कॉन्फ़िगरेशन की कॉन्फ़िगरेशन फ़ाइलों के साथ। उदाहरण के लिए एक्सटेंशन, तो आपके द्वारा उपयोग की जाने वाली एक रणनीति में आपकी निर्देशिका को शामिल करना होगा। PHP के पथ (के माध्यम से set_include_path()) के लिए फ़ाइलें ।
और चूंकि आपको अपनी कॉन्फ़िगरेशन फ़ाइलों की आवश्यकता होती है, इसलिए आप spl_autoload_extensions()उन एक्सटेंशनों को सूचीबद्ध करने के लिए उपयोग करेंगे जिन्हें आप PHP के लिए देखना चाहते हैं।

उदाहरण:

set_include_path(get_include_path().PATH_SEPARATOR.'path/to/my/directory/');
spl_autoload_extensions('.php, .inc');
spl_autoload_register();

चूँकि spl_autoload __autoload()मैजिक विधि का डिफ़ॉल्ट कार्यान्वयन है , इसलिए जब आप प्रयास करते हैं और एक नए वर्ग को तुरंत भेजते हैं, तो PHP spl_autoload को कॉल करेगा।

उम्मीद है की यह मदद करेगा...


35
यह उत्तर के इतिहास के सबसे अच्छे उत्तरों में से एक हो सकता है। आदर करना। मैं उन लोगों में से एक था "OMG! यह सब अब समझ में आता है!" तुम्हारे कारण, मेरे अच्छे आदमी। मुझे लगता है कि मैं सिर्फ एक फैन क्लब शुरू कर सकता हूं।
बस प्लेन हाई

2
वैकल्पिक ब्रह्मांडों में भी सभी उत्तरों का सबसे अच्छा जवाब देने के लिए, कृपया उस spl_autoload को बहुत जोड़ दें, उम, "सहायक रूप से" (?) सभी फ़ाइल नाम को लोअरकेस में परिवर्तित करता है (नीचे मेरी टिप्पणी @user देखें)। यदि आप अपनी CapitalLettersAndStuff को पसंद करते हैं तो spl_autoload_register () वेनिला का उपयोग नहीं कर सकते।
बस प्लेन हाई

6
@ जस्ट प्लेन हाई मैं वह मुद्दा नहीं है और मेरी सभी क्लास फाइलें ऊँट हैं। BTW, यह एक अद्भुत जवाब है। इसने मुझे एक सरल अवधारणा के आसपास अपना सिर लाने में मदद की जिसे मैं तब तक समझ नहीं पाया जब तक मैं इस पोस्ट को नहीं पढ़ गया! मेरी 85 (और बढ़ती) लाइन में वह फ़ाइल शामिल है जिसमें मेरी सभी श्रेणी की फाइलें अब 7 लाइनें शामिल हैं!
काइल

2
यह वास्तव में एक अच्छा जवाब है लेकिन मुझे एक बात याद आ रही है। वास्तविक डिफ़ॉल्ट कार्यक्षमता क्या है? जिन कक्षाओं को मैं जानता हूं, वे फ़ाइल नाम के रूप में नाम और पथ का उपयोग करते हैं। हालांकि मैं यह पता नहीं लगा सकता कि यह कैसे काम करता है।
SiXoS

2
(और सामान्य रूप से) का उपयोग करने के लिए एक बड़ा लाभ यह नहीं है कि यह आलसी लोड में फ़ाइलें / कक्षाएं शामिल हैं? यह उत्तर द्वारा निहित है, लेकिन स्पष्ट रूप से नहीं कहा गया है। मेरे लिए, यह महत्वपूर्ण जानकारी है जो आपके उत्तर में शामिल करने के लिए एकदम सही होगी! :)spl_autoload_register()__autoload()
rinogo

13

PHP 5.3 के बाद से, आप spl_autoload_register()नेमस्पेस के साथ उपयोग कर सकते हैं , जिसका अर्थ है कि आप अपने प्रोजेक्ट को व्यवस्थित कर सकते हैं और बिना किसी आवश्यकता के या बिना किसी __autoload()फ़ंक्शन को शामिल किए और अपने php क्लासेस को ऑटोलैड कर सकते हैं।

इस व्यवहार को प्रदर्शित करने के लिए, बस index.php नामक एक फाइल बनाएं:

<?php
spl_autoload_register();
var_dump(new Main\Application);

फिर Index.php फ़ाइल के ठीक बगल में स्थित Main नामक एक फ़ोल्डर बनाएँ। अंत में, मुख्य में स्थित Application.php नामक एक फाइल बनाता है और उसमें निम्न कोड पेस्ट करता है:

<?php namespace Main;
class Application{}

9
इस सब के साथ मेरी फीलिंग का एक नोट: spl_autoload () - और इस प्रकार spl_autoload_register () - लोअरकेस में फ़ाइल नाम परिवर्तित करता है (बग रिपोर्ट, दलीलों और उग्र मतदान के बावजूद)। इसका मतलब है कि आप "Main \ Application" ढूंढ रहे होंगे, लेकिन spl_autoload "main \ application" की तलाश में है। यदि आप ऊंट को पसंद करते हैं, जैसे मैं करता हूं, तो आपको अपना फ़ंक्शन लिखना होगा। यहां एक अच्छा स्टार्टर उदाहरण है: github.com/ircmaxell/PHP-CryptLib/blob/…
जस्ट प्लेन हाई

1
पेशेवरों: spl_autoload_register () ऑटोलैडिंग विपक्ष का सबसे तेज़ तरीका है: यह केवल लोअरकेस फ़ाइलों / कक्षाओं के साथ काम करेगा, और नाम स्थान भी होगा, जो इस दिन और उम्र में केवल बड़ा समय sux (कैमलकेस आदि का उपयोग करने के लिए इसे बताने का कोई विकल्प नहीं है)। लेकिन अगर आप नाम स्थान / classname.php संरचना के साथ रह सकते हैं, तो आगे मत देखो।
स्टैमस्टर

1
spl_autoload_register()डिफ़ॉल्ट कार्यान्वयन विरासत में मिली कक्षाओं को खोजने में असमर्थ है। इसलिए डिफॉल्ट्स, लोअरकेस फाइल्स और डायरेक्ट्रीज़ का उपयोग करके नेमस्पेस पथ को दर्शाते हुए, सब कुछ ठीक काम करता है जब तक कि मेरे पास एक क्लास न हो जो दूसरे क्लास (पैरेंट) को बढ़ाता है। PHP तब त्रुटि फेंकता है कि वह उस मूल वर्ग को नहीं खोज सकता है, यहाँ तक कि वे सभी एक ही निर्देशिका / नाम स्थान में हैं! भ्रामक यह है कि शाब्दिक रूप से केवल प्रथम स्तर की कक्षाएं ही पाई जाती हैं, इसलिए मुझे spl_autoload_register()अनाम फ़ंक्शन नियम के साथ एक और बस एक के बाद एक आदेश देना होगा ताकि ओ में मैन्युअल रूप से लापता माता-पिता / विरासत वाली कक्षाएं शामिल हों।
स्ट्रैमस्टर

1

यहाँ मैं Autoload का उपयोग करने का तरीका है। दिए गए उदाहरण में, मैं चाहता हूं कि कक्षाएं 3 अलग-अलग निर्देशिकाओं को लोड करें।

function namespaceAutoload($rawClass){

$class = str_replace('\\', DIRECTORY_SEPARATOR, $rawClass);

$possiblePaths[] = '..\sys\class\file.php';
$possiblePaths[] = '..\sys\class\lib\file.php';
$possiblePaths[] = '..\sys\class\class.file.inc.php';

foreach ($possiblePaths as $templatePath) {
    $path = str_replace(["\\", "file"], [DIRECTORY_SEPARATOR, $class], $templatePath);
    if (file_exists($path)) {
        require_once "$path";
        break;
    }
} spl_autoload_register("namespaceAutoload"); 

मैंने उदाहरण दिया है, PHP इन तीन निर्देशिकाओं में इन तीन अलग-अलग फ़ाइल नाम स्वरूपों का उपयोग करके नाम स्थान \ वर्ग की खोज करेगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.