2011-03-01 15 views
12

एप्लिकेशन लॉगिंग के हिस्से के रूप में, मैं एक स्थानीय फ़ाइल खोलने का प्रयास कर रहा हूं, और यदि वह फ़ाइल पहले से मौजूद नहीं है, तो नया निर्माण करने के लिए। यहाँ मैं क्या है:PHP fopen() फ़ाइल नहीं बना रहा है अगर यह पहले से मौजूद नहीं है

$path = '/home/www/phpapp/logs/myawesome_logfile.txt'; 
$f = (file_exists($path))? fopen($path, "a+") : fopen($path, "w+"); 
fwrite($f, $msg); 
fclose($f); 
chmod($path, 0777); 

मैं दोबारा जांच की है, और /logs निर्देशिका chmod 0777 है, और मैं भी अपाचे के लिए यह chown'ing के अतिरिक्त कदम चला गया: अच्छा उपाय अपाचे। फिर भी, जब स्क्रिप्ट फ़ाइल खोलने के लिए जाती है, तो यह मुझे चेतावनी देता है कि फ़ाइल मौजूद नहीं है और बम बाहर है। कोई फ़ाइल कभी नहीं बनाई गई है।

क्या मुझे फ़ाइल बनाने के लिए fopen() चेतावनी दबाने की आवश्यकता है?

+0

नोट: मैंने 'file_exists()' के साथ तर्क जोड़ा है, यदि किसी भी कारण से मुझे 'ए +' पकड़ रहा था। –

+2

क्या आप वास्तव में रूट पर अपना रास्ता शुरू करना चाहते हैं? यह आपकी ऐप की रूट निर्देशिका नहीं होगी, यह आपके सिस्टम की मूल निर्देशिका होगी। –

+0

आपको क्यों लगता है कि त्रुटि दमन आपको फ़ाइल खोलने में मदद करेगा? –

उत्तर

16

जब आप PHP में पथ के साथ काम कर रहे हैं, तो संदर्भ एक बड़ा सौदा कर सकता है। यदि आप पुनर्निर्देशन संदर्भ में यूआरएल के साथ काम कर रहे हैं - तो मूल निर्देशिका ('/') आपके डोमेन की जड़ को संदर्भित करती है। फाइलों या छवियों को जोड़ने और निर्देशों के लिए पथों के लिए पथों के लिए यह वही है।

हालांकि, जब आप fopen जैसे फ़ाइल सिस्टम कमांड से निपट रहे हैं, तो रूट निर्देशिका ('/') सिस्टम रूट है। आपका डोमेन रूट नहीं है।

इसे ठीक करने के लिए, लॉग फ़ाइल को पूरा पथ देने का प्रयास करें जिसे आप सिस्टम रूट से खोलना चाहते हैं। उदाहरण के लिए: /var/www/phpapplication/logs/myLogFile.txt

या आप $_SERVER['DOCUMENT_ROOT'] का उपयोग कर सकते हैं जैसा कि अन्य रूट में दस्तावेज़ रूट के पथ के लिए आपके सर्वर के संग्रहीत मूल्य तक पहुंचने के लिए किया गया है। /var/www भाग।

स्पष्ट करने के लिए संपादित किया गया।

+0

"जब आप फाइल हैंडलिंग कमांड से निपट रहे हैं जैसे fopen() php रूट निर्देशिका से काम करता है, न कि एप्लिकेशन की रूट निर्देशिका।" er ... नहीं, जब आप पथ की शुरुआत में '/' डालते हैं तो मूल निर्देशिका से प्रारंभ होता है। अगर वह 'phpapp/logs/myawesome_logfile.txt'' डालता है तो यह कार्यशील निर्देशिका से जांच करेगा, जो संदर्भ से भी गलत निर्णय ले रहा है। – Powerlord

+0

कुछ समय हैं जब एक/सामने डालने से आपको डोमेन की मूल निर्देशिका - जैसे यूआरएल रीडायरेक्शन के साथ निर्देशित किया जाएगा। संदर्भ निर्धारित करता है कि हम रूट निर्देशिका या रूट डोमेन की बात कर रहे हैं या नहीं। हालांकि, पथों को समान दिखने के बाद भी उन्हें भ्रमित करना आसान है। –

+0

