2008-12-04 17 views
11

मैं एक php परियोजना की स्थापना की प्रक्रिया में हूँ शामिल हैं, लेकिन कैसे ठीक php का उपयोग करने से परिचित नहीं हूँ शामिल/आदेशों की आवश्यकता है। मेरे लेआउट वर्तमान में इस तरह दिखता है:PHP फ़ाइल रणनीति की जरूरत

/public --apache points into this directory 
/public/index.php 
/public/blah/page.php 
/utils/util1.php  -- useful classes/code are stored in other directories out here 
/dbaccess/db1.php 

dbaccess/db1.php 



require '../utils/util1.php 

सार्वजनिक/index.php

require '../dbaccess/db1.php' 

सार्वजनिक/blah/page.php

require '../../dbaccess/db1.php' 

समस्या php से है 'शामिल' प्रलेखन:

अगर फ़ाइल नाम से शुरू होता है ./ या ../, यह देखता है केवल वर्तमान कार्यशील निर्देशिका में

तो सार्वजनिक/blah/page.php में विफल रहता है, क्योंकि यह dbaccess/db1.php जो ऊपर चल रही है जब यह util1.php शामिल करने के लिए कोशिश करता है शामिल हैं घ। यह विफल रहता है, क्योंकि यह रिश्तेदार पथ है,/सार्वजनिक/blah/मूल स्क्रिप्ट से है dbaccess से नहीं

यह सुंदर बेवकूफ लगता है - db1.php सिर्फ जानना चाहता है जहां यह शामिल किया जा रहा है, जो काम करने के लिए नहीं जा रहा है है ।

मैं इस तरह की रणनीतियों को देखा है:

require_once dirname(__FILE__) . '/../utils/util1.php'); 

जाहिरा तौर पर काम करता है कि के बाद से अब पथ एक पूर्ण पथ है, लेकिन सिर्फ मेरे लिए वास्तव में विचित्र लगता है।

क्या यह सामान्य है? मुझे लगता है कि पथ जारी रखना चाहिए या मैं यहाँ कुछ स्पष्ट याद आ रही है?

+0

मैं करने के लिए बहुत नहीं मिला है यह कहना छोड़कर जोड़ें कि मैं 5 साल से PHP का उपयोग कर रहा हूं और यह बात * अभी भी * मुझे भ्रमित करती है। – nickf

उत्तर

13

आमतौर पर, मानक सम्मेलनों इस प्रकार हैं: @grepsedawk की तरह कहा, तुम और एक निरंतर है कि आपके प्रोजेक्ट फ़ोल्डर की जड़ होता है परिभाषित करने के लिए चाहता हूँ यदि आप कर सकते हैं अपने से रूट फ़ोल्डर में शामिल हैं:

define('APP_ROOT', dirname(__FILE__)); 
define('INCLUDE_ROOT', APP_ROOT . "/includes"); 

नोट: निरंतर नाम एक स्ट्रिंग होने की आवश्यकता है!

इसके अलावा, आप मुझे dirname(__FILE__); उपयोग कर रहा हूँ पर ध्यान देंगे। यदि आप अपनी स्थिरांक परिभाषा फ़ाइल को उपनिर्देशिका में रखते हैं, तो आप dirname(dirname(__FILE__)); कर सकते हैं, जो ../ के बराबर है।

अब कुछ अन्य चेतावनी। जबकि PATH_SEPARATOR एक शांत स्थिर है, इसकी आवश्यकता नहीं है। विंडोज पथ नामों में/या \ स्वीकार करता है, और लिनक्स केवल उपयोगकर्ता/पथ विभाजक के रूप में, आगे बढ़ें और PATH_SEPARATOR पर दोहराए गए संदर्भों के साथ अपने कोड को मक्का करने के बजाय हमेशा एक/का उपयोग करें।

अब जब आपने अपने जड़ स्थिरांक परिभाषित जब आप की जरूरत है एक विन्यास फाइल शामिल आप क्या करेंगे एक सरल है:

include INCLUDE_ROOT . '/path/to/some/file.php'; 

आप शायद अपने निरंतर परिभाषाएँ (define(...) के ऊपर चाहता हूँ) अपने रूट निर्देशिका में एक बूटस्ट्रैप स्क्रिप्ट में:

www_root/ 
    index.php 
    bootstrap.php 

