PHP में सत्र. PHP और MySQL में एक अविश्वसनीय रूप से सरल पंजीकरण प्रणाली का निर्माण जहां यह सब शुरू हुआ

💖क्या आपको यह पसंद है?लिंक को अपने दोस्तों के साथ साझा करें

Reg.ru: डोमेन और होस्टिंग

रूस में सबसे बड़ा रजिस्ट्रार और होस्टिंग प्रदाता।

सेवा में 2 मिलियन से अधिक डोमेन नाम।

प्रमोशन, डोमेन मेल, व्यावसायिक समाधान।

दुनिया भर में 700 हजार से अधिक ग्राहक पहले ही अपनी पसंद बना चुके हैं।

*स्क्रॉलिंग रोकने के लिए माउस को ऊपर ले जाएँ।

पीछे की ओर आगे की ओर

PHP और MySQL में एक सरल उपयोगकर्ता पंजीकरण प्रणाली बनाना

पंजीकरण प्रणाली बनाना बहुत काम का काम है। आपको कोड लिखना होगा जो ईमेल पते को मान्य करता है, पंजीकरण की पुष्टि करने वाला एक ईमेल भेजता है, और अन्य फॉर्म फ़ील्ड को भी मान्य करता है, और भी बहुत कुछ।

और आपके यह सब लिखने के बाद भी, उपयोगकर्ता पंजीकरण करने में अनिच्छुक होंगे, क्योंकि... इसके लिए उनकी ओर से कुछ प्रयास की आवश्यकता है।

इस ट्यूटोरियल में, हम एक बहुत ही सरल पंजीकरण प्रणाली बनाएंगे जिसमें पासवर्ड की बिल्कुल भी आवश्यकता या भंडारण की आवश्यकता नहीं होगी! परिणाम को संशोधित करना और मौजूदा PHP साइट में जोड़ना आसान होगा। जानना चाहते हैं कि यह कैसे काम करता है? नीचे पढ़ें।



यहां बताया गया है कि हमारी सुपर सरल प्रणाली कैसे काम करेगी:

हम प्राधिकरण फॉर्म और पंजीकरण को जोड़ देंगे। इस फॉर्म में आपका ईमेल पता दर्ज करने के लिए एक फ़ील्ड और एक पंजीकरण बटन होगा;
- ईमेल पते के साथ फ़ील्ड भरते समय, पंजीकरण बटन पर क्लिक करने से नए उपयोगकर्ता के बारे में एक रिकॉर्ड बन जाएगा, लेकिन केवल तभी जब दर्ज किया गया ईमेल पता डेटाबेस में नहीं मिला हो।

इसके बाद, वर्णों का एक यादृच्छिक अद्वितीय सेट (टोकन) बनाया जाता है, जिसे उपयोगकर्ता द्वारा निर्दिष्ट ईमेल पर एक लिंक के रूप में भेजा जाता है जो 10 मिनट के लिए प्रासंगिक होगा;
- लिंक उपयोगकर्ता को हमारी वेबसाइट पर ले जाता है। सिस्टम टोकन की उपस्थिति निर्धारित करता है और उपयोगकर्ता को अधिकृत करता है;

इस दृष्टिकोण के लाभ:

पासवर्ड संग्रहीत करने या फ़ील्ड मान्य करने की कोई आवश्यकता नहीं है;
- आपका पासवर्ड, सुरक्षा प्रश्न आदि पुनर्प्राप्त करने की कोई आवश्यकता नहीं है;
- जिस क्षण कोई उपयोगकर्ता पंजीकरण/लॉग इन करता है, आप हमेशा यह सुनिश्चित कर सकते हैं कि यह उपयोगकर्ता आपके एक्सेस क्षेत्र में होगा (ईमेल पता सत्य है);
- अविश्वसनीय रूप से सरल पंजीकरण प्रक्रिया;

कमियां:

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

हमारे सिस्टम के फायदे और नुकसान की तुलना करते हुए, हम कह सकते हैं कि सिस्टम में उच्च उपयोगिता (अंतिम उपयोगकर्ता के लिए अधिकतम सुविधा) है और साथ ही, कम सुरक्षा संकेतक भी है।

इसलिए इसे उन मंचों और सेवाओं पर पंजीकरण के लिए उपयोग करने का सुझाव दिया गया है जो महत्वपूर्ण जानकारी के साथ काम नहीं करते हैं।

इस सिस्टम का उपयोग कैसे करें

यदि आपको अपनी साइट पर उपयोगकर्ताओं को अधिकृत करने के लिए किसी सिस्टम का उपयोग करने की आवश्यकता है, और आप इस पाठ को टुकड़ों में नहीं लेना चाहते हैं, तो आपको यहां क्या करना है:

आपको पाठ से जुड़े स्रोतों को डाउनलोड करना होगा
- संग्रह में tables.sql फ़ाइल ढूंढें। phpMyAdmin में आयात विकल्प का उपयोग करके इसे अपने डेटाबेस में आयात करें। वैकल्पिक तरीका: इस फ़ाइल को टेक्स्ट एडिटर के माध्यम से खोलें, SQL क्वेरी की प्रतिलिपि बनाएँ और इसे निष्पादित करें;
- include/main.php खोलें और अपने डेटाबेस से जुड़ने के लिए सेटिंग्स भरें (डेटाबेस से जुड़ने के लिए उपयोगकर्ता और पासवर्ड, साथ ही होस्ट और डेटाबेस का नाम निर्दिष्ट करें)। उसी फ़ाइल में, आपको ईमेल भी निर्दिष्ट करना होगा, जिसका उपयोग सिस्टम द्वारा भेजे गए संदेशों के मूल पते के रूप में किया जाएगा। कुछ होस्ट आउटगोइंग ईमेल को तब तक ब्लॉक कर देते हैं जब तक कि फॉर्म में वास्तविक ईमेल पता न हो, जो होस्ट के नियंत्रण कक्ष से बनाया गया हो, इसलिए वास्तविक पता प्रदान करें;
- अपने होस्ट पर FTP के माध्यम से सभी Index.php, संरक्षित.php फ़ाइलें और संपत्तियाँ और फ़ोल्डर्स अपलोड करें;
- प्रत्येक PHP पेज पर नीचे दिया गया कोड जोड़ें जहां आप लॉगिन फॉर्म प्रदर्शित करना चाहते हैं;

Require_once "includes/main.php"; $उपयोगकर्ता = नया उपयोगकर्ता(); यदि(!$user->loggedIn())(रीडायरेक्ट("index.php"); )
- तैयार!

जो लोग इसमें रुचि रखते हैं कि यह सब कैसे काम करता है, उनके लिए नीचे पढ़ें!

पहला कदम प्राधिकरण फॉर्म के लिए एचटीएम कोड लिखना है। यह कोड Index.php फ़ाइल में स्थित है। इस फ़ाइल में PHP कोड भी है जो फॉर्म डेटा और अन्य उपयोगी लॉगिन सिस्टम फ़ंक्शंस को संभालता है। आप PHP कोड समीक्षा के लिए समर्पित नीचे दिए गए अनुभाग में इसके बारे में अधिक जान सकते हैं।

Index.php

ट्यूटोरियल: PHP और MySQL लॉगिन या रजिस्टर के साथ सुपर सरल पंजीकरण प्रणाली

ऊपर अपना ईमेल पता दर्ज करें और हम भेज देंगे
आप एक लॉगिन लिंक.

लॉगिन/रजिस्टर करें

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


जावास्क्रिप्ट

jQuery फ़ंक्शन का उपयोग करके "रजिस्टर/लॉगिन" बटन की स्थिति को ट्रैक करता है e.preventDefault()और AJAX अनुरोध भेजता है। सर्वर प्रतिक्रिया के आधार पर, यह एक या दूसरा संदेश प्रदर्शित करता है और आगे की कार्रवाई निर्धारित करता है/

संपत्ति/जेएस/स्क्रिप्ट.जेएस

$(function())( var form = $("#login-register"); form.on("submit", function(e)( if(form.is("।loading, .loggedIn"))( return गलत ; ) var ईमेल = form.find("input").val(), messageHolder = form.find("span"); e.preventDefault(); $.post(this.action, (ईमेल: ईमेल), फ़ंक्शन (m)( if(m.error)( form.addClass("error"); messageHolder.text(m.message); ) else( form.removeClass("error").addClass("loggedIn"); messageHolder . text(m.message); ) )); )); $(document).ajaxStart(function())( form.addClass("loading"); )); $(document).ajaxComplete(function()) ( फॉर्म. रिमूवक्लास("लोड हो रहा है"); )); ));

AJAX अनुरोध की वर्तमान स्थिति को प्रदर्शित करने के लिए फॉर्म में जोड़ा गया था (यह विधियों के कारण संभव हुआ था अजाक्सस्टार्ट()) और अजाक्सपूर्ण(), जिसे आप फ़ाइल के अंत में पा सकते हैं)।

