2015-04-17 4 views
18

php एक apache मॉड्यूल के रूप में प्रयोग किया जाता है, एक वातावरण चर एक अपाचे SetEnv निर्देश से आ रही php के getenv() के लिए उपलब्ध है, लेकिन यह stdlib के getenv() के माध्यम से C एक्सटेंशन के लिए उपलब्ध हो प्रतीत नहीं होता है। कम से कम यह pgsql मॉड्यूल के साथ होता है। चर php कोड के साथ reinstantiated हैक्यों पहले से परिभाषित पर्यावरण चर पर putenv() की आवश्यकता है?

हैं:

putenv("varname=".getenv("varname")); 

तो यह एक्सटेंशन के कोड के लिए उपलब्ध हो जाता है।

प्रश्न: यह बहाली क्यों आवश्यक है? कोर php पर्यावरण "मानक" (stdlib) वातावरण से अलग कैसे है?

यह एक अपाचे मॉड्यूल के रूप में उबंटू 12.04 में PHP Version 5.3.10-1ubuntu3.17 के साथ होता है। कमांड लाइन से चलाए जाने पर, उपर्युक्त कामकाज आवश्यक नहीं है। इस अन्य प्रश्न से: Using .pgpass from Apache libphp5.so ऐसा प्रतीत होता है कि यह वर्कअराउंड फ्रीबीएसडी के तहत php-5.4 के लिए भी आवश्यक है, इसलिए यह केवल उबंटू या php-5.3 नहीं है।

यह variables_order पर E पर निर्भर नहीं है। मैं EGPCS और GPCS दोनों की कोशिश की है, और $_ENV तैयार नहीं हुआ है जब E वहाँ नहीं है, के रूप में उम्मीद है, लेकिन उस getenv() के परिणाम को बदलने नहीं है, documented के रूप में, या जाहिरा तौर पर stdlib के getenv() अंदर एक्सटेंशन से का परिणाम है। pgsql मॉड्यूल के साथ समस्या की


डेमो। यह libpqC में लिखी गई साझा लाइब्रेरी के शीर्ष पर बनाया गया है, जो वैकल्पिक PG* पर्यावरण चर के कुछ हद तक getenv() पर कॉल करता है।

अपाचे विन्यास फाइल में, एक <VirtualHost> के तहत, मैं इस संबंध प्रयास विफल बनाने के लिए सेट कर रहा हूं:

SetEnv PGHOST doesnotexist 

और नहीं pg_connect कॉल में एक मेजबान को निर्दिष्ट है, तो PGHOST जब वर्तमान लिया जाना चाहिए।

पहले कोशिश:

$v=getenv("PGHOST"); 
echo "PGHOST=$v\n"; 

$cnx=pg_connect("user=daniel"); 
if ($cnx) { 
    echo "Connection is successful."; 
} 

परिणाम:

 
PGHOST=doesnotexist 
Connection is successful. 

तो PGHOST पर ध्यान नहीं दिया जा रहा है, वातावरण में होने के बावजूद।

दूसरा कोशिश, अब वातावरण में फिर से PGHOST डाल भले ही यह पहले से ही वहाँ है:

$v=getenv("PGHOST"); 
echo "PGHOST=$v\n"; 
putenv("PGHOST=".getenv("PGHOST")); 
$cnx=pg_connect("user=daniel"); 
if ($cnx) { 
    echo "Connection is successful."; 
} 

परिणाम (अपेक्षित रूप से विफलता निर्दिष्ट मेजबान से कनेक्ट करने,):

PGHOST=doesnotexist 
Warning: pg_connect(): Unable to connect to PostgreSQL server: 
could not translate host name "doesnotexist" to address: 
Name or service not known in /var/www/test/pgtest2.php on line 8 
+0

मुझे लगता है कि आपके पास यूनिक्स पथ हैं, लेकिन क्या आप साइगविन की तरह कुछ ऐसा करते हैं? इस पड़ोस में एक खिड़की का मुद्दा है जिसके आधार पर सी रनटाइम्स अलग-अलग साझा libs के खिलाफ जुड़े हुए हैं। – covener

+0

लिनक्स उबंटू 12.04 –

+0

के साथ ऐसा नहीं होता है PHP 5.4 के साथ फ्रीबीएसडी 10.1 पर भी होता है। – CXJ

उत्तर

8

इसका कारण यह है:

पर्यावरण मूल्य जो आपको getenv()[PHP] से प्राप्त होते हैं (php func टियन) getenv()[C] (सी lib फ़ंक्शन) के साथ पूछे जाने वाले पर्यावरण से अलग हैं। क्या getenv()[PHP] करता है, एक मैच के लिए पंजीकृत सैपी के साथ जांच कर रहा है (http://lxr.php.net/xref/PHP_5_6/ext/standard/basic_functions.c#3999)।

apache2 sapi अपने पर्यावरण संदर्भ (http://lxr.php.net/xref/PHP_5_6/sapi/apache2handler/sapi_apache2.c#253) के माध्यम से करता है, अपाचे प्रक्रिया से मानक ओएस पर्यावरण नहीं।

केवल जब कोई मिलान नहीं मिलता है, तो यह वास्तविक प्रक्रिया के माहौल पर जांच करेगा। तो यही कारण है कि getenv()[PHP] एक मान देता है, लेकिन getenv()[C] नहीं करता है।

अब, "हैक" एक साधारण भी है: putenv()[PHP], चल रही प्रक्रिया के माहौल में दी गई कुंजी/मान संग्रहीत करता है, यही कारण है कि इसे बाद में getenv()[c] पर पाया जा सकता है।

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