बूटस्ट्रैप परिभाषित करता है में शामिल होंगे (या एकस्थिरांक फ़ाइल के), साथ ही include किसी भी फाइल के लिए जो प्रत्येक पृष्ठ द्वारा आवश्यक होगा।

और अंत में पिछले मानक सम्मेलन आप उपयोग नहीं कर सकते, लेकिन अगर आप वस्तु उन्मुख प्रोग्रामिंग कर रही शुरू करते हैं, सबसे आम तरीका (नाशपाती मानक) एक _ नामस्थान अलग करने के लिए का उपयोग करके अपने वर्गों नाम के लिए है:

class GlobalNamespace_Namespace_Class 
//... 

और फिर उप निर्देशिकाओं पर अपनी फ़ाइल संरचना मानचित्रण नाम रिक्त स्थान का आयोजन (शाब्दिक सभी जगह _ के साथ/के है):

include_dir/ 
    GlobalNamespace/ 
     Namespace/ 
      Class.php 

और __autoload() अपने वर्गों को लोड करने के लिए फ़ंक्शंस का उपयोग करके, लेकिन यह एक और सवाल है।

+0

और मैं उल्लेख करना भूल गया, dirname (__ FILE__) का उपयोग करके आप पूर्ण पथों का उपयोग करने की स्वतंत्रता (किसी ./ या ../ हल करने के बारे में चिंता करने की आवश्यकता नहीं है) जैसे आप तैनाती सर्वरों (जैसे कि "ओप्स ने /har/httpd/.../ को प्रतिलिपि बनाने के लिए /var/www/.../") – dcousineau

+0