यह वर्ग एक घूमती हुई एनिमेटेड GIF फ़ाइल प्रदर्शित करता है (जैसे कि हमें संकेत देता है कि अनुरोध संसाधित किया जा रहा है), और फॉर्म को दोबारा सबमिट होने से रोकने के लिए एक ध्वज के रूप में भी कार्य करता है (जब रजिस्टर बटन पहले ही एक बार क्लिक किया जा चुका हो)। .loggedIn वर्ग एक अन्य ध्वज है - यह तब सेट किया जाता है जब ईमेल भेजा गया था। यह फ़्लैग फ़ॉर्म के साथ किसी भी आगे की कार्रवाई को तुरंत रोक देता है।

डेटाबेस स्कीमा

हमारा अविश्वसनीय रूप से सरल लॉगिंग सिस्टम 2 MySQL तालिकाओं का उपयोग करता है (SQL कोड tables.sql फ़ाइल में है)। पहला उपयोगकर्ता खातों के बारे में डेटा संग्रहीत करता है। दूसरा लॉगिन प्रयासों की संख्या के बारे में जानकारी संग्रहीत करता है।


उपयोगकर्ता तालिका स्कीमा.

सिस्टम पासवर्ड का उपयोग नहीं करता है, जैसा कि चित्र में देखा जा सकता है। इस पर आप टोकन_वैलिडिटी कॉलम के बगल में टोकन वाला टोकन कॉलम देख सकते हैं। जैसे ही उपयोगकर्ता सिस्टम से जुड़ता है और संदेश भेजने के लिए अपना ईमेल सेट करता है, टोकन इंस्टॉल हो जाता है (अगले ब्लॉक में इस पर अधिक जानकारी)। टोकन_वैधता कॉलम 10 मिनट बाद का समय निर्धारित करता है, जिसके बाद टोकन मान्य नहीं होता है।


तालिका स्कीमा जो प्राधिकरण प्रयासों की संख्या की गणना करती है।

दोनों तालिकाओं में, आईपी पते को पूर्णांक प्रकार के क्षेत्र में ip2long फ़ंक्शन का उपयोग करके संसाधित रूप में संग्रहीत किया जाता है।

अब हम कुछ PHP कोड लिख सकते हैं। सिस्टम की मुख्य कार्यक्षमता वर्ग User.class.php को सौंपी गई है, जिसे आप नीचे देख सकते हैं।

यह वर्ग सक्रिय रूप से idorm (docs) का उपयोग करता है, ये लाइब्रेरी डेटाबेस के साथ काम करने के लिए न्यूनतम आवश्यक उपकरण हैं। यह डेटाबेस एक्सेस, टोकन जेनरेशन और टोकन सत्यापन को संभालता है। यह एक सरल इंटरफ़ेस प्रदान करता है जो PHP का उपयोग करने पर पंजीकरण प्रणाली को आपकी साइट से कनेक्ट करना आसान बनाता है।

उपयोगकर्ता.वर्ग.php

