शुरुआती लोगों के लिए लारवेल ट्यूटोरियल

लारवेल क्या है?

Laravel PHP के लिए एक ओपन-सोर्स वेब MVC फ्रेमवर्क है। Laravel एक मजबूत फ्रेमवर्क है जो एक समर्पित निर्भरता प्रबंधक के साथ एक मॉड्यूलर पैकेजिंग सिस्टम, रिलेशनल डेटाबेस तक पहुंच और एप्लिकेशन परिनियोजन और रखरखाव के लिए अन्य उपयोगिताओं जैसी सुविधाओं के साथ PHP वेब अनुप्रयोगों का आसान विकास प्रदान करता है।

लारवेल को टेलर ओटवेल ने बनाया था। जून 2011 (संस्करण 1) में अपनी प्रारंभिक रिलीज़ के बाद से, यह वेब डेवलपमेंट उद्योग के PHP-फ्रेमवर्क क्षेत्र में लगातार अधिक से अधिक लोकप्रिय होता गया है। इसकी लोकप्रियता का एक बड़ा हिस्सा डेवलपर-प्रथम-दिमाग वाली कई विशेषताओं के कारण है जो स्टॉक के साथ आती हैं।

लारावल क्यों?

लगभग 2000, अधिकांश PHP कोड प्रक्रियात्मक था और इसे “स्क्रिप्ट” के रूप में पाया जा सकता था जिसमें स्पेगेटी कोड का एक उलझा हुआ ढेर होता था। यहां तक ​​कि सबसे सरल पृष्ठों में भी कोई कोड नहीं था चिंताओ का विभाजन, और इस प्रकार किसी एप्लिकेशन के लिए रखरखाव दुःस्वप्न में जल्दी से विकसित होना काफी आसान था। दुनिया को कुछ बेहतर चाहिए था... PHP संस्करण 5 और विभिन्न PHP फ्रेमवर्क में प्रवेश करें जो विभिन्न वेब एप्लिकेशन चिंताओं के लिए कुछ बहुत जरूरी समाधान और बेहतर समाधान लाने का प्रयास करते हैं।

तब से हमने कई ऐसे फ्रेमवर्क जारी होते देखे हैं जो आज मौजूद और इस्तेमाल किए जा रहे लोकप्रिय फ्रेमवर्क के लिए रास्ता तैयार करेंगे। आज, शीर्ष तीन (हमारी राय में) Zend Framework, Symfony और निश्चित रूप से Laravel होंगे। हालाँकि इनमें से प्रत्येक फ्रेमवर्क समान सिद्धांतों पर आधारित था और (मूल रूप से) समान सामान्य समस्याओं को हल करने के लिए तैयार किया गया था, लेकिन उनका मुख्य अंतर उनके कार्यान्वयन में है। समस्याओं को हल करने के तरीके के बारे में उनमें से प्रत्येक की अपनी-अपनी विचित्रताएँ हैं। जब आप उनमें से प्रत्येक द्वारा निर्मित कोड को देखेंगे, तो आप देखेंगे कि उन्हें एक-दूसरे से अलग करने वाली एक बहुत ही ठोस रेखा है। हमारी विनम्र राय में, Laravel फ्रेमवर्क सबसे अच्छा है।

इस बारे में अधिक जानें लारवेल और कोडइग्निटर के बीच अंतर

कंपोजर के साथ लारवेल को कैसे डाउनलोड और इंस्टॉल करें

ध्यान दें यह माना जाता है कि आपके स्थानीय सिस्टम पर PHP की एक प्रति पहले से ही स्थापित है। यदि नहीं, तो आप इसे स्थापित करने का तरीका पढ़ सकते हैं यहाँ उत्पन्न करें

कंपोजर एक पैकेज और निर्भरता प्रबंधक दोनों है। इसे स्थापित करने के लिए, एक टर्मिनल खोलें और एक नई निर्देशिका में cd करें। यह कमांड चलाएँ:

curl -Ss getcomposer.org/installer | php

इस आदेश के परिणाम इस प्रकार दिखेंगे:

कंपोजर के साथ लारवेल डाउनलोड और इंस्टॉल करें

नोट Laravel को स्थापित करने के बारे में अधिक विस्तृत निर्देशों के लिए, Laravel दस्तावेज़ देखें यहाँ उत्पन्न करें.

आप देखेंगे कि यह कंपोजर.फ़ार स्क्रिप्ट को डाउनलोड और संकलित कर रहा है, जिसका उपयोग हम लारवेल को स्थापित करने के लिए करते हैं। हालाँकि एक नया लारवेल एप्लिकेशन सेट अप करने के कई तरीके हैं, हम इसे लारवेल कंपोजर स्क्रिप्ट के माध्यम से करेंगे। इस स्क्रिप्ट को स्थापित करने के लिए, चलाएँ:

composer global require laravel/installer

जो कुछ इस तरह दिखेगा:

कंपोजर के साथ लारवेल डाउनलोड और इंस्टॉल करें

यह सभी फ्रेमवर्क फ़ाइलों को डाउनलोड और इंस्टॉल करेगा और साथ ही सभी निर्भरताएँ भी जिनकी आवश्यकता है। पैकेज विक्रेता निर्देशिका के अंदर सहेजे जाएँगे। एक बार इसे डाउनलोड और इंस्टॉल कर लेने के बाद, यह निम्न कमांड जारी करने जितना आसान है:

laravel new uploadApp

आपको कुछ इस प्रकार का आउटपुट दिखाई देगा:

कंपोजर के साथ लारवेल डाउनलोड और इंस्टॉल करें

कंपोजर उन सभी पैकेजों को इंस्टॉल कर रहा है जिनकी लारवेल को चलने के लिए ज़रूरत है। इसमें कुछ मिनट लग सकते हैं इसलिए धैर्य रखें। इसके पूरा होने के बाद, ls -al कमांड चलाकर देखें कि क्या इंस्टॉल किया गया है।