का मतलब है DIRECTORY_SEPARATOR, PATH_SEPARATOR नहीं! PATH_SEPARATOR का उपयोग include_path के लिए किया जाता है और अन्यथा विंडोज़, कोलन पर अर्धविराम है। और पढ़ें [यहां] (http://www.php.net/manual/en/dir.constants.php) – Alexxus

-1

क्यों नहीं यह आवश्यकता होती है उस पर आधारित पूर्ण पथ है?

उदाहरण के लिए, /sharedhost/yourdomain.com/apache/www अपने दस्तावेज़ जड़ है, तो क्यों उपयोग नहीं

require('/sharedhost/yourdomain.com/apache/www/dbutils.php'); 

यह भी आप स्टोर करने के लिए अपने में शामिल हैं बाहर के सक्षम होने का लाभ दिया है अपने wwwroot इसलिए वे अब तक कम होने की संभावना है inadvertenly वेब के माध्यम से उजागर किया है।

तुम भी एक वैश्विक चर इसके बारे में /sharedhost/yourdomain.com/apache/ भाग के बराबर की स्थापना की है ताकि आप के आसपास साइट स्थानांतरित कर सकते हैं कर सकते हैं।

require(WWWROOT . '/dbutils.php'); 
+0

एक निरंतर दस्तावेज़ रूट नहीं होगा। यह कई अलग-अलग डेवलपर मशीनों पर, एक लाइव साइट पर, आंतरिक परीक्षण क्षेत्र आदि पर होगा। तो मैं उस वैश्विक चर को कहां स्थापित करूं? – Clyde

+1

आप नहीं चाहते हैं कि कोड सिस्टम के फाइल सिस्टम में कहां है, इस बारे में धारणाएं करें। – staticsan

+0

@ क्लाइड, निश्चित रूप से इसे एक कॉन्फ़िगरेशन फ़ाइल में सेट किया जा सकता है जब आप इसे प्रत्येक मशीन पर तैनात करते हैं? @staticsan, दोबारा, तैनाती/स्थापित चरण के दौरान केवल एक बार WWWROOT को परिभाषित करके उपचार किया जाता है? –

4

एक विन्यास स्क्रिप्ट है जो आपके परियोजना के "रूट स्थापित करें" और उसके बाद का उपयोग पूर्ण पथ सेट हैं। कई शामिल हैं के साथ सापेक्ष पथ php में सिर में दर्द है।

परिभाषित करते हैं ("INSTALL_ROOT" "/ path/to/www/परियोजना")

require_once (INSTALL_ROOT। '/util1.php')

+0

मैं उस वैश्विक परिभाषा को कहां सेट करूं? मैं स्पष्ट रूप से हर फाइल में ऐसा नहीं करना चाहता हूं। – Clyde

+0

क्लाइड: कॉन्फ़िगरेशन स्क्रिप्ट में, जैसे पाठ सुझाता है। – OIS

+0

कॉन्स्टेंट को स्ट्रिंग का उपयोग नाम के रूप में परिभाषित किया जाना चाहिए। वह कोड दिखेगा जैसे यह त्रुटि काम करता है अगर आप त्रुटि रिपोर्टिंग बंद कर देते हैं, लेकिन केवल इसलिए कि यदि PHP उस स्ट्रिंग अक्षर से मेल खाने के लिए निरंतर नहीं ढूंढ पाता है तो यह इसे स्ट्रिंग के रूप में डंप करेगा। 'परिभाषित करें (' INSTALL_ROOT ','/path/to/dir/');' सही है। – dcousineau

-1

मैं उपयोग

require '../path/to/file.ext'; 

बिना समस्या का।

भी आवश्यकता होती है एक बयान एक समारोह के रूप में तो यह

require '/path/to/file.ext'; 

इस्तेमाल किया जाना चाहिए नहीं

require('/path/to/file.ext'); 
+0

आपका दूसरा कथन बस सच नहीं है। –

+0

वास्तव में निर्देश और आवश्यकताएं शामिल हैं। वे सिर्फ बयान की तरह दिखने और काम करने के लिए होते हैं। और ब्रैकेट-कम संस्करण बेहतर दिखता है क्योंकि इसमें कम दृश्य प्रदूषण है। – staticsan

+0

यह निश्चित रूप से है: "आवश्यकता() कथन में विशिष्ट फ़ाइल शामिल है और मूल्यांकन करता है।" प्रेषक: http://us2.php.net/require – UnkwnTech

0

ध्यान रखें नहीं है, यह वर्तमान कार्यशील निर्देशिका में शुरू होता है और फिर शामिल के माध्यम से लग रहा है पथ। यदि आप कुछ केंद्रीय रूट निर्देशिका (या कई) से अपने सभी पथों को संदर्भित करना चाहते हैं तो आप php.ini फ़ाइल में उस निर्देशिका को जोड़ सकते हैं या आप इसे set_include_path( $path.PATH_SEPERATOR.get_include_path());

0

के साथ प्रोग्रामेटिक रूप से कर सकते हैं। मैं एक अमूर्त रणनीति का सुझाव देता हूं।

  1. अपने एप्लिकेशन पेज क्षेत्र में, एक ही फ़ाइल है जिसमें सभी पृष्ठों में शामिल हैं।

  2. यह "स्थानीय" फ़ाइल में एक नौकरी है: एप्लिकेशन पृष्ठ क्षेत्र के बाहर मौजूद फ़ाइल शामिल करें। इसके बाद इसमें शामिल है। यह शायद हो सकता है यह दूसरा फ़ाइल के रूप में सरल रूप में <?php include dirname(__FILE__).'/../include/include.php/'; ?>

  3. अपने पुस्तकालय संरचना में एकल प्रविष्टि केंद्र है। यह, या इसमें कुछ और शामिल है, यह जानने का काम है कि सबकुछ कहां है और इसमें शामिल है।

यह संरचना मतलब है कि आप अपनी लाइब्रेरी के प्रवेश बिंदु है और कैसे यह पाता है पुस्तकालय के बाकी आवेदन पृष्ठ 'समस्या नहीं है के रूप में सिर्फ एक फ़ाइल है। इसका मतलब यह भी है कि आपके पास अपने एप्लिकेशन क्षेत्र में केवल एक फ़ाइल है जो जानता है कि आपकी लाइब्रेरी के प्रवेश बिंदु को कैसे ढूंढें।

आप अलग अलग चीजें लोड करने के लिए अलग-अलग आवेदन पृष्ठों के लिए एक तरह से की जरूरत है, मैं एक Modularisation दृष्टिकोण सुझाव है। यह या तो मास्टर ग्लोबल सरणी हो सकता है जिसे आपने मास्टर से पहले सेट किया है, या एक फ़ंक्शन जिसे आप नाम से पुस्तकालयों का अनुरोध करने के लिए कॉल कर सकते हैं। हां, यह आपकी मास्टर लाइब्रेरी फ़ाइल का एक छोटा सा प्रशंसक तरीका है जहां सबकुछ स्थिर रहता है - लेकिन यह include LIBRARY_DIR.'/utils/util.php'; करने की प्रलोभन को हटा देता है जो सीधे में से में को स्थानांतरित करने के लिए अनावश्यक रूप से कठिन बनाता है।

श्रृंखलित फ़ाइलों के अन्य लाभ यह है कि यह तो बहुत आसान अपने codebase पुनर्निधारणीय है, जो यह संभव से अधिक संस्करण runnable होने के लिए बनाता है बनाने के लिए है। और यह आपके पुस्तकालय के लिए आवेदन के लिए एक पेड़ और दूसरा संभव बनाता है। जिसका अर्थ है कि एक और एप्लिकेशन आपकी लाइब्रेरी का उपयोग कर सकता है। वास्तव में, यदि आप अलगाव के साथ आगे बढ़ना चाहते हैं तो आप थोड़ा और अधिक चेनिंग बढ़ा सकते हैं।

1
मेरी config/सेटअप फ़ाइल में

, मैं तो मैं संदर्भ की तरह

define('MYAPP_BASEDIR',realpath('.'));

कुछ सब कुछ है कि के सापेक्ष है।

... यदि आपकी निर्देशिका शामिल है विशेष रूप से कक्षा फाइलों से संबंधित है और आप उन्हें नाम देने में सक्षम हैं ताकि फ़ाइल का नाम कक्षा से लिया जा सके, तो आप spl_autoload_register() देख सकते हैं।

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

0

आप सही हैं, आपकी स्क्रिप्ट को आपके पथ में मौजूद भौतिक पथ को नहीं जानना है।

IMO स्थान जहां भी शामिल कर रहे हैं php.ini फ़ाइल में कॉन्फ़िगर किया जाना चाहिए (या .htaccess अगर आप preffer)।

Suponse अपने भी शामिल है (utils और डेटाबेस यहां जमा हो जाती है/घर/स्कॉट/php_includes /)।

php.ini:

include_path =:।/घर/स्कॉट/php_includes/

अब अपनी स्क्रिप्ट इस तरह से पुस्तकालयों में शामिल कर सकते हैं:

dbaccess/DB1।php:

requ_once 'utils/util1.php';

सार्वजनिक/index.php

require_once 'dbaccess/db1.php';

सार्वजनिक/blah/page.php:

require_once 'dbaccess/db1.php';

0

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

यदि आप बहुत सारी फाइलों को शामिल करना और आवश्यकता करना शुरू करते हैं, तो यह include_once या requ_once का उपयोग करने के लिए मोहक हो सकता है। बहुत से _once का उपयोग करने वाली स्क्रिप्ट्स के कैश्रिंड्स ने दिखाया है कि वे वास्तव में प्रदर्शन को धीमा कर देते हैं क्योंकि स्क्रिप्ट को स्कैन करने के लिए क्या करना है और यह सुनिश्चित करना है कि फ़ाइल पहले से ही शामिल नहीं है। जितना आप कर सकते हैं उतने _once को खत्म करने में मदद मिलेगी।

0

एकदम सही समाधान था - "pwee" नामक pecl एक्सटेंशन - यह उपयोगकर्ता को एक्सएमएल फ़ाइल का उपयोग कर अपने बाहरी सुपरग्लोबल स्थिरांक/परिवर्तक को परिभाषित करने की अनुमति देता है। इस प्रकार आप के रूप में मैं इस तरह के रूप में की सिफारिश निरपेक्ष पथ का उपयोग करने में सक्षम थे:

require_once APP_ROOT."/path/to/your/script.php"; 

इस तरह के समाधान का लाभ था:

  • हर जगह
  • से सुलभ नहीं सर्वर लोड - सर्वर स्मृति
  • में सब कुछ

एक्सएमएल फ़ाइल निहित

<Environments> 
    <Application name="www.domain.com" namespace=""> 
     <Constants> 
     <Constant name="APP_ROOT" value="/full/path/to/project/source" /> 
     </Constants> 
     <Constants> 
     <Constant name="WEB_ROOT" value="/full/path/to/project/public" /> 
     </Constants> 
    </Application> 
    </Environments> 

link to pwee project

आप शामिल किए जाने के इन मामलों को अलग करना चाहिए:

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

के उच्च स्तर से आम फ़ाइलों का उपयोग कर रिश्तेदार पथ उपयोग इस फार्म के मामले में रिश्तेदार पथ का उपयोग करना चाहिए :

require_once "./relative/path/to/script.php"; 

मैं पिछले काल का उपयोग क्यों करूं? क्योंकि परियोजना अधिक समर्थित नहीं है - केवल php4 के साथ काम करता है। अगर कोई समर्थन के साथ समान समाधान जानता है, तो कृपया मुझे बताएं।

0

ऐसा करने का सबसे अच्छा तरीका लचीला ऑटोलोड सिस्टम बनाना है।

कक्षा नामों और मालिकाना पैच का सरल मानचित्र। फिर किसी आंतरिक आवश्यकता_ * या include_ * की आवश्यकता नहीं है।

ऑटोलोडर के लिए सापेक्ष/पूर्ण पथ का निश्चित रूप से मामला है। खैर, पूर्ण रूप से सबसे अधिक सिस्टम-कुशल है, इसलिए मैंने जिस सरणी में उल्लेख किया है, उसमें मैंने कुछ प्रकार के चरणीय प्रीपेड कर सकते हैं {मैंने फ़िंग-स्टाइल वैरिएबल का उपयोग किया है} उदा।

<map> 
    <path classname="MyClass">${project_directory}/libs/my_classes/MyClass.php</path> 
    <path classname="OtherClass">${project_directory}/libs/some_new/Other.php</path> 
    <!-- its so flexible that even external libraries fit in --> 
    <path classname="Propel">${project_directory}/vendors/propel/Propel.php</path> 
    <!-- etc --> 
</map> 

एक्सएमएल यह वह जगह है फ़ाइल (के बारे में आरं या YAML रूप में अच्छी तरह लगता है) और पहली शुरुआत के दौरान php के संकलन की आवश्यकता है, लेकिन उसके बाद किसी भी पथ निरपेक्ष है।

ओह, जैसा कि आप कोई फ़ाइल नामकरण सम्मेलन या फ़ाइल लेआउट अनिवार्य नहीं देख सकते हैं - इसका बड़ा लाभ।

चीयर्स, एलन।

0

ऐसा लगता है कि हर बार जब मैं अपनी सरल स्क्रिप्ट को एक सर्वर से दूसरे सर्वर पर ले जाता हूं तो मुझे चीजों को फिर से परिभाषित करना होगा।

मैंने घर पर एक परीक्षण वातावरण स्थापित किया, कुछ चीजें बनाई, और उन्हें एक साझा मेजबान में तैनात किया। नतीजा यह था कि $_server['DOCUMENT_ROOT'] एक सर्वर पर public_html फ़ोल्डर से दो फ़ोल्डर्स अधिक था, और दूसरे सर्वर पर यह एक फ़ोल्डर अधिक था।

जो मेरे सभी संदर्भों को छोड़ देता है। तो मैंने $_server['WEB_ROOT'] की कोशिश की और फिर से असफल रहा। मैं सोच रहा था कि वेब रूट सर्वर पर सार्वजनिक रूप से सुलभ फ़ोल्डरों की जड़ का संदर्भ था, लेकिन मैं गलत था।

मेरे पास ढेर में फेंकने के लिए एक है जो बहुत सारे कोड को जोड़ने के बिना वास्तव में सरल कुछ करता है, मुझे समझ में नहीं आता है (मुझे इस कोड का बहुत कुछ समझ में नहीं आता है, मैंने नियमों को पढ़ते हुए बस जोड़ दिया है और इसे काम करने के लिए मिला)।

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

पब-डॉक-root.php:

<?php 

//You only need to paste the following line into your script once, 
//and it must come before you reference the public document root of your website. 
//Use $pubroot.'/path_from_public_document_root_to_file/filename.php 

$pubroot = (str_replace(($_SERVER['PHP_SELF']), '', (str_replace('\\', '/', (realpath(basename(getenv("SCRIPT_NAME")))))))); 


//uncomment the next line to show the calculated public document root 
//relative to the document root. 

//echo ("$pubroot"); 
?> 

मेरे परीक्षण वातावरण:

  • php 5.3.1
  • अपाचे 2.2.14 (Win32) mod_ssl 2.2.14 OpenSSL 0.9। 8k
  • ZendServer-सीई-5.0.0GA_RC181-5.3.1-Windows_x86
संबंधित मुद्दे