क्लास उपयोगकर्ता (//निजी ORM केस निजी $orm; /** * टोकन द्वारा उपयोगकर्ता ढूंढें। केवल वैध टोकन ही विचार के लिए स्वीकार किए जाते हैं। टोकन बनाए जाने के क्षण से केवल 10 मिनट के लिए उत्पन्न होता है * @param स्ट्रिंग $टोकन . यह वह टोकन है जिसकी हम तलाश कर रहे हैं * @रिटर्न यूजर, यूजर फ़ंक्शन का मान लौटाएं */ सार्वजनिक स्थैतिक फ़ंक्शन ढूंढें बायटोकन($टोकन)( // डेटाबेस में टोकन ढूंढें और सुनिश्चित करें कि सही टाइमस्टैम्प सेट है $result = ORM::for_table("reg_users") ->where ("टोकन", $टोकन) ->where_raw("token_validity > NOW()") ->find_one(); if(!$result)( return false; ) नया उपयोगकर्ता लौटाएं($परिणाम); ) /** * उपयोगकर्ता को अधिकृत या पंजीकृत करें * @param स्ट्रिंग $ईमेल। उपयोगकर्ता ईमेल पता * @उपयोगकर्ता लौटाएं */ सार्वजनिक स्थैतिक फ़ंक्शन लॉगिनऑररजिस्टर($ईमेल)( // यदि ऐसा उपयोगकर्ता पहले से ही है मौजूद है, डेटाबेस में संग्रहीत निर्दिष्ट ईमेल पते से उपयोगकर्ता फ़ंक्शन का मान लौटाएं यदि (उपयोगकर्ता:: मौजूद है ($ ईमेल)) ( नया उपयोगकर्ता लौटाएं ($ ईमेल); ) // अन्यथा, डेटाबेस में एक नया उपयोगकर्ता बनाएं और निर्दिष्ट ईमेल से User::create फ़ंक्शन का मान लौटाएं User::create($email ); ) /** * एक नया उपयोगकर्ता बनाएं और डेटाबेस में सहेजें * @param string $email. उपयोगकर्ता का ईमेल पता * @वापसी उपयोगकर्ता */ निजी स्थैतिक फ़ंक्शन बनाएं ($ईमेल)( // एक नया उपयोगकर्ता लिखें और इन मानों से उपयोगकर्ता फ़ंक्शन का परिणाम लौटाएं $result = ORM::for_table("reg_users")- >बनाएं(); $परिणाम->ईमेल = $ईमेल; $परिणाम->सहेजें(); नया उपयोगकर्ता लौटाएं($परिणाम); ) /** * जांचें कि क्या ऐसा उपयोगकर्ता डेटाबेस में मौजूद है और बूलियन मान लौटाएं वेरिएबल * @param स्ट्रिंग $email. उपयोगकर्ता ईमेल पता * @रिटर्न बूलियन */ सार्वजनिक स्थैतिक फ़ंक्शन मौजूद है ($ ईमेल) ( // क्या उपयोगकर्ता डेटाबेस में मौजूद है? $ परिणाम = ORM::for_table ("reg_users") -> कहाँ ("ईमेल", $ ईमेल ) ->गिनती(); वापसी $परिणाम == 1; ) /** * एक नया उपयोगकर्ता ऑब्जेक्ट बनाएं * @param उदाहरण $param ORM, आईडी, ईमेल या 0 * @वापसी उपयोगकर्ता */ सार्वजनिक फ़ंक्शन __construct($param = शून्य) ( if($param इंस्टेंसऑफ ORM)( // ORM चेक पास हो गया $this->orm = $param; ) अन्यथा if(is_string($param))( // ईमेल चेक पास हो गया $this->orm = ORM:: for_table ("reg_users") ->where("email", $param) ->find_one(); ) else( $id = 0; if(is_numeric($param))( // वेरिएबल $param का मान है उपयोगकर्ता पहचानकर्ता को पारित $id = $param; ) else if(isset($_SESSION["loginid"]))( // अन्यथा, सत्र देखें $id = $_SESSION["loginid"]; ) $this->orm = ORM::for_table( "reg_users") ->where("id", $id) ->find_one(); ) ) /** * एक नया SHA1 प्राधिकरण टोकन जेनरेट करें, इसे डेटाबेस में लिखें और इसका मान लौटाएं * @रिटर्न स्ट्रिंग */ सार्वजनिक फ़ंक्शन जेनरेटटोकन()( // अधिकृत उपयोगकर्ता के लिए एक टोकन जेनरेट करें और इसे डेटाबेस में सहेजें $टोकन = sha1($this->email.time().rand(0, 1000000)); // डेटाबेस में टोकन सहेजें // और इसे चिह्नित करें ताकि यह केवल अगले 10 मिनट के लिए वैध हो $this->orm->set('token', $token); $this->orm->set_expr("टोकन_वैधता", "ADDTIME(NOW(),"0:10")"); $this->orm->save(); $टोकन लौटाएँ; ) /** * उपयोगकर्ता को अधिकृत करें * @return void */ सार्वजनिक फ़ंक्शन लॉगिन())( // उपयोगकर्ता को लॉग इन के रूप में चिह्नित करें $_SESSION["loginid"] = $this->orm->id; // अपडेट करें अंतिम_लॉगिन डेटाबेस फ़ील्ड का मान $this->orm->set_expr("last_login", "NOW()"); $this->orm->save(); ) /** * सत्र को नष्ट करें और उपयोगकर्ता को लॉग आउट करें * @return void */ सार्वजनिक फ़ंक्शन लॉगआउट ()( $_SESSION = array(); unset($_SESSION); ) /** * जांचें कि क्या उपयोगकर्ता लॉग इन है * @return बूलियन */ सार्वजनिक फ़ंक्शन loggedIn())( return isset($this->orm->id) && $_SESSION["loginid"] == $this->orm->id; ) /** * जांचता है कि उपयोगकर्ता प्रशासक है या नहीं * @return boolean */ public फ़ंक्शन isAdmin())( return $this->rank() = = "administrator"; ) /** * उपयोगकर्ता प्रकार ढूंढें, या तो व्यवस्थापक या नियमित हो सकता है * @return string */ सार्वजनिक फ़ंक्शन रैंक())( यदि ($this->orm->रैंक == 1)( रिटर्न "एडमिनिस्ट्रेटर" "; ) रिटर्न "रेगुलर"; ) /** * वह विधि जो आपको उपयोगकर्ता की निजी जानकारी को * उपयोगकर्ता ऑब्जेक्ट के गुणों के रूप में प्राप्त करने की अनुमति देती है * @ परम स्ट्रिंग $key उस प्रॉपर्टी का नाम जिसे एक्सेस मिलता है * @return Mixed */ public function __get($key)( if(isset($this->orm->$key))( return $this->orm-> $कुंजी; ) शून्य वापसी; ) )

टोकन SHA1 एल्गोरिदम का उपयोग करके उत्पन्न किए जाते हैं और डेटाबेस में संग्रहीत किए जाते हैं। मैं टोकन की वैधता के लिए 10 मिनट की समय सीमा निर्धारित करने के लिए MySQL के टाइमिंग फ़ंक्शन का उपयोग कर रहा हूं।

जब कोई टोकन मान्य किया जाता है, तो हम सीधे हैंडलर को बताते हैं कि हम केवल उन टोकन पर विचार कर रहे हैं जो अभी तक समाप्त नहीं हुए हैं, जो टोकन_वैलिडिटी कॉलम में संग्रहीत हैं।

कृपया ध्यान दें कि मैं जादुई विधि का उपयोग कर रहा हूं __पानाउपयोगकर्ता ऑब्जेक्ट के गुणों तक पहुंच को रोकने के लिए फ़ाइल के अंत में डॉक्स लाइब्रेरी।

इसके लिए धन्यवाद, $user->email, $user->टोकन आदि गुणों के कारण डेटाबेस में संग्रहीत जानकारी तक पहुंचना संभव हो जाता है। अगले कोड खंड में, हम देखेंगे कि इन वर्गों को एक उदाहरण के रूप में कैसे उपयोग किया जाए। .


संरक्षित पृष्ठ

एक अन्य फ़ाइल जो उपयोगी और आवश्यक कार्यक्षमता संग्रहीत करती है, वह function.php फ़ाइल है। कई तथाकथित सहायक-सहायक फ़ंक्शन हैं जो आपको अन्य फ़ाइलों में क्लीनर और अधिक पठनीय कोड बनाने की अनुमति देते हैं।

फ़ंक्शन.php

फ़ंक्शन भेजें_ईमेल($से, $से, $विषय, $संदेश)( // सहायक जो ईमेल भेजता है $हेडर = "एमआईएमई-संस्करण: 1.0" . "\r\n"; $हेडर .= "सामग्री-प्रकार: पाठ /plain; charset=utf-8" . "\r\n"; $headers .= "From: ".$from . "\r\n"; रिटर्न मेल($to, $subject, $message, $headers ); ) फ़ंक्शन get_page_url())( // PHP फ़ाइल का URL निर्धारित करें $url = "http"।(empty($_SERVER["HTTPS"])?"":"s")।"://" .$_SERVER ["SERVER_NAME"]; if(isset($_SERVER["REQUEST_URI"]) && $_SERVER["REQUEST_URI"] != "")( $url.= $_SERVER["REQUEST_URI"]; ) अन्यथा( $url. = $_SERVER["PATH_INFO"]; ) रिटर्न $url; ) फ़ंक्शन रेट_लिमिट($ip, $limit_hour = 20, $limit_10_min = 10)( // इस आईपी पते पर अंतिम घंटे में लॉगिन प्रयासों की संख्या $ count_hour = ORM: :for_table("reg_login_attempt") ->where("ip", sprintf("%u", ip2long($ip))) ->where_raw("ts > SUBTIME(NOW(),"1:00 ")") ->गिनती(); // इस आईपी पते पर पिछले 10 मिनट में लॉगिन प्रयासों की संख्या $count_10_min = ORM::for_table("reg_login_attempt") ->where("ip", sprintf("%u ", ip2long($ ip))) ->where_raw("ts > SUBTIME(NOW(),"0:10")) ->count(); if($count_hour > $limit_hour || $count_10_min > $limit_10_min)( नया अपवाद फेंकें ("बहुत सारे लॉगिन प्रयास!"); ) ) फ़ंक्शन रेट_लिमिट_टिक($ip, $email)( // तालिका में एक नया रिकॉर्ड बनाएं यह लॉगिन प्रयासों की संख्या की गणना करता है $login_attempt = ORM::for_table("reg_login_attempt")->create(); $login_attempt->email = $email; $login_attempt->ip = sprintf("%u", ip2long($ip )); $login_attempt->save(); ) फ़ंक्शन रीडायरेक्ट($url)( हेडर("स्थान: $url"); बाहर निकलें; )

कार्य कीमत सीमाऔर रेट_लिमिट_टिकपहले प्रयास के बाद से बीते समय में प्राधिकरण प्रयासों की संख्या की निगरानी करें। लॉगिन प्रयास डेटाबेस में reg_login_attempt कॉलम में दर्ज किया गया है। जब प्रपत्र डेटा संसाधित और सबमिट किया जाता है तो इन फ़ंक्शन को कॉल किया जाता है जैसा कि आप निम्नलिखित कोड स्निपेट से देख सकते हैं।

नीचे दिया गया कोड Index.php फ़ाइल से लिया गया है और यह फ़ॉर्म सबमिशन को संभालता है। यह एक JSON प्रतिक्रिया देता है, जिसे बदले में jQuery द्वारा एसेट/जेएस/स्क्रिप्ट.जेएस फ़ाइल में संसाधित किया जाता है जिसे हमने पहले देखा था।

Index.php

प्रयास करें( if(!empty($_POST) && isset($_SERVER["HTTP_X_REQUESTED_WITH"]))( // एक JSON हेडर हेडर आउटपुट करें ("सामग्री-प्रकार: एप्लिकेशन/json"); // क्या यह ईमेल पता मान्य है यदि (!isset($_POST["email"]) || !filter_var($_POST["email"], FILTER_VALIDATE_EMAIL))( नया अपवाद फेंकें ("कृपया एक वैध ईमेल दर्ज करें।"); ) // जाँच करें। उपयोगकर्ता को लॉग इन करने की अनुमति है, क्या उसने अनुमत कनेक्शनों की संख्या पार कर ली है? (अधिक जानकारी के लिए function.php फ़ाइल) रेट_लिमिट($_SERVER["REMOTE_ADDR"]); // इस लॉगिन प्रयास को लॉग करें रेट_लिमिट_टिक($_SERVER["REMOTE_ADDR"] , $ _POST["email"]); // उपयोगकर्ता को एक ईमेल भेजें $message = ""; $email = $_POST["email"]; $subject = "आपका लॉगिन लिंक"; if(!User:: मौजूद है($ईमेल) )( $विषय = "पंजीकरण करने के लिए धन्यवाद!"; $संदेश = "हमारी साइट पर पंजीकरण करने के लिए धन्यवाद!\n\n"; ) // उपयोगकर्ता को अधिकृत या पंजीकृत करने का प्रयास $उपयोगकर्ता = उपयोगकर्ता ::loginOrRegister($_POST[ "email"]); $message.= "आप इस URL से लॉगइन कर सकते हैं:\n"; $message.= get_page_url()."?tkn=".$user->generateToken()."\n\n"; $message.= "लिंक 10 मिनट के बाद स्वचालित रूप से समाप्त हो जाएगा।"; $परिणाम = भेजें_ईमेल($सेमेल, $_POST["ईमेल"], $विषय, $संदेश); if(!$result)( नया अपवाद फेंकें("आपका ईमेल भेजने में त्रुटि हुई थी। कृपया पुनः प्रयास करें।"); )die(json_encode(array("message" => "धन्यवाद! हमने\"एक लिंक भेजा है अपने इनबॉक्स में। अपना स्पैम फ़ोल्डर भी जांचें। ))); )

सफल लॉगिन/पंजीकरण के बाद, उपरोक्त कोड उपयोगकर्ता को एक लॉगिन लिंक भेजेगा। टोकन उपलब्ध हो जाता है क्योंकि इसे विधि द्वारा जेनरेट किए गए लिंक में एक वेरिएबल के रूप में पारित किया जाता है $_प्राप्त करेंटीकेएन मार्कर के साथ

Index.php

यदि(isset($_GET["tkn"]))( // क्या यह टोकन प्राधिकरण के लिए वैध है? $user = User::findByToken($_GET["tkn"]); if($user)( // हाँ , है। एक सुरक्षित पेज पर रीडायरेक्ट करें $user->login(); रीडायरेक्ट('protected.php'); ) // नहीं, टोकन मान्य नहीं है। एक प्राधिकरण/पंजीकरण फॉर्म रीडायरेक्ट वाले पेज पर रीडायरेक्ट करें('index. php "); )

$उपयोगकर्ता->लॉगिन()

सत्र के लिए आवश्यक वैरिएबल बनाएगा, ताकि साइट के बाद के पृष्ठों को देखने वाला उपयोगकर्ता हर समय अधिकृत बना रहे।

सिस्टम से बाहर निकलने के लिए फ़ंक्शन की प्रोसेसिंग को इसी तरह से व्यवस्थित किया जाता है।

Index.php

यदि(जारी($_GET["लॉगआउट"]))( $उपयोगकर्ता = नया उपयोगकर्ता(); यदि($उपयोगकर्ता->लॉगइन())( $उपयोगकर्ता->लॉगआउट(); ) रीडायरेक्ट("index.php") ; )

कोड के अंत में, मैंने फिर से Index.php पर रीडायरेक्ट सेट किया, इसलिए पैरामीटर ?लॉगआउट=1यूआरएल के माध्यम से प्रेषित करना आवश्यक नहीं है।

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

Index.php

$उपयोगकर्ता = नया उपयोगकर्ता(); अगर($user->लॉगइन())(रीडायरेक्ट("protected.php"); )

अंत में, यहां कोड का एक टुकड़ा है जो आपको अपनी साइट के पृष्ठों की सुरक्षा करने और प्राधिकरण के बाद ही इसे पहुंच योग्य बनाने की अनुमति देता है।

संरक्षित.php

// अपनी साइट पर प्रत्येक पृष्ठ की सुरक्षा के लिए, एक main.php फ़ाइल // शामिल करें और एक नया उपयोगकर्ता ऑब्जेक्ट बनाएं। यह कितना आसान है! require_once "includes/main.php"; $उपयोगकर्ता = नया उपयोगकर्ता(); अगर(!$user->लॉगइन())(रीडायरेक्ट("index.php"); )

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

इको "आपका ईमेल: ".$user->ईमेल; इको "आपकी रैंक: ".$user->रैंक();

तरीका पद()यहां उपयोग किया जाता है क्योंकि डेटाबेस आमतौर पर संख्याओं को संग्रहीत करता है (नियमित उपयोगकर्ता के लिए 0, व्यवस्थापक के लिए 1) और हमें इस डेटा को उन स्थितियों में परिवर्तित करने की आवश्यकता होती है जिनसे वे संबंधित हैं, जिसमें यह विधि हमारी मदद करती है।

एक नियमित उपयोगकर्ता को प्रशासक बनाने के लिए, बस phpMyAdmin (या कोई अन्य प्रोग्राम जो आपको डेटाबेस प्रबंधित करने की अनुमति देता है) के माध्यम से उपयोगकर्ता प्रविष्टि को संपादित करें। व्यवस्थापक स्थिति कोई विशेषाधिकार नहीं देती है; इस उदाहरण में, पृष्ठ प्रदर्शित करेगा कि आप एक व्यवस्थापक हैं - और बस इतना ही।

लेकिन इसके साथ क्या करना है यह आपके विवेक पर छोड़ दिया गया है; आप स्वयं कोड लिख और बना सकते हैं जो प्रशासकों के लिए कुछ विशेषाधिकार और क्षमताएं निर्धारित करता है।

किए गए!

हमने इस अविश्वसनीय सुपर अर्ध सरल आकार का काम पूरा कर लिया है! आप इसे अपनी PHP साइटों में उपयोग कर सकते हैं, यह काफी सरल है। आप इसे अपने लिए संशोधित भी कर सकते हैं और जैसा चाहें वैसा बना सकते हैं।

सामग्री विशेष रूप से वेबसाइट के लिए डेनिस मैल्शोक द्वारा तैयार की गई थी

पी.एस. क्या आप PHP और OOP में महारत हासिल करना चाहते हैं? वेबसाइट निर्माण के विभिन्न पहलुओं पर प्रीमियम पाठों पर ध्यान दें, जिसमें PHP में प्रोग्रामिंग भी शामिल है, साथ ही OOP का उपयोग करके PHP में अपना स्वयं का सीएमएस सिस्टम बनाने पर एक निःशुल्क पाठ्यक्रम भी शामिल है:

क्या आपको सामग्री पसंद आई और आप मुझे धन्यवाद देना चाहते हैं?
बस अपने दोस्तों और सहकर्मियों के साथ साझा करें!


आज हम लोकप्रिय सीएमएस जूमला में एक महत्वपूर्ण 1-दिवसीय भेद्यता के शोषण को देखेंगे, जो अक्टूबर के अंत में इंटरनेट पर फैल गया था। हम CVE-2016-8869, CVE-2016-8870 और CVE-2016-9081 नंबरों वाली कमजोरियों के बारे में बात करेंगे। ये तीनों कोड के एक टुकड़े से आते हैं जो पांच लंबे वर्षों तक ढांचे की गहराई में पड़ा रहा, पंखों में इंतजार कर रहा था, और फिर मुक्त हो गया और अपने साथ अराजकता, हैक की गई साइटों और इस जूमला के निर्दोष उपयोगकर्ताओं के आँसू लेकर आया। केवल सबसे बहादुर और साहसी डेवलपर्स, जिनकी आंखें मॉनिटर की रोशनी से लाल हो गई हैं, और जिनके कीबोर्ड ब्रेड के टुकड़ों से अटे पड़े हैं, उग्र बुरी आत्माओं को चुनौती देने और सुधार की वेदी पर अपना सिर रखने में सक्षम थे।

चेतावनी सभी जानकारी केवल सूचनात्मक उद्देश्यों के लिए प्रदान की गई है। इस लेख की सामग्री से होने वाले किसी भी संभावित नुकसान के लिए न तो संपादक और न ही लेखक जिम्मेदार हैं। जहां से यह सब शुरू हुआ

6 अक्टूबर 2016 को, डेमिस पाल्मा ने स्टैक एक्सचेंज पर एक विषय बनाया जिसमें उन्होंने पूछा: क्यों, वास्तव में, जूमला संस्करण 3.6 में एक ही नाम रजिस्टर() के साथ उपयोगकर्ताओं को पंजीकृत करने के दो तरीके हैं? पहला UserControllerRegistration कंट्रोलर में है और दूसरा UsersControllerUser कंट्रोलर में है। डेमिस जानना चाहता था कि क्या UsersControllerUser::register() पद्धति का उपयोग कहीं किया गया था, या क्या यह पुराने तर्क से बचा हुआ एक विकासवादी कालवाद था। उनकी चिंता यह थी कि भले ही इस पद्धति का उपयोग किसी भी दृष्टिकोण से नहीं किया जाता है, फिर भी इसे एक गढ़ी गई क्वेरी द्वारा बुलाया जा सकता है। जिस पर मुझे इटोक्टोपस उपनाम के तहत एक डेवलपर से प्रतिक्रिया मिली, जिसने पुष्टि की: समस्या वास्तव में मौजूद है। और जूमला डेवलपर्स को एक रिपोर्ट भेजी।

तब घटनाएँ सबसे तेजी से विकसित हुईं। 18 अक्टूबर को, जूमला डेवलपर्स ने डेमिस की रिपोर्ट स्वीकार कर ली, जिसने उस समय तक एक पीओसी का मसौदा तैयार कर लिया था जो उपयोगकर्ता पंजीकरण की अनुमति देगा। उन्होंने अपनी वेबसाइट पर एक नोट प्रकाशित किया, जहां उन्होंने सामान्य शब्दों में अपनी समस्या और इस मामले पर अपने विचारों के बारे में बात की। उसी दिन, जूमला 3.6.3 का एक नया संस्करण जारी किया गया है, जिसमें अभी भी असुरक्षित कोड शामिल है।

इसके बाद, डेविड टैम्पेलिनी एक साधारण उपयोगकर्ता को नहीं, बल्कि एक प्रशासक को पंजीकृत करने के बिंदु पर बग को घुमाता है। और 21 अक्टूबर को जूमला सुरक्षा टीम के पास एक नया मामला आता है। इसमें पहले से ही विशेषाधिकार बढ़ाने की बात कही गई है. उसी दिन, जूमला वेबसाइट पर एक घोषणा दिखाई देती है कि मंगलवार, 25 अक्टूबर को सीरियल नंबर 3.6.3 के साथ अगला संस्करण जारी किया जाएगा, जो सिस्टम कर्नेल में एक महत्वपूर्ण भेद्यता को ठीक करता है।

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

इसके सामने आने के बाद, कई इच्छुक व्यक्ति डेवलपर समुदाय में शामिल हो जाते हैं - वे भेद्यता को बढ़ावा देना और कारनामे तैयार करना शुरू कर देते हैं।

27 अक्टूबर को, शोधकर्ता हैरी रॉबर्ट्स ने Xiphos रिसर्च रिपॉजिटरी में एक तैयार-निर्मित शोषण अपलोड किया है जो एक कमजोर सीएमएस वाले सर्वर पर एक PHP फ़ाइल अपलोड कर सकता है।

विवरण

खैर, पृष्ठभूमि खत्म हो गई है, आइए सबसे दिलचस्प भाग पर चलते हैं - भेद्यता का विश्लेषण। मैंने जूमला 3.6.3 को एक परीक्षण संस्करण के रूप में स्थापित किया है, इसलिए सभी पंक्ति संख्याएँ इस संस्करण के लिए प्रासंगिक होंगी। और फ़ाइलों के सभी पथ जो आप नीचे देखेंगे, स्थापित सीएमएस की जड़ के सापेक्ष इंगित किए जाएंगे।

डेमिस पाल्मा की खोज के लिए धन्यवाद, हम जानते हैं कि दो विधियाँ हैं जो सिस्टम में उपयोगकर्ता पंजीकरण करती हैं। पहला सीएमएस द्वारा उपयोग किया जाता है और फ़ाइल /components/com_users/controllers/registration.php:108 में स्थित होता है। दूसरा (जिसे हमें कॉल करने की आवश्यकता होगी) /components/com_users/controllers/user.php:293 में रहता है। आइए इस पर करीब से नज़र डालें।

286: /** 287: * उपयोगकर्ता को पंजीकृत करने की विधि। 288: * 289: * @रिटर्न बूलियन 290: * 291: * @सिंस 1.6 292: */ 293: पब्लिक फंक्शन रजिस्टर() 294: (295: JSession::checkToken("post") या jexit(JText::_ ("JINVALID_TOKEN")); ... 300: // फॉर्म डेटा प्राप्त करें। 301: $ डेटा = $ यह-> इनपुट-> पोस्ट-> प्राप्त करें ("उपयोगकर्ता", सरणी(), "सरणी"); । .. 315: $रिटर्न = $मॉडल->वैलिडेट($फॉर्म, $डेटा); 316: 317: // त्रुटियों की जांच करें। 318: यदि ($रिटर्न === गलत) 319: (...345: / / पंजीकरण समाप्त करें। 346: $रिटर्न = $मॉडल->रजिस्टर($डेटा);

यहाँ मैंने केवल दिलचस्प पंक्तियाँ छोड़ी हैं। असुरक्षित विधि का पूर्ण संस्करण जूमला रिपॉजिटरी में देखा जा सकता है।

आइए जानें कि सामान्य उपयोगकर्ता पंजीकरण के दौरान क्या होता है: कौन सा डेटा भेजा जाता है और इसे कैसे संसाधित किया जाता है। यदि सेटिंग्स में उपयोगकर्ता पंजीकरण सक्षम है, तो फॉर्म http://joomla.local/index.php/component/users/?view=registration पर पाया जा सकता है।


एक वैध उपयोगकर्ता पंजीकरण अनुरोध निम्नलिखित स्क्रीनशॉट जैसा दिखता है।


com_users घटक उपयोगकर्ताओं के साथ काम करने के लिए जिम्मेदार है। अनुरोध में कार्य पैरामीटर पर ध्यान दें. इसका प्रारूप $controller.$method है। आइए फ़ाइल संरचना को देखें।

नियंत्रक फ़ोल्डर में स्क्रिप्ट के नाम, बुलाए गए नियंत्रकों के नाम से मेल खाते हैं। चूंकि हमारे अनुरोध में अब $controller = "registration" है, इसलिए रजिस्ट्रेशन.php फ़ाइल और इसकी रजिस्टर() विधि को कॉल किया जाएगा।

ध्यान दें, प्रश्न: पंजीकरण प्रसंस्करण को कोड में कमजोर स्थान पर कैसे स्थानांतरित किया जाए? आपने संभवतः इसका अनुमान पहले ही लगा लिया होगा। कमजोर और वास्तविक तरीकों के नाम समान हैं (रजिस्टर), इसलिए हमें केवल बुलाए गए नियंत्रक का नाम बदलने की जरूरत है। हमारा असुरक्षित नियंत्रक कहाँ स्थित है? यह सही है, user.php फ़ाइल में। यह $controller = "user" निकला। सब कुछ एक साथ रखने पर हमें Task = user.register मिलता है। अब पंजीकरण अनुरोध को उस विधि द्वारा संसाधित किया जाता है जिसकी हमें आवश्यकता है।


दूसरी चीज़ जो हमें करने की ज़रूरत है वह है डेटा को सही प्रारूप में भेजना। यहां सब कुछ सरल है. वैध रजिस्टर() हमसे jform नामक एक सरणी की अपेक्षा करता है, जिसमें हम पंजीकरण डेटा - नाम, लॉगिन, पासवर्ड, ईमेल पास करते हैं (अनुरोध के साथ स्क्रीनशॉट देखें)।

  • /components/com_users/controllers/registration.php: 124: // उपयोगकर्ता डेटा प्राप्त करें। 125: $requestData = $this->input->post->get("jform", array(), "array");

हमारे क्लाइंट को यह डेटा उपयोगकर्ता नामक सरणी से प्राप्त होता है।

  • /components/com_users/controllers/user.php: 301: // फॉर्म डेटा प्राप्त करें। 302: $डेटा = $यह->इनपुट->पोस्ट->प्राप्त करें("उपयोगकर्ता", सरणी(), "सरणी");

इसलिए, हम अनुरोध में सभी मापदंडों के नाम jfrom से उपयोगकर्ता में बदल देते हैं।

हमारा तीसरा कदम एक वैध सीएसआरएफ टोकन ढूंढना है, क्योंकि इसके बिना कोई पंजीकरण नहीं होगा।

  • /components/com_users/controllers/user.php: 296: JSession::checkToken("post") या jexit(JText::_("JINVALID_TOKEN"));

यह MD5 हैश जैसा दिखता है, और आप इसे, उदाहरण के लिए, साइट /index.php/component/users/?view=login पर प्राधिकरण फॉर्म से ले सकते हैं।


अब आप वांछित विधि का उपयोग करके उपयोगकर्ता बना सकते हैं। यदि सब कुछ काम कर गया, तो बधाई हो - आपने CVE-2016-8870 "नए उपयोगकर्ताओं को पंजीकृत करने के लिए अनुपलब्ध अनुमति जांच" भेद्यता का फायदा उठाया।

UsersControllerRegistration नियंत्रक से "कार्यशील" रजिस्टर() विधि में यह ऐसा दिखता है:

  • /components/com_users/controllers/registration.php: 113: // यदि पंजीकरण अक्षम है - लॉगिन पृष्ठ पर रीडायरेक्ट करें। 114: यदि (JComponentHelper::getParams("com_users")->get("allowUserRegistration") == 0) 115: ( 116: $this->setRedirect(JRoute::_("index.php?option=com_users&view= लॉगिन", गलत)); 117: 118: गलत वापसी; 119: )

और इसलिए असुरक्षित में:

  • /components/com_users/controllers/user.php:

हाँ, बिलकुल नहीं.

दूसरी, कहीं अधिक गंभीर समस्या को समझने के लिए, आइए अपने द्वारा बनाया गया अनुरोध भेजें और देखें कि इसे कोड के विभिन्न भागों में कैसे निष्पादित किया जाता है। यहां वह हिस्सा है जो कार्यकर्ता विधि में उपयोगकर्ता द्वारा सबमिट किए गए डेटा को सत्यापित करने के लिए जिम्मेदार है:

निरंतरता केवल सदस्यों के लिए उपलब्ध है विकल्प 1। साइट पर सभी सामग्रियों को पढ़ने के लिए "साइट" समुदाय में शामिल हों

निर्दिष्ट अवधि के भीतर समुदाय में सदस्यता आपको सभी हैकर सामग्रियों तक पहुंच प्रदान करेगी, आपकी व्यक्तिगत संचयी छूट बढ़ाएगी और आपको एक पेशेवर Xakep स्कोर रेटिंग जमा करने की अनुमति देगी!

मैंने यह नोट लिखने का निर्णय इसलिए लिया क्योंकि मैं प्रश्नोत्तरी पर एक ही बात का 100,500 बार उत्तर देकर थक गया हूँ।

कई नौसिखिया वेब प्रोग्रामर को देर-सबेर अपनी वेबसाइट में मानव-पठनीय लिंक (एचयूआर) पेश करने के कार्य का सामना करना पड़ता है। सीएनसी के कार्यान्वयन से पहले, सभी लिंक /myscript.php या यहां तक ​​कि /myfolder/myfolder2/myscript3.php जैसे दिखते थे, जिसे याद रखना मुश्किल है और SEO के लिए और भी बुरा है। सीएनसी के कार्यान्वयन के बाद, लिंक /statiya-o-php या यहां तक ​​कि सिरिलिक /article-o-php में भी रूप ले लेते हैं।

SEO की बात हो रही है. मानव-पठनीय लिंक वास्तव में आसान याद रखने के लिए नहीं, बल्कि मुख्य रूप से साइट की अनुक्रमणिका को बढ़ाने के लिए आविष्कार किए गए थे, क्योंकि खोज क्वेरी और यूआरएल के हिस्से का संयोग खोज रैंकिंग में अच्छा लाभ देता है।

एक नौसिखिया PHP प्रोग्रामर के विकास को चरणों के निम्नलिखित अनुक्रम में व्यक्त किया जा सकता है:

  • सादे-PHP कोड को अलग-अलग फ़ाइलों में रखना और /myfolder/myscript.php जैसे लिंक के माध्यम से इन फ़ाइलों तक पहुँचना
  • यह समझना कि सभी स्क्रिप्टों में एक महत्वपूर्ण भूमिका समान है (उदाहरण के लिए, डेटाबेस से कनेक्शन बनाना, कॉन्फ़िगरेशन पढ़ना, सत्र शुरू करना, आदि) और, परिणामस्वरूप, एक सामान्य प्रारंभिक "प्रविष्टि" बिंदु बनाना, कुछ स्क्रिप्ट जो सभी अनुरोधों को स्वीकार करता है, और फिर चुनता है कि कौन सी आंतरिक स्क्रिप्ट कनेक्ट होती है। आमतौर पर इस स्क्रिप्ट को Index.php नाम दिया जाता है और यह मूल में स्थित होती है, जिसके परिणामस्वरूप सभी अनुरोध (उर्फ URL) इस तरह दिखते हैं: /index.php?com=myaction&com2=mysubaction
  • एक राउटर को लागू करने और मानव-पठनीय लिंक में परिवर्तन की आवश्यकता।
  • मैं ध्यान देता हूं कि बिंदु 2 और 3 के बीच, अधिकांश प्रोग्रामर एक स्पष्ट गलती करते हैं। अगर मैं इसे लगभग 95% प्रोग्रामर का मूल्य कहूं तो गलत नहीं होगा। यहां तक ​​कि अधिकांश प्रसिद्ध फ़्रेमवर्क में भी यह त्रुटि होती है। और इसमें निम्नलिखित शामिल हैं.

    लिंक को संसाधित करने के मौलिक रूप से नए तरीके को लागू करने के बजाय, .htaccess पर आधारित "पैच और रीडायरेक्ट" की अवधारणा गलती से बनाई गई है, जिसमें mod_rewrite का उपयोग करके कई रीडायरेक्ट नियम बनाना शामिल है। ये पंक्तियाँ URL की तुलना कुछ रेगुलर एक्सप्रेशन से करती हैं और, यदि कोई मेल है, तो URL से निकाले गए मानों को GET वेरिएबल्स में धकेलती हैं, बाद में उसी Index.php को कॉल करती हैं।

    #गलत सीएनसी विधि रीराइटइंजिन रीराइटरूल पर ^\/users\/(.+)$ Index.php?module=users&id=$1 #....इसी तरह के और भी कई नियम...

    इस अवधारणा के कई नुकसान हैं. उनमें से एक नियम बनाने में कठिनाई है, नियम जोड़ते समय मानवीय त्रुटियों का एक बड़ा प्रतिशत जिनका पता लगाना मुश्किल होता है, लेकिन वे 500 सर्वर त्रुटि का कारण बनते हैं।

    एक और कमी यह है कि इसे अक्सर सर्वर कॉन्फ़िगरेशन के आधार पर संपादित किया जाता है, जो अपने आप में बकवास है। और यदि अपाचे में कॉन्फ़िगरेशन को .htaccess का उपयोग करके "पैच" किया जा सकता है, तो लोकप्रिय nginx में ऐसा कोई विकल्प नहीं है, सब कुछ सिस्टम ज़ोन में एक सामान्य कॉन्फ़िगरेशन फ़ाइल में स्थित है।

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

    नीचे प्रस्तावित विधि इन सभी नुकसानों को दूर करती है। इसका उपयोग पहले से ही बड़ी संख्या में आधुनिक ढाँचों में किया जा रहा है।

    लब्बोलुआब यह है कि प्रारंभिक अनुरोध हमेशा $_SERVER['REQUEST_URI'] वेरिएबल में संग्रहीत किया जाता है, यानी, इसे इंडेक्स.php के अंदर पढ़ा जा सकता है और सभी त्रुटि प्रबंधन, गतिशील रीडायरेक्ट इत्यादि के साथ PHP का उपयोग करके स्ट्रिंग के रूप में पार्स किया जा सकता है।

    इस स्थिति में, आप कॉन्फ़िगरेशन फ़ाइल में केवल एक स्थिर नियम बना सकते हैं, जो गैर-मौजूद फ़ाइलों या फ़ोल्डरों के सभी अनुरोधों को Index.php पर रीडायरेक्ट कर देगा।

    RewriteEngine On RewriteCond %(REQUEST_FILENAME) !-f #यदि फ़ाइल मौजूद नहीं है तो RewriteCond %(REQUEST_FILENAME) !-d #और यदि फ़ोल्डर मौजूद नहीं है तो RewriteRule ^.*$ Index.php

    इसके अलावा, इस नियम को .htaccess और मुख्य अपाचे कॉन्फ़िगरेशन फ़ाइल दोनों में रखा जा सकता है।

    Nginx के लिए, संबंधित नियम इस तरह दिखेगा:

    स्थान / ( यदि (!-e $request_filename) ( पुनः लिखें ^/(.*)$ /index.php अंतिम; ) )

    यह आसान है।

    अब आइए Index.php में PHP कोड के एक टुकड़े को देखें, जो लिंक का विश्लेषण करता है और तय करता है कि कौन सी स्क्रिप्ट चलानी है।

    /भाग1/भाग2/भाग3

    पहली बात जो दिमाग में आती है वह है इसे विस्फोट ('/', $uri) का उपयोग करके तोड़ना और स्विच/केस के आधार पर एक जटिल राउटर बनाना जो अनुरोध के प्रत्येक टुकड़े का विश्लेषण करता है। ऐसा मत करो! यह जटिल है और अंततः कोड को भयानक रूप से समझ से बाहर और गैर-कॉन्फ़िगर करने योग्य बना देता है!

    मैं एक अधिक संक्षिप्त तरीका सुझाता हूँ। बेहतर होगा कि इसका वर्णन शब्दों में न किया जाए, बल्कि तुरंत कोड दिखाया जाए।


    4. आपको एक ही डेटाबेस में एक तालिका जोड़ने की आवश्यकता है। यह उन आईपी पतों को संग्रहीत करेगा जिनसे लॉग इन करते समय त्रुटियां हुईं। इस तरह हम उन लोगों तक पहुंच को सीमित कर सकते हैं जिन्होंने लगभग 15 मिनट तक लगातार तीन बार से अधिक गलतियाँ की हैं। मुझे लगता है कि पासवर्ड का चयन करने वाले प्रोग्रामों को लंबे समय तक छेड़छाड़ करनी होगी।
    आइए phpmyadmin पर जाएं और 3 फ़ील्ड के साथ एक नई तालिका बनाएं:


    आईपी ​​- आईपी पता.
    दिनांक - इस आईपी वाले उपयोगकर्ता के लिए पिछले 15 मिनट में असफल लॉगिन की तिथि। col - इस आईपी वाले उपयोगकर्ता के लिए पिछले 15 मिनट में त्रुटियों की संख्या।
    महान! हो गया, अब लॉगिन और पासवर्ड सत्यापन फ़ाइल को बदलते हैं, क्योंकि अब हमारा पासवर्ड एन्क्रिप्ट किया गया है। testreg.php खोलें और लॉगिन और पासवर्ड से रिक्त स्थान हटाने के अलावा सब कुछ हटा दें। आगे हम निम्नलिखित कोड जोड़ते हैं:

    //अतिरिक्त रिक्त स्थान हटा दें
    $लॉगिन = ट्रिम($लॉगिन);
    $पासवर्ड = ट्रिम($पासवर्ड);

    // एक नए से बदलें************************************************* *******
    // डेटाबेस से कनेक्ट करें
    include('bd.php');// bd.php फ़ाइल अन्य सभी फ़ोल्डरों के समान फ़ोल्डर में होनी चाहिए, यदि ऐसा नहीं है तो बस पथ बदलें
    // पासवर्ड चयन के लिए मिनी-चेक
    $ip=getenv('HTTP_X_FORWARDED_FOR');
    अगर (खाली($आईपी) || $आईपी=='अज्ञात'' ($आईपी=getenv('REMOTE_ADDR'); )//आईपी निकालें
    mysql_query ("ओशिबका से हटाएं जहां UNIX_TIMESTAMP() - UNIX_TIMESTAMP(दिनांक) > 900");//उन उपयोगकर्ताओं के आईपी पते हटाएं जिन्होंने 15 मिनट के बाद लॉग इन करते समय गलती की थी।
    $result = mysql_query('SELECT col FROM oshibka WHERE ip='$ip''',$db); // डेटाबेस से किसी दिए गए आईपी वाले उपयोगकर्ता के लिए पिछले 15 में असफल लॉगिन प्रयासों की संख्या प्राप्त करें
    $myrow = mysql_fetch_array($परिणाम);
    यदि ($myrow["col"] > 2) (
    //यदि दो से अधिक यानी तीन त्रुटियां हैं, तो हम एक संदेश जारी करते हैं।
    बाहर निकलें ("आपने अपना उपयोगकर्ता नाम या पासवर्ड 3 बार गलत तरीके से दर्ज किया है। कृपया दोबारा प्रयास करने से पहले 15 मिनट तक प्रतीक्षा करें।");
    }
    $password = md5($password);//पासवर्ड एन्क्रिप्ट करें
    $password = strrev($password);// विश्वसनीयता के लिए, रिवर्स जोड़ें
    $पासवर्ड = $पासवर्ड।"बी3पी6एफ";
    //आप अपनी रुचि के अनुसार अपने कुछ पात्र जोड़ सकते हैं, उदाहरण के लिए, "b3p6f" दर्ज करके। यदि यह पासवर्ड उसी md5 सर्वर पर बलपूर्वक हैक किया गया है, तो जाहिर तौर पर इससे कुछ भी अच्छा नहीं होगा। लेकिन मैं आपको सलाह देता हूं कि आप अन्य अक्षर भी रखें, शायद पंक्ति की शुरुआत में या बीच में।
    //इस मामले में, डेटाबेस में पासवर्ड फ़ील्ड की लंबाई बढ़ाना आवश्यक है। एन्क्रिप्टेड पासवर्ड बहुत बड़ा हो सकता है.

    $ परिणाम = mysql_query ("चुनें * उपयोगकर्ताओं से जहां लॉगिन = "$ लॉगिन" और पासवर्ड = "$ पासवर्ड"", $ db); // दर्ज किए गए लॉगिन और पासवर्ड के साथ डेटाबेस से उपयोगकर्ता के बारे में सभी डेटा पुनर्प्राप्त करें
    $myrow = mysql_fetch_array($परिणाम);
    यदि (खाली($myrow["id"]))
    {
    //यदि दर्ज लॉगिन और पासवर्ड वाला उपयोगकर्ता मौजूद नहीं है
    // हम एक रिकॉर्ड बनाते हैं कि यह आईपी लॉग इन नहीं कर सका।
    $select = mysql_query('ओशिबका से आईपी चुनें जहां आईपी='$आईपी'');
    $tmp = mysql_fetch_row($select);
    यदि ($ip == $tmp) (//जांचें कि उपयोगकर्ता "oshibka" तालिका में है या नहीं
    $result52 = mysql_query('ओशिबका से कॉल चुनें जहां आईपी='$आईपी'',$डीबी);
    $myrow52 = mysql_fetch_array($result52);
    $col = $myrow52 + 1;//एक और असफल लॉगिन प्रयास जोड़ें
    mysql_query('अद्यतन त्रुटि सेट col=$col,date=NOW() जहां ip='$ip'');
    }
    अन्य(
    mysql_query ("ओशिबका (आईपी, दिनांक, कॉलम) मानों में डालें ("$आईपी", अब(), "1")");
    //यदि पिछले 15 मिनट में कोई त्रुटि नहीं हुई, तो "ओशिबका" तालिका में एक नई प्रविष्टि डालें
    }

    बाहर निकलें ("क्षमा करें, आपके द्वारा दर्ज किया गया उपयोगकर्ता नाम या पासवर्ड गलत है।");
    }
    अन्य(
    nbsp; //यदि पासवर्ड मेल खाते हैं, तो हम उपयोगकर्ता के लिए एक सत्र लॉन्च करते हैं! आप उसे बधाई दे सकते हैं, वह अंदर आ गया!
    $_SESSION["पासवर्ड"]=$myrow["पासवर्ड"];
    $_SESSION["लॉगिन"]=$myrow["लॉगिन"];
    $_SESSION["id"]=$myrow["id"];//यह डेटा बहुत बार उपयोग किया जाता है, इसलिए लॉग इन किया हुआ उपयोगकर्ता "इसे अपने साथ रखेगा"

    // इसके बाद हम बाद में लॉगिन के लिए डेटा को कुकीज़ में सहेजते हैं।
    //ध्यान!!! यह अपने विवेक से करें क्योंकि डेटा बिना एन्क्रिप्शन के कुकीज़ में संग्रहीत होता है
    यदि ($_POST["सहेजें"] == 1) (
    //यदि उपयोगकर्ता चाहता है कि उसका डेटा बाद के लॉगिन के लिए सहेजा जाए, तो हम इसे उसके ब्राउज़र कुकीज़ में सहेजते हैं
    सेटकुकी("लॉगिन", $_POST["लॉगिन"], समय()+9999999);
    सेटकुकी("पासवर्ड", $_POST["पासवर्ड"], समय()+9999999);
    }}
    इको ""; // हम उपयोगकर्ता को मुख्य पृष्ठ पर पुनर्निर्देशित करते हैं, जहां हम उसे सफल लॉगिन के बारे में सूचित करेंगे
    ?>

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




    होम पेज


    होम पेज



    6. लॉग इन उपयोगकर्ताओं के लिए लॉग आउट करना संभव बनाना आवश्यक है। मुख्य पृष्ठ पर बाहर निकलने के लिए पहले से ही एक लिंक मौजूद था। लेकिन यह फ़ाइल अभी तक मौजूद नहीं है. तो आइए कोड के साथ एक नई एक्ज़िट.php फ़ाइल बनाएं:

    ठीक है अब सब ख़त्म हो गया! अपने स्वास्थ्य के लिए इसका आनंद लें! आपको कामयाबी मिले!

    पिछले पाठ में, हमने पता लगाया कि यात्रा टेम्पलेट में कौन से ब्लॉक शामिल होंगे, ताकि हम काम पर लग सकें। सबसे पहले, आइए दो फ़ोल्डर बनाएं:

    छवियाँ - इस फ़ोल्डर में टेम्पलेट डिज़ाइन करने के लिए उपयोग की जाने वाली कोई भी ग्राफ़िक फ़ाइलें होंगी। क्योंकि हमारे पास अभी तक कोई डिज़ाइन विकास नहीं है, तो किसी भी एक ग्राफ़िक फ़ाइल को इस फ़ोल्डर में छोड़ दें, अन्यथा जूमला टेम्पलेट स्थापित नहीं करेगा और फ़ोल्डर खाली होने पर एक त्रुटि देगा।

    ध्यान दें: टेम्प्लेट इमेज फ़ोल्डर में सामग्री ग्राफ़िक्स नहीं हैं!

    सीएसएस - इस फ़ोल्डर में कैस्केडिंग स्टाइल शीट फ़ाइलें होंगी। सबसे पहले, इसमें एक खाली template.css फ़ाइल रखें, जिसका उपयोग साइट तत्वों को विभिन्न डिज़ाइन शैलियाँ निर्दिष्ट करने के लिए किया जाएगा।

    इसके बाद, आप मुख्य फ़ाइल इंडेक्स.php बनाना शुरू कर सकते हैं, जो साइट तत्वों की दृश्य व्यवस्था निर्धारित करेगी और जूमला सीएमएस को बताएगी कि किस ब्लॉक में विभिन्न घटकों और मॉड्यूल को रखा जाए। फ़ाइल PHP और HTML का संयोजन है.

    कोड लिखते समय मैं हमेशा केवल मैक्रोमीडिया ड्रीमवीवर का उपयोग करता हूं। एक उत्कृष्ट कार्यक्रम, मैं शुरुआती लोगों को इसकी पुरजोर अनुशंसा करता हूं, क्योंकि... यदि आपने कोड पर काम करते समय कोई गलती की है, तो प्रोग्राम निश्चित रूप से आपकी गलती को उजागर करेगा।

    साइट पर आपको मैक्रोमीडिया ड्रीमविवर के लिए एक ट्यूटोरियल मिलेगा। यदि आप वेबसाइट विकसित करने जा रहे हैं, तो आपको त्रुटियों के बिना टेम्पलेट कोड संपादित करने के लिए, कम से कम प्रारंभिक स्तर पर, इस कार्यक्रम में महारत हासिल करनी चाहिए।

    पृष्ठ तत्वों (ब्लॉक) की स्थिति HTML कोड का उपयोग करके की जाती है; विशेष रूप से, हम DIV टैग का उपयोग करेंगे। लेकिन जिस तरह से हमारी साइट जूमला इंजन पर काम करेगी, यानी। यह डायनामिक होगा तो आपको PHP लैंग्वेज का भी इस्तेमाल करना होगा। इसकी मदद से, हम यह निर्धारित करेंगे कि आउटपुट मॉड्यूल के लिए स्थान किन ब्लॉकों में स्थित होंगे, और इन पदों को क्या कहा जाएगा, ब्लॉक ढह जाएंगे या नहीं। हम स्टाइल शीट को बाहरी फ़ाइलों से जोड़ेंगे, सामग्री भाषा, यह सेट करेंगे कि साइट का आकार कैसे बदलेगा, आदि।

    Index.php

    फ़ाइल शीर्ष लेख

    फ़ाइल हेडर में कई भाग होते हैं। PHP हेडर कोड का पहला भाग यह सुनिश्चित करना है कि सुरक्षा कारणों से फ़ाइल को सीधे एक्सेस नहीं किया जाता है।

    < ?php
    परिभाषित ("_JEXEC") या मरो;
    JHtml::_('behavior.framework' , true ) ;
    $app = JFactory::getApplication() ;
    ?>
    < ?php echo "< ?" ; ?>xml संस्करण = "1.0" एन्कोडिंग = "< ?php echo $this - >_चारसेट ?> " ?>

    DOCTYPE एक बहुत ही महत्वपूर्ण पैरामीटर है जिसके आधार पर ब्राउज़र यह तय करता है कि इस पेज को कैसे प्रस्तुत करना है और CSS की व्याख्या कैसे करनी है।

    < ! DOCTYPE html PUBLIC "- / / W3C/ / DTD XHTML 1.0 Strict/ / EN" "http:/ / www.w3.org/ TR/ xhtml1/ DTD/ xhtml1- strict.dtd" >

    निम्नलिखित स्निपेट वैश्विक कॉन्फ़िगरेशन से स्थापित भाषा को पुनः प्राप्त करता है।

    < html xmlns= "http:/ / www.w3.org/ 1999/ xhtml" xml:lang= "< ?php echo $this - >भाषा; ?> " लैंग ="< ?php echo $this - >भाषा; ?> " डीआईआर = "< ?php echo $this - >दिशा; ?> " >

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

    < head>
    < jdoc:include type= "head" / >

    निम्नलिखित हेडर पंक्तियों में मुख्य जूमला सीएसएस शैलियों के लिंक हैं।

    < link rel= "stylesheet" href= "< ?php echo $this - >बेसुरल ?> / टेम्प्लेट/ सिस्टम / सीएसएस/ सिस्टम .css" टाइप= "टेक्स्ट/ सीएसएस" / >
    < link rel= "stylesheet" href= "< ?php echo $this - >बेसुरल ?> / टेम्प्लेट/ सिस्टम / सीएसएस/ जनरल.सीएसएस" टाइप = "टेक्स्ट/ सीएसएस" / >

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

    < link rel= "stylesheet" href= "< ?php echo $this - >बेसुरल ?> /टेम्पलेट्स/< ?php echo $this - >टेम्पलेट ?> / सीएसएस / टेम्पलेट.सीएसएस" प्रकार = "टेक्स्ट / सीएसएस" / >

    यदि बाएँ और दाएँ स्थान पर कोई मॉड्यूल स्थित नहीं है, तो निम्नलिखित कोड स्निपेट हमें बाएँ या दाएँ कॉलम को संक्षिप्त करने की अनुमति देता है। यदि दोनों कॉलम संक्षिप्त हो जाते हैं, तो सामग्री पृष्ठ की चौड़ाई का 100% घेर लेती है। यदि केवल एक कॉलम शामिल किया जाता है, तो सामग्री 80% तक बढ़ जाती है। दो कॉलम सक्षम होने पर, सामग्री पृष्ठ की चौड़ाई का 60% होती है।

    < ?php
    यदि ($यह - > countModules('बाएँ और दाएँ' ) = = 0) $contentwidth = "100" ;
    यदि ($यह - > countModules('बाएँ या दाएँ' ) = = 1) $contentwidth = "80" ;
    यदि ($यह - > countModules('बाएँ और दाएँ' ) = = 1) $contentwidth = "60" ;
    ?>

    हेडर बंद हो जाता है

    < / head>

    < body>

    "पेज" ब्लॉक में केवल साइट पेज का डिज़ाइन शामिल है, जो 950px चौड़ा होगा।

    < div id= "page" >

    "शीर्ष" ब्लॉक पृष्ठ के बिल्कुल शीर्ष पर स्थित है और इसमें दो ब्लॉक "लोगो" और "उपयोगकर्ता1" शामिल हैं।

    < div id= "top" >

    "लोगो" बोके में हम लोगो की एक ग्राफिक फ़ाइल रखेंगे; इसे स्टाइल शीट में निर्दिष्ट किया जाएगा। लेकिन हम साइट नाम का स्वचालित प्रदर्शन Index.php फ़ाइल में लिखते हैं, और नाम को H1 टैग में रखते हैं, जो खोज इंजन अनुकूलन के लिए बहुत महत्वपूर्ण है।

    < div id= "logo" >
    < h1> < ?php echo $app - >getCfg('साइटनाम' ); ?>< / h1>
    < / div>

    आइए साइट खोज मॉड्यूल प्रदर्शित करने के लिए उसी नाम के ब्लॉक में "उपयोगकर्ता1" स्थिति को परिभाषित करें।

    < div id= "user1" >
    < jdoc:include type= "modules" name= "user1" style= "xhtml" / >
    < / div>
    < / div> < ! - - конец блока top - - >

    "user2" स्थिति में "user2" ब्लॉक में क्षैतिज मेनू मॉड्यूल का आउटपुट। यदि उस स्थान पर कोई मॉड्यूल नहीं है तो ब्लॉक ढह जाएगा।

    < ?php if ($this - >countModules("user2") : ?>
    < div id= "user2 " >
    < jdoc:include type= "modules" name= "user2" style= "xhtml" / >
    < / div>
    < ?php endif ; ?>

    इसके बाद साइट हेडर ब्लॉक आता है। इसमें हम मॉड्यूल प्रदर्शित करने के लिए "हेडर" स्थिति को परिभाषित करेंगे। यदि उस स्थान पर कोई मॉड्यूल नहीं है तो ब्लॉक ढह जाएगा। मैंने जानबूझकर इस ब्लॉक की क्षमताओं का विस्तार किया ताकि मैं इसमें न केवल हेडर छवि, बल्कि छवि रोटेटर भी रख सकूं।

    < ?php if ($this - >काउंटमॉड्यूल("हेडर") ): ?>
    < div id= "header " >
    < jdoc:include type= "modules" name= "header " style= "xhtml" / >
    < / div>
    < ?php endif ; ?>

    "user3" ब्लॉक में हम आउटपुट मॉड्यूल के लिए "user3" स्थिति को परिभाषित करते हैं।

    यदि इस स्थिति "user3" पर कोई मॉड्यूल आउटपुट नहीं है तो ब्लॉक ढह जाएगा।

    < ?php if ($this - >काउंटमॉड्यूल("user3") : ?>
    < div id= "user3" >
    < jdoc:include type= "modules" name= "user3" style= "xhtml" / >
    < / div>
    < ?php endif ; ?>

    बाएं कॉलम का एक ब्लॉक खुलता है, जो "बाएं" स्थिति में कोई मॉड्यूल नहीं होने पर ढह जाएगा।

    < ?php if ($this - >काउंटमॉड्यूल("बाएं") ) : ?>
    < div id= "left" >
    < jdoc:include type= "modules" name= "left" style= "xhtml" / >
    < / div>
    < ?php endif ; ?>

    सबसे महत्वपूर्ण सामग्री ब्लॉक खुलता है, जो शामिल कॉलम की संख्या के आधार पर, पृष्ठ की चौड़ाई का 100%, 80% और 60% पर कब्जा कर सकता है।

    < div id= "content< ?php echo $contentwidth ; ?> " >

    घटकों में संदेश प्रदर्शित करना

    < jdoc:include type= "message" / >

    आउटपुट सामग्री सामग्री।

    < jdoc:include type= "component" style= "xhtml" / >
    < / div> < ! - - конец блока контента- - >

    दाएं कॉलम का एक ब्लॉक खुलता है, जो "दाएं" स्थिति में कोई मॉड्यूल नहीं होने पर ढह जाएगा।

    < ?php if ($this - >गिनती मॉड्यूल("सही") ) : ?>
    < div id= "rigth" >
    < jdoc:include type= "modules" name= "right" style= "xhtml" / >
    < / div>
    < ?php endif ; ?>

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

    < ?php if ($this - >काउंटमॉड्यूल("फुटर") ) : ?>
    < div id= "footer" >
    < jdoc:include type= "modules" name= "footer" style= "xhtml" / >
    < / div>
    < ?php endif ; ?>

    साइट पेज ब्लॉक "पेज", बॉडी और सभी कोड बंद हैं।

    < / div> < ! - - конец блока page- - >
    < / body> < ! - - конец блока body - - >
    < / html> < ! - - конец кода- - >

    हमने एक संपूर्ण Index.php फ़ाइल बनाई है। अब आप जानते हैं कि कौन से कमांड का उपयोग किया जाता है और टेम्पलेट ब्लॉक किस क्रम में प्रदर्शित होते हैं।

    ध्यान दें: टेम्प्लेट कोड को जूमला एडमिन पैनल से पढ़ने के लिए, इंडेक्स.php फ़ाइल को अकेलपैड संपादक में खोला जाना चाहिए और बीओएम चेकबॉक्स को अनचेक करते हुए यूटीएफ -8 एन्कोडिंग में सहेजा जाना चाहिए। यदि आपने फ़ाइल के साथ काम करने के लिए मैक्रोमीडिया ड्रीमविवर प्रोग्राम का उपयोग किया है, तो आपको शीर्ष मेनू में "संपादित करें"> "पेज गुण" का चयन करना होगा और दस्तावेज़ एन्कोडिंग यूनिकोड (यूटीएफ -8) का चयन करना होगा, और "यूनिकोड हस्ताक्षर सक्षम करें (बीओएम) को अनचेक करना होगा" )” हालाँकि, मैं आपको दृढ़ता से सलाह देता हूं कि यदि आप कुछ गड़बड़ करते हैं, तो जूमला एडमिन पैनल से कोड को संपादित न करें - मैक्रोमीडिया ड्रीमवीवर प्रोग्राम के विपरीत, कोई पीछे मुड़कर नहीं देख सकता है, जहां आप हमेशा किए गए परिवर्तनों को पूर्ववत कर सकते हैं।

    ब्लॉकों का डिज़ाइन स्वयं template.css में वर्णित किया जाएगा। लेकिन हम जूमला 3 (जूमला 2.5) पर टेम्पलेट स्थापित करने के बाद स्टाइल शीट कॉन्फ़िगर करेंगे, और इसके लिए हमें बनाने की आवश्यकता है



    मित्रों को बताओ