यहां एक सामान्य लारवेल अनुप्रयोग में निर्देशिकाओं का संक्षिप्त विवरण दिया गया है:

  • अनुप्रयोग/ : यह वह स्रोत फ़ोल्डर है जहाँ हमारा एप्लिकेशन कोड रहता है। सभी नियंत्रक, नीतियाँ और मॉडल इस फ़ोल्डर के अंदर हैं
  • बूटस्ट्रैप/ : एप्लिकेशन की स्टार्टअप स्क्रिप्ट और कुछ क्लास मैप फ़ाइलें रखता है
  • कॉन्फ़िग/ : ऐप की कॉन्फ़िगरेशन फ़ाइलें रखता है। इन्हें आमतौर पर सीधे संशोधित नहीं किया जाता है, बल्कि इसके बजाय, ऐप के रूट पर .env (पर्यावरण) फ़ाइल में सेट किए गए मानों पर निर्भर करता है
  • डेटाबेस/ : माइग्रेशन, सीड्स और टेस्ट फैक्ट्री सहित डेटाबेस फ़ाइलों को रखता है
  • जनता/ : सार्वजनिक रूप से सुलभ फ़ोल्डर जिसमें संकलित संपत्तियां और निश्चित रूप से एक index.php फ़ाइल होती है
  • संसाधन/ : इसमें फ्रंट-एंड संपत्तियां जैसे जावास्क्रिप्ट फाइलें, भाषा फाइलें, CSS/SASS फाइलें और एप्लिकेशन में उपयोग किए जाने वाले सभी टेम्पलेट्स (जिन्हें ब्लेड टेम्पलेट्स कहा जाता है) शामिल हैं
  • मार्ग/ : एप्लिकेशन में सभी रूट यहीं हैं। रूट के कुछ अलग-अलग “स्कोप” हैं, लेकिन हम जिस पर ध्यान केंद्रित करेंगे, वह web.php फ़ाइल है
  • भंडारण/ : एप्लिकेशन द्वारा उपयोग की जाने वाली सभी अस्थायी कैश फ़ाइलें, सत्र फ़ाइलें, संकलित दृश्य स्क्रिप्ट और लॉग फ़ाइलें
  • परीक्षण/ : इसमें अनुप्रयोग के लिए परीक्षण फ़ाइलें शामिल हैं, जैसे यूनिट परीक्षण और कार्यात्मक परीक्षण।
  • विक्रेता/ : कंपोजर के साथ स्थापित सभी निर्भरता पैकेज

अब, आइए बाकी ऐप बनाएं और इसे एक विशेष आर्टिसन कमांड के साथ चलाएं (अपाचे या nginx जैसे वेब सर्वर को इंस्टॉल और कॉन्फ़िगर करने की परेशानी से खुद को बचाने के लिए)। .env फ़ाइल में सभी कॉन्फ़िगरेशन मान होते हैं जो /config निर्देशिका में फ़ाइलें एप्लिकेशन को कॉन्फ़िगर करने के लिए उपयोग करती हैं। इसके अंदर, आप देखेंगे कि एप्लिकेशन के आंतरिक भागों द्वारा उपयोग किए जाने वाले विभिन्न मापदंडों के लिए कॉन्फ़िगरेशन मान।

एप्लीकेशन डिज़ाइन: हमारी आवश्यकताओं का संक्षिप्त विवरण

इस ऑनलाइन लारवेल ट्यूटोरियल में, हम एक बहुत ही सरल एप्लिकेशन का निर्माण करेंगे जो केवल दो काम करेगा:

  1. वेब फ़ॉर्म से फ़ाइल अपलोड को संभालें
  2. पहले अपलोड की गई फ़ाइलों को एक अलग पृष्ठ पर प्रदर्शित करना।

इस प्रोजेक्ट के लिए, हमारा एप्लिकेशन केवल लिखने के लिए होगा, जिसका अर्थ है कि उपयोगकर्ता केवल फ़ाइलें लिख सकता है और उन फ़ाइलों की सूची देख सकता है जिन्हें उन्होंने अपलोड किया है। यह एप्लिकेशन बेहद बुनियादी है लेकिन आपके लिए अपने Laravel कौशल और ज्ञान का निर्माण शुरू करने के लिए एक अच्छा अभ्यास होना चाहिए। ध्यान दें कि संक्षिप्तता के लिए, मैंने किसी भी डेटाबेस मॉडलिंग, माइग्रेशन और प्रमाणीकरण को बाहर रखा है, लेकिन वास्तविक दुनिया के एप्लिकेशन में, ये अतिरिक्त चीजें हैं जिन पर आप विचार करना चाहेंगे।

यहां उन घटकों की सूची दी गई है जिनकी हमें एप्लिकेशन को अपेक्षित रूप से कार्य करने के लिए आवश्यकता होगी:

  • A मार्ग जो बाहरी दुनिया (इंटरनेट) को एप्लिकेशन का उपयोग करने की अनुमति देगा और साथ ही वह अंत बिंदु निर्दिष्ट करेगा जो यह इंगित करेगा कि अपलोड की गई फ़ाइल को सहेजने का तर्क कहाँ स्थित है
  • A नियंत्रक जो अनुरोध से प्रतिक्रिया प्रवाह को संभालता है
  • A टेम्पलेट इसका उपयोग पहले अपलोड की गई फ़ाइलों की सूची और वास्तविक अपलोड फ़ॉर्म को प्रदर्शित करने के लिए किया जाएगा
  • A का अनुरोध जिसका उपयोग नियंत्रक वेब फॉर्म से पास किए गए डेटा को मान्य करने के लिए करेगा

मार्ग क्या है?

लारवेल में एक रूट मूल रूप से एक यूआरआई द्वारा निर्दिष्ट एक एंडपॉइंट है जो एप्लिकेशन द्वारा पेश की गई कार्यक्षमता के कुछ हिस्से के लिए "पॉइंटर" के रूप में कार्य करता है। सबसे आम तौर पर, एक रूट केवल एक नियंत्रक पर एक विधि को इंगित करता है और यह भी निर्धारित करता है कि कौन सी HTTP विधियाँ उस URI को हिट करने में सक्षम हैं। एक रूट का मतलब हमेशा नियंत्रक विधि नहीं होता है; यह एप्लिकेशन के निष्पादन को एक परिभाषित क्लोजर या अनाम फ़ंक्शन पर भी पास कर सकता है।