यह पूरा रास्ता प्राप्त कर रहा है। (मैंने ब्रेवटी के लिए मेरे पोस्ट में पथ के/home/www/पथ को हटा दिया)। –

15

क्या आपने यह कोशिश की है?

$msg = "I'm a line that is a message.\n"; 
$path = $_SERVER['DOCUMENT_ROOT'] . '/logs/myawesome_logfile.txt'; 
$f = fopen($path, "a+"); 
fwrite($f, $msg); 
fclose($f); 
chmod($path, 0777); 

जिस सर्वर पर आप काम कर रहे हैं वह आपको केवल phpapp की निर्देशिका और इसकी उपनिर्देशिका में काम करने के लिए जेल में डाल सकता है।

+0

+1: DOCUMENT_ROOT लगभग निश्चित रूप से आवश्यक फ़िक्स है। – Powerlord

1

आप हमेशा अपनी फ़ाइल को "a" के साथ खोल सकते हैं, यह एक नई फ़ाइल भी बनाएगा।
कोई शर्त बनाने की आवश्यकता नहीं है।

हालांकि, आपके कोड के साथ मुख्य समस्या भौतिक फाइल सिस्टम और वर्चुअल वेब-सर्वर के बीच अंतर को समझ रही है, जिसे पहले से ही समझाया गया है।

ध्यान दें कि आपको त्रुटि संदेश की सटीक प्रति के साथ अपना प्रश्न प्रदान करना चाहिए। इसमें अत्यंत उपयोगी जानकारी का एक टन शामिल है, यह शपथ की तरह नहीं है "मैं आपकी फाइल नहीं बनाऊंगा, चले जाओ!" लेकिन यह गलत और क्यों गलत हो रहा है के स्पष्टीकरण के माध्यम से है। यदि आपको ऐसी उपयोगी जानकारी का ख्याल नहीं है, तो आपको इसे उन लोगों को प्रदान करना होगा जिन्हें सहायता मांगना है।

+0

कोई वर्चुअल सर्वर शामिल नहीं है, और स्क्रिप्ट को फ़ाइल का पूरा पथ मिल रहा है। मेरे पास त्रुटि आसान नहीं है, लेकिन जब मैं इसे प्राप्त कर सकता हूं तो मैं इसे पोस्ट करूंगा। –

+0

@b। ई। हॉलनबेक अच्छी तरह से, एक त्रुटि संदेश तब भी और अधिक महत्वपूर्ण हो जाता है। –

0

फ़ाइल का पथ सर्वर रूट के साथ होना चाहिए। मैं उस दस्तावेज़ के अंदर phpinfo() विधि का उपयोग करके इसे प्राप्त कर सकता था जिसे मैं जानना चाहता था। तो जब आप phpinfo() का उपयोग करते हैं तो आपको एक सूचना दस्तावेज़ दिखाई देगा। यदि आपको _SERVER ["SCRIPT_FILENAME"] मिलती है तो आपको अपनी फ़ाइल का पूर्ण पथ दिखाई देगा।

मुझे उम्मीद है कि यह किसी की मदद करेगा।

0

यह सुनिश्चित करने के लिए मत भूलना कि SELinux आपको अवरुद्ध नहीं कर रहा है।

[जड़ @ yourbox] # audit2allow < /var/log/audit/audit.log
# ============= httpd_t ========= =====
# !!!! इस एवीसी को बूलियन 'httpd_unified' का उपयोग करके अनुमति दी जा सकती है httpd_t httpd_sys_content_t: dir {write add_name};
# !!!! इस एवीसी को बूलियन 'httpd_unified' का उपयोग करके httpd_t httpd_sys_content_t: फ़ाइल {लिखना बनाने} की अनुमति दी जा सकती है; [जड़ @ yourbox] # audit2allow -एक -M my_httpd

नोट:

इस नीति पैकेज सक्रिय बनाने के लिए, निष्पादित करें:

semodule मैं my_httpd.pp

[रूट @ yourbox] # semodule -i my_httpd.pp
[रूट @ yourbox] # systemctl httpd

पुनरारंभ करें
2

UBUNTU 14.04 में इस समस्या को हल करने के एक तरीके से फ़ाइल पर स्थित है और "दूसरों को" फ़ाइलों को बनाने और हटाने के लिए "अन्य" की अनुमतियों को बदलकर उस निर्देशिका पर राइट क्लिक करके था।

संबंधित मुद्दे