ऐसे कई कारण हैं कि कोई इस त्रुटि में भाग सकता है और इस प्रकार पहले चेक करने के लिए एक अच्छा चेकलिस्ट काफी मदद करता है।
आइए विचार करें कि हम निम्नलिखित पंक्ति का निवारण कर रहे हैं:
require "/path/to/file"
चेकलिस्ट
1. टाइपोस के लिए फ़ाइल पथ की जाँच करें
- या तो मैन्युअल रूप से जांचें (नेत्रहीन रूप से पथ की जांच करके)
या चाल जो कुछ भी से पुकारा जाता है require*
या include*
अपने स्वयं के चर करने के लिए, यह गूंज, इसे कॉपी, और एक टर्मिनल से यह तक पहुँचने का प्रयास:
$path = "/path/to/file";
echo "Path : $path";
require "$path";
फिर, एक टर्मिनल में:
cat <file path pasted>
2. जाँच करें कि फ़ाइल पथ सापेक्ष बनाम निरपेक्ष पथ विचारों के संबंध में सही है
- यदि यह आगे स्लैश "/" से शुरू हो रहा है, तो यह आपकी वेबसाइट के फ़ोल्डर (दस्तावेज़ रूट) की जड़ का उल्लेख नहीं कर रहा है, लेकिन आपके सर्वर की जड़ तक।
- उदाहरण के लिए, आपकी वेबसाइट की निर्देशिका हो सकती है
/users/tony/htdocs
- यदि यह आगे स्लैश से शुरू नहीं हो रहा है तो यह या तो शामिल पथ पर निर्भर है (नीचे देखें) या पथ सापेक्ष है। यदि यह सापेक्ष है, तो PHP अपेक्षाकृत वर्तमान कार्यशील निर्देशिका के पथ की गणना करेगा ।
- इस प्रकार, आपकी वेब साइट के रूट के पथ के सापेक्ष नहीं, या उस फ़ाइल के लिए जहाँ आप टाइप कर रहे हैं
- इस कारण से, हमेशा निरपेक्ष फ़ाइल पथ का उपयोग करें
सर्वोत्तम प्रथाएं :
अपनी स्क्रिप्ट को मजबूत बनाने के लिए, जब आप चीजों को इधर-उधर करते हैं, तब भी रनटाइम के दौरान एक निरपेक्ष मार्ग उत्पन्न होता है, आपके पास 2 विकल्प हैं:
- उपयोग करें
require __DIR__ . "/relative/path/from/current/file"
। __DIR__
जादू निरंतर वर्तमान फ़ाइल की निर्देशिका देता है।
SITE_ROOT
अपने आप को एक निरंतर परिभाषित करें:
- अपनी वेब साइट की निर्देशिका के मूल में, एक फ़ाइल बनाएँ, जैसे
config.php
में config.php
, लिखो
define('SITE_ROOT', __DIR__);
प्रत्येक फ़ाइल में जहाँ आप साइट रूट फ़ोल्डर को संदर्भित करना चाहते हैं, शामिल हैं config.php
, और फिर SITE_ROOT
जहाँ भी आप चाहते हैं, निरंतर का उपयोग करें :
require_once __DIR__."/../config.php";
...
require_once SITE_ROOT."/other/file.php";
ये 2 प्रथाएं आपके एप्लिकेशन को अधिक पोर्टेबल बनाती हैं क्योंकि यह शामिल पथ की तरह ini सेटिंग्स पर निर्भर नहीं करती है।
3. अपने शामिल पथ की जाँच करें
फ़ाइलों को शामिल करने का एक और तरीका, न तो अपेक्षाकृत और न ही पूरी तरह से पूरी तरह से, शामिल पथ पर भरोसा करना है । यह अक्सर लाइब्रेरी या फ्रेमवर्क जैसे कि Zend फ्रेमवर्क के लिए होता है।
ऐसा समावेश इस तरह दिखेगा:
include "Zend/Mail/Protocol/Imap.php"
उस स्थिति में, आप यह सुनिश्चित करना चाहेंगे कि फ़ोल्डर जहां "Zend" है, शामिल पथ का हिस्सा है।
आप के साथ शामिल पथ की जाँच कर सकते हैं:
echo get_include_path();
आप इसके साथ एक फ़ोल्डर जोड़ सकते हैं:
set_include_path(get_include_path().":"."/path/to/new/folder");
4. जांचें कि आपके सर्वर की उस फ़ाइल तक पहुंच है
यह हो सकता है कि सभी एक साथ, सर्वर प्रक्रिया (Apache या PHP) चलाने वाले उपयोगकर्ता को बस उस फ़ाइल से पढ़ने या लिखने की अनुमति नहीं है।
सर्वर किस उपयोगकर्ता के चल रहा है, इसकी जांच के लिए आप posix_getpwuid का उपयोग कर सकते हैं :
$user = posix_getpwuid(posix_geteuid());
var_dump($user);
फ़ाइल पर अनुमतियों का पता लगाने के लिए, टर्मिनल में निम्न कमांड टाइप करें:
ls -l <path/to/file>
और अनुमति प्रतीकात्मक संकेतन को देखें
5. PHP सेटिंग्स की जाँच करें
यदि उपरोक्त में से कोई भी काम नहीं किया है, तो मुद्दा शायद यह है कि कुछ PHP सेटिंग्स ने उस फ़ाइल का उपयोग करने से मना किया है।
तीन सेटिंग्स प्रासंगिक हो सकती हैं:
- open_basedir
- यदि यह सेट किया गया है तो PHP निर्दिष्ट निर्देशिका के बाहर किसी भी फ़ाइल तक पहुँचने में सक्षम नहीं होगी (प्रतीकात्मक लिंक के माध्यम से भी नहीं)।
- हालाँकि, डिफ़ॉल्ट व्यवहार इसके लिए निर्धारित नहीं है कि किस स्थिति में कोई प्रतिबंध नहीं है
- यह या तो बुला द्वारा जाँच की जा सकती है
phpinfo()
या का उपयोग करकेini_get("open_basedir")
- आप अपनी php.ini फ़ाइल या अपनी httpd.conf फ़ाइल को संपादित करके सेटिंग बदल सकते हैं
- सुरक्षित मोड
- यदि यह प्रतिबंधों पर चालू है तो लागू हो सकता है। हालाँकि, इसे PHP 5.4 में हटा दिया गया है। यदि आप अभी भी एक ऐसे संस्करण पर हैं जो PHP संस्करण के लिए सुरक्षित मोड अपग्रेड का समर्थन करता है जो अभी भी समर्थित है ।
- allow_url_fopen और allow_url_include
- यह केवल एक नेटवर्क प्रक्रिया जैसे http: // के माध्यम से फ़ाइलों को शामिल करने या खोलने के लिए लागू होता है, जब स्थानीय फ़ाइल सिस्टम पर फ़ाइलों को शामिल करने का प्रयास नहीं किया जाता है
- इस के साथ की जाँच की
ini_get("allow_url_include")
और सेट किया जा सकता हैini_set("allow_url_include", "1")
कोने के मामले
यदि उपरोक्त में से कोई भी समस्या का निदान करने में सक्षम नहीं है, तो यहां कुछ विशेष परिस्थितियां हैं जो हो सकती हैं:
1. शामिल पथ पर निर्भर पुस्तकालय का समावेश
ऐसा हो सकता है कि आप एक पुस्तकालय में शामिल हों, उदाहरण के लिए, एक रिश्तेदार या निरपेक्ष पथ का उपयोग करते हुए Zend फ्रेमवर्क। उदाहरण के लिए :
require "/usr/share/php/libzend-framework-php/Zend/Mail/Protocol/Imap.php"
लेकिन फिर भी आपको उसी तरह की त्रुटि मिलती है।
ऐसा इसलिए हो सकता है क्योंकि आपके पास (सफलतापूर्वक) शामिल की गई फ़ाइल में स्वयं किसी अन्य फ़ाइल के लिए एक सम्मिलित कथन होता है, और उस दूसरे विवरण में यह कथन शामिल होता है कि आपने उस लाइब्रेरी के पथ को शामिल पथ में जोड़ दिया है।
उदाहरण के लिए, पहले बताई गई Zend फ्रेमवर्क फ़ाइल में निम्नलिखित शामिल हो सकते हैं:
include "Zend/Mail/Protocol/Exception.php"
जो न तो सापेक्ष पथ द्वारा सम्मिलित है, न ही पूर्ण मार्ग से। यह मान रहा है कि Zend फ्रेमवर्क निर्देशिका को शामिल पथ में जोड़ा गया है।
ऐसे मामले में, निर्देशिका को अपने शामिल पथ में जोड़ने का एकमात्र व्यावहारिक समाधान है।
2. SELinux
यदि आप सुरक्षा-संवर्धित लिनक्स चला रहे हैं, तो यह सर्वर से फ़ाइल तक पहुंच से इनकार करके समस्या का कारण हो सकता है।
यह जांचने के लिए कि क्या आपके सिस्टम पर SELinux सक्षम है, sestatus
कमांड को टर्मिनल में चलाएं । यदि कमांड मौजूद नहीं है, तो SELinux आपके सिस्टम पर नहीं है। यदि यह मौजूद है, तो आपको यह बताना चाहिए कि यह लागू है या नहीं।
यह जांचने के लिए कि क्या SELinux नीतियां समस्या का कारण हैं , आप इसे अस्थायी रूप से बंद करने का प्रयास कर सकते हैं। हालाँकि CAREFUL हो, क्योंकि यह पूरी तरह से सुरक्षा को निष्क्रिय कर देगा। अपने प्रोडक्शन सर्वर पर ऐसा न करें।
setenforce 0
यदि आपको अब SELinux बंद होने की समस्या नहीं है, तो इसका मूल कारण है।
इसे हल करने के लिए , आपको तदनुसार SELinux को कॉन्फ़िगर करना होगा।
निम्नलिखित संदर्भ प्रकार आवश्यक होंगे:
httpd_sys_content_t
उन फ़ाइलों के लिए जिन्हें आप चाहते हैं कि आपका सर्वर पढ़ने में सक्षम हो
httpd_sys_rw_content_t
उन फ़ाइलों के लिए, जिन पर आप एक्सेस पढ़ना और लिखना चाहते हैं
httpd_log_t
लॉग फ़ाइलों के लिए
httpd_cache_t
कैश डायरेक्टरी के लिए
उदाहरण के लिए, httpd_sys_content_t
अपनी वेबसाइट के रूट डायरेक्टरी के संदर्भ प्रकार को चलाने के लिए:
semanage fcontext -a -t httpd_sys_content_t "/path/to/root(/.*)?"
restorecon -Rv /path/to/root
यदि आपकी फ़ाइल किसी होम डायरेक्टरी में है, तो आपको httpd_enable_homedirs
बूलियन चालू करना होगा :
setsebool -P httpd_enable_homedirs 1
किसी भी मामले में, कई कारण हो सकते हैं कि SELinux आपकी नीतियों के आधार पर किसी फ़ाइल तक पहुंच से इनकार क्यों करेगा। तो आपको उससे पूछताछ करनी होगी। यहाँ एक वेब सर्वर के लिए विशेष रूप से SELinux को कॉन्फ़िगर करने पर एक ट्यूटोरियल है।
3. सिम्फनी
यदि आप सिम्फनी का उपयोग कर रहे हैं, और सर्वर पर अपलोड करते समय इस त्रुटि का अनुभव कर रहे हैं, तो यह हो सकता है कि ऐप का कैश रीसेट नहीं किया गया है, या तो app/cache
अपलोड किया गया है, या उस कैश को साफ़ नहीं किया गया है।
आप निम्न कंसोल कमांड चलाकर इसे ठीक कर सकते हैं:
cache:clear
4. गैर ACSII अक्षर ज़िप फ़ाइल के अंदर
जाहिरा तौर पर, यह त्रुटि तब भी हो सकती है zip->close()
जब कॉल करने पर ज़िप के अंदर की कुछ फाइलें गैर-ASCII वर्णों में उनके फ़ाइल नाम में होती हैं, जैसे "é"।
एक संभावित समाधान utf8_decode()
लक्ष्य फ़ाइल बनाने से पहले फ़ाइल का नाम लपेटना है ।
इस मुद्दे के समाधान की पहचान करने और सुझाव देने के लिए फ्रैंक कैनो को श्रेय