रूट का उपयोग क्यों करें?

रूट्स को प्रोजेक्ट की रूट डायरेक्टरी के अंदर /routes फ़ोल्डर के अंतर्गत फ़ाइलों के अंदर संग्रहीत किया जाता है। डिफ़ॉल्ट रूप से, एप्लिकेशन के विभिन्न "पक्षों" के अनुरूप कुछ अलग-अलग फ़ाइलें होती हैं ("पक्ष" हेक्सागोनल आर्किटेक्चर पद्धति से आता है)। उनमें शामिल हैं:

  • web.php सार्वजनिक रूप से दिखने वाले “ब्राउज़र”-आधारित रूट। ये सबसे आम हैं और वेब ब्राउज़र द्वारा हिट किए जाते हैं। वे वेब मिडलवेयर समूह के माध्यम से चलते हैं और इनमें सुविधाएँ भी होती हैं सीएसआरएफ संरक्षण (जो फॉर्म-आधारित दुर्भावनापूर्ण हमलों और हैक से बचाव में मदद करता है) और आम तौर पर इसमें एक हद तक "स्थिति" होती है (इससे मेरा मतलब है कि वे सत्रों का उपयोग करते हैं)
  • api.php रूट जो API समूह से संबंधित होते हैं और इस प्रकार डिफ़ॉल्ट रूप से API मिडलवेयर सक्षम होते हैं। ये रूट स्टेटलेस होते हैं और इनमें कोई सत्र या क्रॉस-रिक्वेस्ट मेमोरी नहीं होती (एक रिक्वेस्ट किसी अन्य रिक्वेस्ट के साथ डेटा या मेमोरी साझा नहीं करती है - प्रत्येक रिक्वेस्ट सेल्फ-एनकैप्सुलेटेड होती है)।
  • console.php ये रूट आपके ऐप के लिए बनाए गए कस्टम आर्टिसन कमांड से मेल खाते हैं
  • channels.php इवेंट प्रसारण के लिए रूट पंजीकृत करता है

इस समय जिस मुख्य फ़ाइल पर ध्यान देना चाहिए वह ब्राउज़र-विशिष्ट फ़ाइल है, web.php। डिफ़ॉल्ट रूप से पहले से ही एक रूट परिभाषित है, जिसे आप अपने एप्लिकेशन के वेब रूट पर नेविगेट करते समय सही तरीके से हिट करते हैं (वेब ​​रूट सार्वजनिक निर्देशिका में है)। हमारे अपलोड एप्लिकेशन को काम करने के लिए हमें तीन अलग-अलग रूट की आवश्यकता होगी:

  • /upload यह फ़ाइलें अपलोड करने के लिए हमारे वेब फ़ॉर्म को प्रदर्शित करने वाले मुख्य पृष्ठ का URI होगा।
  • /process यह वह स्थान होगा जहां /upload URI पर स्थित फ़ॉर्म अपना फ़ॉर्म-सबमिट किया गया डेटा पोस्ट करता है (फ़ॉर्म का “एक्शन”)
  • /list यह साइट पर अपलोड की गई सभी फ़ाइलों की सूची देगा

नोट यदि हम अपलोड फॉर्म और फाइलों की सूची को एक ही पृष्ठ पर प्रदर्शित करने के लिए सभी तर्क रखना चाहते हैं, तो /list समापन बिंदु की आवश्यकता नहीं होगी, हालांकि, हमने विषय में थोड़ा और तथ्य जोड़ने के लिए उन्हें अभी अलग रखा है।

//inside routes/web.php
Route::get('/upload', 'UploadController@upload')->name('upload');
Route::get('/download, 'UploadController@download)->name(‘download');
Route::post('/process', 'UploadController@process')->name('process');
Route::get('/list', 'UploadController@list')->name('list');

इस लारवेल फ्रेमवर्क ट्यूटोरियल में, प्रत्येक वांछित रूट के लिए, हम उपलब्ध HTTP-विशिष्ट अनुरोध विधियों (get(), post(), put() , delete(), patch() या options()) में से किसी एक का उपयोग करके इसे रूट फ़ाइल web.php में स्पष्ट रूप से सूचीबद्ध करेंगे। इनमें से प्रत्येक के टूटने के लिए, जाँच करें इसका आउट। ये विधियाँ यह निर्दिष्ट करती हैं कि कौन सी HTTP क्रियाएँ उस दिए गए रूट तक पहुँचने की अनुमति देती हैं। यदि आपको एक से अधिक HTTP क्रियाएँ स्वीकार करने में सक्षम रूट की आवश्यकता है (जो तब हो सकता है जब आप आरंभिक डेटा और पोस्ट सबमिट किए गए फ़ॉर्म डेटा दोनों को प्रदर्शित करने के लिए एक ही पृष्ठ का उपयोग कर रहे हों), तो आप Route::any() विधि का उपयोग कर सकते हैं।

Route::get() और Route::post() विधि (और Route मुखौटे पर किसी भी अन्य HTTP-क्रिया-संबंधित विधि) के लिए दूसरा तर्क, उस नियंत्रक के अंदर स्थित एक विशिष्ट नियंत्रक और विधि का नाम है, जो अनुमत HTTP अनुरोध (GET, POST, PATCH, आदि) के साथ रूट के अंत बिंदु पर पहुंचने पर निष्पादित होता है। हम तीनों रूट के लिए UploadController का उपयोग कर रहे हैं और उन्हें निम्नलिखित तरीके से निर्दिष्ट किया है:

मार्ग क्या है?

प्रत्येक रूट पर हम जिस अंतिम विधि को कॉल करते हैं, वह उसका name() फ़ंक्शन है, जो एक तर्क के रूप में एकल स्ट्रिंग को स्वीकार करता है और किसी विशेष रूट को आसानी से याद रखने योग्य नाम (हमारे मामलों में, अपलोड, प्रक्रिया और सूची) के साथ कमोबेश “टैग” करने के लिए उपयोग किया जाता है। मुझे एहसास है कि जब URL का नाम बिल्कुल एक जैसा हो, तो प्रत्येक रूट को उसका अपना नाम देना बहुत बढ़िया सुविधा नहीं लगती, लेकिन यह वास्तव में तब काम आता है जब आपके पास /users/profile/dashboard/config जैसा कोई विशिष्ट रूट हो, जिसे profile-admin या user-config के रूप में याद रखना आसान होगा।

अग्रभाग पर एक नोट:

  • फ़ेसेड उन क्लासों के लिए एक "स्थिर" इंटरफ़ेस प्रदान करते हैं जो एप्लिकेशन के सेवा कंटेनर में उपलब्ध हैं।"
  • वे एक संक्षिप्त, स्मरणीय वाक्यविन्यास प्रदान करते हैं जो आपको लंबे वर्ग नामों को याद किए बिना लारवेल की सुविधाओं का उपयोग करने की अनुमति देता है जिन्हें मैन्युअल रूप से इंजेक्ट या कॉन्फ़िगर किया जाना चाहिए।

इस लारवेल फ्रेमवर्क ट्यूटोरियल में ऊपर दिए गए रूट डेफ़िनेशन में, हम एक नए इल्यूमिनेट/रूटिंग/राउटर ऑब्जेक्ट को मैन्युअल रूप से इंस्टेंटिएट करने और उस ऑब्जेक्ट पर संबंधित विधियों को कॉल करने के बजाय रूट फ़ेसेड का उपयोग करते हैं। यह सिर्फ़ एक शॉर्टकट है जो टाइपिंग बचाता है। फ़ेसेड का उपयोग लारवेल फ्रेमवर्क में बहुत ज़्यादा किया जाता है - आप उनसे और अधिक परिचित हो सकते हैं और होना भी चाहिए। फ़ेसेड के लिए दस्तावेज़ यहाँ पाए जा सकते हैं यहाँ उत्पन्न करें.

नियंत्रक क्या है?

एक नियंत्रक "MVC" (मॉडल-व्यू-कंट्रोलर) आर्किटेक्चर में "C" है, जिस पर Laravel आधारित है। एक नियंत्रक का काम इस सरल परिभाषा में समाहित किया जा सकता है: यह क्लाइंट से अनुरोध प्राप्त करता है और क्लाइंट को प्रतिक्रिया देता है। यह सबसे बुनियादी परिभाषा है और किसी भी दिए गए नियंत्रक की न्यूनतम आवश्यकता भी है। इन दो चीजों के बीच यह जो करता है उसे आम तौर पर नियंत्रक की "कार्रवाई" (या "मार्ग का कार्यान्वयन") माना जाता है। यह क्लाइंट के लिए एप्लिकेशन में प्रवेश के दूसरे बिंदु (पहला अनुरोध है) के रूप में कार्य करता है, जो अनुरोध पेलोड (जिस पर हम आगे चर्चा करेंगे) को एप्लिकेशन को भेजता है, जिसमें किसी प्रकार की प्रतिक्रिया (सफलता पृष्ठ, रीडायरेक्ट, त्रुटि पृष्ठ या किसी अन्य प्रकार की HTTP प्रतिक्रिया के रूप में) की अपेक्षा की जाती है।

एक नियंत्रक (मूल रूप से) एक रूट परिभाषा के समान ही कार्य करता है, जिसमें एक अनाम फ़ंक्शन होता है जिसे उस रूट के हिट होने पर "कार्रवाई" के रूप में सेट किया जाता है। अंतर यह है कि एक नियंत्रक चिंताओं के पृथक्करण को अच्छी तरह से पकड़ता है जबकि एक रूट को वास्तविक यूआरएल परिभाषा के लिए इनलाइन परिभाषित किया जाता है, जिसका मूल रूप से मतलब है कि हम रूट के असाइन किए गए यूआरआई को रूट के कार्यान्वयन, या उस कोड के साथ जोड़ रहे हैं जो उस रूट के हिट होने पर निष्पादित होता है।

उदाहरण के लिए, कोड के निम्नलिखित दो टुकड़े एक ही काम करेंगे:

उदाहरण #1: एकल विधि कॉल के अंदर रूट की परिभाषा और कार्यान्वयन (web.php रूट फ़ाइल में)

//inside routes/web.php
<?php
Route::get('/hello-world', function(Request $request) {
   $name = $request->name;
   return response()->make("<h1>Hello World! This is ".$name, 200);
});

उदाहरण #2: रूट की परिभाषा roots/web.php के अंदर है, लेकिन इसका कार्यान्वयन /app/Http/Controllers/HelloWorldController वर्ग के अंदर रहता है

//inside routes/web.php
<?php

Route::get('/hello-world', 'HelloWorldController@index')->name('hello-world');

------------------------------------------------------------------------------------
//inside app/Http/Controllers/HelloWorldController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;

class HelloWorldController extends Controller
{
   public function index(Request $request)
   {
       $name = $request->name;
       return response()->make("<h1>Hello World! This is ".$name, 200);
   }
}

हालाँकि लारवेल उदाहरण #2 बहुत अधिक काम की तरह लगता है (जो कि ऐसा नहीं है - बस थोड़ा और कोड ही काफी है), दिए गए “हेल्लो-वर्ल्ड” रूट के लिए हमारे एक्शन लॉजिक को कॉलबैक फ़ंक्शन के रूप में रूट की परिभाषा के बजाय नियंत्रक के अंदर रखकर हमें मिलने वाले लाभों पर नज़र डालें:

  1. हमारा तर्क स्पष्ट रूप से अपनी स्वयं की श्रेणी (चिंताओं का पृथक्करण) में विभाजित है
  2. हमारा नियंत्रक बाद में विस्तार के लिए सेट किया गया है यदि हमें इसमें अतिरिक्त क्षमताएं जोड़ने की आवश्यकता है... मान लें कि शायद हम एक "अलविदा-दुनिया" सुविधा जोड़ना चाहते थे... इस मामले में हम नियंत्रक का नाम बदलकर अधिक सामान्य "हैलोकंट्रोलर" कर देंगे और फिर दो अलग-अलग तरीके परिभाषित करेंगे, नमस्ते() और अलविदा(). हमें दो अलग-अलग मार्गों को भी परिभाषित करना होगा जो /नमस्ते और / अलविदा नियंत्रक पर उनके उचित विधि के लिए URIs। यह प्रत्येक रूट के कार्यान्वयन के साथ रूट फ़ाइल को मोटा करने की तुलना में वांछनीय है - कॉलबैक फ़ंक्शन के रूप में परिभाषित किया गया है।
  3. लारवेल में एप्लिकेशन में सभी रूट परिभाषाओं को कैश करने की अंतर्निहित क्षमता है ताकि यह किसी दिए गए रूट को खोजने में लगने वाले समय को तेज कर सके (एप्लिकेशन प्रदर्शन को बढ़ाता है); तथापि, आप इसका लाभ तभी उठा पाएंगे जब एप्लिकेशन के अंदर आपके सभी परिभाषित रूट नियंत्रक-विशिष्ट मैपिंग का उपयोग करके कॉन्फ़िगर किए गए हों (ऊपर उदाहरण #2 देखें)

आइये इस कमांड को चलायें जो हमारे लिए एक नया नियंत्रक उत्पन्न करेगा।

// ...inside the project's root directory:
php artisan make:controller UploadController   

अनिवार्य रूप से, यह कमांड मुख्य नियंत्रक निर्देशिका के अंदर /app/Http/Controllers/UploadController.php पर “UploadController” नामक नियंत्रक के लिए एक स्टब उत्पन्न करता है। उस फ़ाइल को खोलने और देखने के लिए स्वतंत्र महसूस करें। यह बहुत सरल है क्योंकि यह नियंत्रक का केवल एक स्टब आउट संस्करण है, जिसमें सही नामस्थान पथ और आवश्यक वर्ग हैं जिनसे यह विस्तारित होता है।

अनुरोध तैयार करना

इससे पहले कि हम इस PHP Laravel ट्यूटोरियल में आगे बढ़ें और UploadController के जेनरेट किए गए स्टब में कुछ बदलाव करें, मुझे लगता है कि पहले रिक्वेस्ट क्लास बनाना ज़्यादा समझदारी होगी। ऐसा इसलिए है क्योंकि रिक्वेस्ट को हैंडल करने वाले कंट्रोलर मेथड को अपने सिग्नेचर में रिक्वेस्ट ऑब्जेक्ट को टाइप हिंट करना चाहिए, जिससे यह आने वाले फॉर्म डेटा को स्वचालित रूप से वैलिडेट कर सके (जैसा कि rules() मेथड में बताया गया है। इस पर बाद में और जानकारी दी जाएगी…) अभी के लिए, आइए अपने रिक्वेस्ट स्टब को जेनरेट करने के लिए फिर से आर्टिसन कमांड का इस्तेमाल करें:

php artisan make:request UploadFileRequest

यह कमांड app/Http/Requests/UploadFileRequest के अंदर UploadFileRequest नामक एक फ़ाइल जेनरेट करेगा। स्टब खोलें और एक नज़र डालें... आपको यह बहुत सरल लगेगा, जिसमें केवल दो विधियाँ हैं, authorize() और नियम।

सत्यापन तर्क बनाना

आइए अपने एप्लिकेशन की ज़रूरतों को पूरा करने के लिए अनुरोध स्टब को संशोधित करें। फ़ाइल को इस तरह संशोधित करें कि यह इस तरह दिखे:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class UploadFileRequest extends FormRequest
{
   /**
    * Determine if the user is authorized to make this request.
    *
    * @return bool
    */
   public function authorize()
   {
       return true;
   }

   /**
    * Get the validation rules that apply to the request.
    *
    * @return array
    */
   public function rules()
   {
       return [
           'fileName' => 'required|string',
           'userFile' => 'required|file'
       ];
   }
}

बहुत ज़्यादा बदलाव नहीं हुए हैं, लेकिन ध्यान दें कि authorize() विधि अब false के बजाय true लौटाती है। यह विधि तय करती है कि अनुरोध को एप्लिकेशन में जाने दिया जाए या नहीं। अगर इसे false पर सेट किया जाता है, तो यह अनुरोध को सिस्टम में प्रवेश करने से रोक देता है (जो आमतौर पर नियंत्रक पर एक विधि होगी)। यह उपयोगकर्ता पर किसी भी प्राधिकरण जांच या किसी अन्य तर्क को रखने के लिए एक बहुत ही सुविधाजनक स्थान होगा जो यह तय कर सकता है कि अनुरोध नियंत्रक के पास आगे बढ़ सकता है या नहीं। अभी के लिए, हम यहाँ केवल true लौटाते हैं ताकि किसी भी चीज़ और हर चीज़ को अनुरोध का उपयोग करने की अनुमति मिल सके।

दूसरी विधि, rules() वह है जहाँ सत्यापन के संबंध में सभी जादू काम करते हैं। विचार सरल है: निम्न रूप में नियमों का एक सेट युक्त एक सरणी लौटाएँ:

'formFieldName' => 'constraints this field has separated by pipe characters (|)'

कई अलग-अलग वैलिडेशन कंस्ट्रेन्ट हैं जो Laravel द्वारा बॉक्स से बाहर ही समर्थित हैं। उनकी पूरी सूची के लिए, ऑनलाइन दस्तावेज़ देखें यहाँ उत्पन्न करेंहमारे अपलोड एप्लिकेशन के लिए, दो फ़ील्ड होंगे जो फ्रंट एंड पर एक फ़ॉर्म से POST अनुरोध के माध्यम से पास किए जाएंगे। फ़ाइलनाम पैरामीटर को फ़ॉर्म बॉडी के अंदर शामिल किया जाना चाहिए (यानी आवश्यक) और फ़ाइलनाम के रूप में उपयोग किया जाता है जिसे हम फ़ाइल को स्टोरेज में स्टोर करेंगे (यह नियंत्रक में किया जाता है - हम इसे थोड़ी देर बाद प्राप्त करेंगे)। हम यह भी निर्दिष्ट करते हैं कि फ़ाइल नाम एक पाइप वर्ण (|) और शब्द 'स्ट्रिंग' जोड़कर एक स्ट्रिंग होना चाहिए। बाधाओं को हमेशा पाइप द्वारा सीमांकित किया जाता है, जिससे आप किसी भी अतिरिक्त मानदंड को एक पंक्ति में दिए गए फ़ील्ड के लिए निर्दिष्ट कर सकते हैं! क्या शक्ति है!

दूसरा पैरामीटर, userFile, वह वास्तविक फ़ाइल है जिसे उपयोगकर्ता किसी वेबपेज पर किसी फ़ॉर्म से अपलोड करता है। UserFile भी आवश्यक है और चाहिए एक फ़ाइल हो. नोट: अगर हम अपलोड की गई फ़ाइल को एक छवि होने की उम्मीद कर रहे थे, तो हम इसके बजाय छवि बाधा का उपयोग करेंगे, जो लोकप्रिय छवि प्रकारों (jpeg, png, bmp, gif या svg) में से एक के रूप में स्वीकार किए जाने वाले फ़ाइल प्रकारों को सीमित करेगा। चूँकि हम उपयोगकर्ता को किसी भी प्रकार की फ़ाइल अपलोड करने की अनुमति देना चाहते हैं, इसलिए हम केवल फ़ाइल सत्यापन बाधा के साथ ही रहेंगे।

अनुरोध ऑब्जेक्ट के बारे में बस इतना ही है। इसका मुख्य काम केवल स्वीकार्य मानदंड (बाधाओं) को बनाए रखना है जिसे फ़ॉर्म के बॉडी पैरामीटर को एप्लिकेशन में गहराई से आगे बढ़ने के लिए पूरा करना चाहिए। ध्यान देने वाली एक और बात यह है कि इन दो फ़ील्ड (यूज़रफ़ाइल और फ़ाइलनाम) को HTML कोड के अंदर इनपुट फ़ील्ड के रूप में भी निर्दिष्ट किया जाना चाहिए (फ़ील्ड नाम अनुरोध ऑब्जेक्ट के अंदर नाम के अनुरूप होना चाहिए)।

आप पूछ रहे होंगे: निश्चित रूप से यह उन विशेषताओं को परिभाषित करता है जो एक फॉर्म अनुरोध में होनी चाहिए, लेकिन इन बाधाओं की वास्तविक जाँच कहाँ की जाती है? हम आगे इस पर चर्चा करेंगे।

नियंत्रक को संशोधित करना

app/Http/Controllers/UploadController खोलें और इसमें निम्नलिखित परिवर्तन करें:

<?php

namespace App\Http\Controllers;

use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Http\Request;
use App\Http\Requests\UploadFileRequest; //our new request class
use Illuminate\Support\Facades\Storage; 

class UploadController extends Controller
{
   /**
    * This is the method that will simply list all the files uploaded by name and provide a
    * link to each one so they may be downloaded
    *
    * @param $request : A standard form request object
    * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
    * @throws BindingResolutionException
    */
   public function list(Request $request)
   {
       $uploads = Storage::allFiles('uploads');

       return view('list', ['files' => $uploads]);
   }

   /**
    * @param $file
    * @return \Symfony\Component\HttpFoundation\BinaryFileResponse
    * @throws BindingResolutionException
    */
   public function download($file)
   {
       return response()->download(storage_path('app/'.$file));
   }

   /**
    * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
    * @throws BindingResolutionException
    */
   public function upload()
   {
       return view('upload');
   }

   /**
    * This method will handle the file uploads. Notice that the parameter's typehint
    * is the exact request class we generated in the last step. There is a reason for this!
    *
    * @param $request : The special form request for our upload application
    * @return array|\Illuminate\Http\UploadedFile|\Illuminate\Http\UploadedFile[]|null
    * @throws BindingResolutionException
    */
   public function store(UploadFileRequest $request)
   {
       //At this point, the parameters passed into the $request (from form) are
       //valid--they satisfy each of the conditions inside the rules() method

       $filename = $request->fileName;    //parameters have already been validated
       $file = $request->file('userFile'); //that we don't need any additional isset()

       $extension = $file->getClientOriginalExtension(); //grab the file extension
       $saveAs = $filename . "." . $extension; //filename to save file under

       $file->storeAs('uploads', $saveAs, 'local'); //save the file to local folder

       return response()->json(['success' => true]); //return a success message
   }
}

इसलिए अपलोड की गई फ़ाइलों को डिस्क पर सहेजने का यह एक बहुत ही सरल तरीका है। यहाँ ऊपर upload() विधि का विवरण दिया गया है:

  • नियंत्रक विधि में अनुरोध वर्ग को टाइप-संकेत दें जो 'मांस और आलू' कार्यक्षमता कर रहा है ताकि हम आने वाले डेटा को स्वचालित रूप से सत्यापित कर सकें
  • नियंत्रक विधि के अंदर (अब मान्य) अनुरोध ऑब्जेक्ट से फ़ाइल को प्राप्त करें (इस मामले में हमने इसे upload() नाम दिया है, लेकिन इसे store() जैसे अधिक मानकीकृत नाम से भी नामित किया जा सकता था)।
  • अनुरोध से फ़ाइल नाम प्राप्त करें
  • अंतिम फ़ाइल नाम जनरेट करें जिसका उपयोग फ़ाइल को सहेजने के लिए किया जाएगा। getClientOriginalExtension() विधि केवल अपलोड की गई फ़ाइल के मूल एक्सटेंशन को पकड़ लेती है।
  • फ़ाइल को स्थानीय फ़ाइल सिस्टम में storeAs() विधि का उपयोग करके संग्रहीत करें, /storage निर्देशिका के अंदर नामित पथ को पहले तर्क के रूप में और इसे सहेजने के लिए फ़ाइल नाम को दूसरे तर्क के रूप में पास करें।
  • अनुरोध सफल होने का संकेत देते हुए JSON प्रतिक्रिया लौटाएँ

ब्लेड टेम्पलेट

इस पहेली का आखिरी मुख्य भाग ब्लेड टेम्पलेट है, जो हमारे सरल अनुप्रयोग के लिए सभी HTML, CSS और जावास्क्रिप्ट को रखेगा। यहाँ कोड है - हम इसे बाद में समझाएँगे।

<body>
   <h1>Upload a file</h1>
   <form id="uploadForm" name="uploadForm" action="{{route('upload')}}" enctype="multipart/form-data">
       @csrf
       <label for="fileName">File Name:</label>
       <input type="text" name="fileName" id="fileName" required /><br />
       <label for="userFile">Select a File</label>
       <input type="file" name="userFile" id="userFile" required />
       <button type="submit" name="submit">Submit</button>
   </form>
   <h2 id="success" style="color:green;display:none">Successfully uploaded file</h2>
   <h2 id="error" style="color:red;display:none">Error Submitting File</h2>
   <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
   <script>
        $('#uploadForm').on('submit', function(e) {
            e.preventDefault();
            var form = $(this);
            var url = form.attr('action');
            $.ajax({
                url: url,
                type: "POST",
                data: new FormData(this),
                processData: false,
                contentType: false,
                dataType: "JSON",
                success: function(data) {
                    $("#fileName").val("");
                    $("#userFile").val("");
                }
            }).done(function() {
                $('#success').css('display', 'block');
                window.setTimeout(()=>($("#success").css('display', 'none')), 5000);
            }).fail(function() {
                $('#error').css('display', 'block');
                window.setTimeout(()=>($("#error").css('display', 'none')), 5000);
            });
        });
   </script>
</body>
</html>

यहाँ हमारा क्या कहना है /डालना पेज ऐसा दिखता है:

ब्लेड टेम्पलेट

यह ब्लेड फ़ाइल का एक बहुत ही विशिष्ट उदाहरण है जिसमें एसिंक्रोनस कार्यक्षमता जोड़ने के लिए HTML फ़ॉर्म और जावास्क्रिप्ट/jQuery शामिल है (ताकि पेज रिफ्रेश न हो)। टैग जिसमें कोई मेथड विशेषता नहीं है (जिसे मैं बस एक सेकंड में समझाऊंगा) और एक दिलचस्प एक्शन विशेषता है जिसका मान {{route('file.upload')}} है। ब्लेड में, इसे के रूप में जाना जाता है निर्देश. डायरेक्टिव सिर्फ़ फ़ंक्शन का एक आकर्षक नाम है-वे ब्लेड टेम्प्लेट के लिए विशिष्ट फ़ंक्शन हैं जो वेब पेज और वेब एप्लिकेशन बनाने के लिए सामान्य रूप से अलग-अलग ऑपरेशन करते हैं। ब्लेड द्वारा किए जा सकने वाले सभी बेहतरीन कामों को बेहतर ढंग से समझने के लिए, दस्तावेज़ देखें यहाँ उत्पन्न करेंउपरोक्त मामले में, हम अपने फॉर्म सबमिशन के लिए URL जेनरेट करने के लिए रूट डायरेक्टिव का उपयोग कर रहे हैं।

याद रखें कि हमने अपने रूट को पहले ही एप्लीकेशन में web.php फ़ाइल के अंदर परिभाषित कर दिया था, और उनमें से प्रत्येक के लिए याद रखने में आसान नाम निर्दिष्ट किया था। {{route()}} निर्देश एक रूट का नाम स्वीकार करता है, इसे आंतरिक रूप से कैश किए गए रूट सूची के अंदर देखता है, और web.php फ़ाइल में उस रूट की परिभाषा के आधार पर एक पूर्ण URL उत्पन्न करता है। इस पहले मामले के लिए, हम निर्दिष्ट कर रहे हैं कि हम चाहते हैं कि फ़ॉर्म अपना सबमिट किया गया डेटा हमारे एप्लीकेशन के /process URL पर भेजे, जिसे इस प्रकार परिभाषित किया गया है पोस्ट मार्ग.

अगली अजीब बात जो आपने देखी होगी वह है @csrf टैग जो ओपनिंग फॉर्म टैग के ठीक नीचे है। ब्लेड में, यह टैग फॉर्म पर एक _token पैरामीटर जेनरेट करता है, जिसे फॉर्म डेटा को प्रोसेस करने की अनुमति देने से पहले एप्लिकेशन के अंदर चेक किया जाता है। यह सुनिश्चित करता है कि फॉर्म के अंदर का डेटा वैध मूल का है और क्रॉस-साइट-रिक्वेस्ट-फ़ॉर्जरी हमलों को रोकता है। इस पर अधिक जानकारी के लिए, देखें डॉक्स.

इसके बाद हम अपने फॉर्म को सामान्य रूप से परिभाषित करते हैं, हालाँकि, ध्यान दें कि हमारे फॉर्म पैरामीटर, userFile और fileName के नाम समान हैं। एक ही सटीक जैसा कि हमारे अनुरोध ऑब्जेक्ट के अंदर परिभाषित किया गया है। यदि हम अनुरोध ऑब्जेक्ट में परिभाषित किसी दिए गए पैरामीटर के लिए इनपुट शामिल करना भूल गए (या इसे गलत तरीके से लिखा), तो अनुरोध विफल हो जाएगा और एक त्रुटि वापस आ जाएगी, जिससे मूल फ़ॉर्म अनुरोध कभी भी UploadController@process पर स्थित नियंत्रक विधि को हिट करने से रोका जा सकेगा।

आगे बढ़ें और इसे आज़माएँ और इस फ़ॉर्म का उपयोग करके आवेदन में कुछ फ़ाइलें सबमिट करें। उसके बाद, नेविगेट करें /सूची अपलोड फ़ोल्डर की सामग्री देखने के लिए पृष्ठ पर जाएँ, जिसमें आपके द्वारा अपलोड की गई फ़ाइलें एक तालिका में सूचीबद्ध होंगी:

ब्लेड टेम्पलेट

बड़ा चित्र

आइए एक कदम पीछे जाएं और देखें कि हमने इस Laravel ट्यूटोरियल में क्या किया है।

यह आरेख एप्लिकेशन को वर्तमान स्थिति में दर्शाता है (उच्च-स्तरीय विवरण को छोड़कर):

लारवेल ट्यूटोरियल आरेख

आपको याद होगा कि इस Laravel ट्यूटोरियल की शुरुआत में हमने जो रिक्वेस्ट ऑब्जेक्ट बनाया था, उसके नियम विधि में वही पैरामीटर परिभाषित होने चाहिए जो ब्लेड टेम्पलेट में फ़ॉर्म पर हैं (यदि नहीं तो “वैलिडेशन लॉजिक बनाना” अनुभाग को फिर से पढ़ें)। उपयोगकर्ता एक वेब पेज में फ़ॉर्म दर्ज करता है जिसे ब्लेड टेम्पलेट इंजन के माध्यम से रेंडर किया जाता है (यह प्रक्रिया निश्चित रूप से ऑटो-पायलट पर है इसलिए हमें इसके बारे में सोचना भी नहीं पड़ता है) और फ़ॉर्म सबमिट करता है। नीचे टेम्पलेट का jQuery कोड डिफ़ॉल्ट सबमिशन को रोकता है (जो स्वचालित रूप से एक अलग पेज पर रीडायरेक्ट करेगा), एक ajax रिक्वेस्ट बनाता है, फ़ॉर्म डेटा के साथ रिक्वेस्ट को लोड करता है और फ़ाइल अपलोड करता है, और पूरी चीज़ को हमारे एप्लिकेशन की पहली परत में भेजता है: रिक्वेस्ट।

अनुरोध ऑब्जेक्ट rules() विधि के अंदर पैरामीटर को सबमिट किए गए फ़ॉर्म पैरामीटर के साथ जोड़कर पॉपुलेट हो जाता है, फिर प्रत्येक निर्दिष्ट नियम के अनुसार डेटा को मान्य करता है। यदि सभी नियम संतुष्ट हैं, तो अनुरोध उस नियंत्रक विधि के साथ पारित हो जाता है जो रूट फ़ाइल web.php में परिभाषित मूल्यों से मेल खाता है। इस मामले में, यह अपलोडकंट्रोलर की प्रक्रिया() विधि है जो काम करती है। एक बार जब हम नियंत्रक को हिट करते हैं, तो हम पहले से ही जानते हैं कि अनुरोध ने सत्यापन पारित कर दिया है, इसलिए हमें यह दोबारा जांचने की ज़रूरत नहीं है कि दिया गया फ़ाइल नाम वास्तव में एक स्ट्रिंग है या उपयोगकर्ता फ़ाइल पैरामीटर वास्तव में किसी प्रकार की फ़ाइल रखता है... हम सामान्य रूप से जारी रख सकते हैं।

नियंत्रक विधि फिर अनुरोध ऑब्जेक्ट से मान्य पैरामीटर को पकड़ती है, पास किए गए फ़ाइलनाम पैरामीटर को userFile के मूल एक्सटेंशन के साथ जोड़कर एक पूर्ण फ़ाइल नाम उत्पन्न करती है, फ़ाइल को हमारे एप्लिकेशन में एक निर्देशिका के अंदर संग्रहीत करती है, फिर एक सरल JSON-एन्कोडेड प्रतिक्रिया लौटाती है जो यह सत्यापित करती है कि अनुरोध सफल रहा। प्रतिक्रिया jQuery तर्क द्वारा प्राप्त की जाती है, जो कुछ और UI-संबंधित कार्य करती है जैसे कि 5 सेकंड के लिए सफलता (या त्रुटि) संदेश प्रदर्शित करना और फिर उसे छिपाना और साथ ही पिछली फ़ॉर्म प्रविष्टियों को साफ़ करना... ऐसा इसलिए है ताकि उपयोगकर्ता निश्चित रूप से जान सके कि अनुरोध सफल रहा और यदि वे चाहें तो दूसरी फ़ाइल अपलोड कर सकते हैं।

इसके अलावा, ऊपर दिए गए आरेख में ध्यान दें कि क्लाइंट और सर्वर के बीच रेखा कहाँ खींची गई है। यह अवधारणा आपके लिए समझने के लिए बिल्कुल महत्वपूर्ण है और भविष्य में आपके सामने आने वाली समस्याओं और मुद्दों को हल करने में आपकी मदद करेगी, उदाहरण के लिए, किसी भी समय होने वाले कई एसिंक्रोनस अनुरोध। अलगाव अनुरोध ऑब्जेक्ट की सीमा पर ठीक है। अनुरोध ऑब्जेक्ट को ही बाकी एप्लिकेशन के लिए "गेटवे" के रूप में माना जा सकता है... यह वेब ब्राउज़र से पास किए गए फ़ॉर्म मानों का प्रारंभिक सत्यापन और पंजीकरण करता है। यदि उन्हें वैध माना जाता है, तो यह नियंत्रक के पास जारी रहता है। इससे पहले की हर चीज़ फ़्रंट एंड पर है ("क्लाइंट" का शाब्दिक अर्थ है "उपयोगकर्ता के कंप्यूटर पर")। प्रतिक्रिया ऐप से क्लाइंट साइड में वापस आ जाती है, जहाँ हमारा jQuery कोड धैर्यपूर्वक इसके आने का इंतज़ार करता है और इसे प्राप्त करने के बाद कुछ सरल UI कार्य करता है।

हमने लगभग 90+ महत्वपूर्ण अक्सर पूछे जाने वाले प्रश्नों को कवर किया है लारवेल और PHP से संबंधित साक्षात्कार प्रश्न नए और अनुभवी उम्मीदवारों को सही नौकरी पाने के लिए।