2017-03-24 10 views
10

मैं http से https तक जा रहा हूं, और इसलिए मुझे StreamContext कई read_file और get_file_contents कॉल में जोड़ना है।स्ट्रीमकॉन्टेक्स्ट पुन: प्रयोज्य कब होता है? और इसे फिर से उपयोग नहीं किया जाना चाहिए?

मैं

$stream_context = stream_context_create([ 
    /* some lenghty options array */ 
]); 
read_file('https://'.$host.$uri, false, $stream_context); 

अब मेरे सवाल से

read_file('http://'.$host.$uri); 

प्रतिस्थापित करने की आवश्यकता: इस तरह एक $ stream_context पुन: प्रयोज्य है:

$stream_context = stream_context_create([ 
    /* some lenghty options array */ 
]); 
read_file('https://'.$host.$uri, false, $stream_context); 
get_file_contents($another_url, false, $stream_context); 
read_file($even_another, false, $stream_context); 

या मैं एक नया पुन: बनाने की जरूरत है प्रत्येक यूआरएल के लिए StreamContext?

अलग से पूछे गए: क्या एक स्ट्रीम संदर्भ पैरामीटर और विकल्पों के लिए सिर्फ एक वर्णक है, या इसका उपयोग करते समय संसाधन से जुड़ा हुआ है?

संपादित करें: यह टिप्पणी से लगता है, कि एक StreamContext अक्सर पुन: उपयोग कर सकते हैं, लेकिन हमेशा नहीं। यह एक जवाब के रूप में काफी संतोषजनक नहीं है।

इसे कब उपयोग किया जा सकता है या इसे कब उपयोग किया जा सकता है? क्या कोई StreamContext के आंतरिक काम पर कुछ प्रकाश डाल सकता है। documentation मेरे लिए काफी अस्पष्ट दिखता है।

+0

आप इसे आज़मा सकते हैं। मैं उम्मीद करता हूं कि यह पुन: प्रयोज्य होगा क्योंकि यह एक संसाधन है जिसे पढ़ा जाता है लेकिन लिखा नहीं जाता है। – apokryfos

+1

मैं कहूंगा कि इसका पुन: उपयोग करने का उद्देश्य है; लेकिन ऐसा लगता है कि इसमें अनपेक्षित परिणाम हो सकते हैं (जब मुझे ठीक से उपयोग नहीं किया जाता है) जैसा कि यहां टिप्पणी की गई है: http://php.net/manual/en/function.stream-context-create.php#117361 – ilpaijin

+0

@ilpaijin यह बिंदु दिलचस्प है । –

उत्तर

1

धारा संदर्भों को फिर से प्रयोग करने योग्य है और वे हमेशा पुन: उपयोग किया जा सकता है, प्रायः नहीं।

@ilpaijin से टिप्पणी "अप्रत्याशित व्यवहार टिप्पणी" की ओर इशारा करते हुए टिप्पणी छोड़ने वाले लेखक की एक गलतफहमी है।

जब आप HTTP wrapper के लिए अपना संदर्भ निर्दिष्ट करते हैं, तो आप उस स्कीमा के बावजूद रैपर को HTTP के रूप में निर्दिष्ट करते हैं, जिसका अर्थ है कि HTTPS wrapper जैसी कोई चीज़ नहीं है।

आपको निम्न कार्य करने का प्रयास करें:

"https" => [ 
// options will not be applied to HTTPS stream as there is no such wrapper (https) 
] 

सही तरीका:

"http" => [ 
// options will apply to http:// and https:// streams. 
] 

जब/फिर से इस्तेमाल कर सकते हैं करना चाहिए?

यह वास्तव में आपके ऊपर और उस तर्क तक है जो आप कार्यान्वित करने का प्रयास कर रहे हैं।

भूलें कि आपके पास native PHP wrappers के लिए डिफ़ॉल्ट संदर्भ सेट है।

उदाहरण आपने पोस्ट किया है उदाहरण जहां आपके पास एक ही संदर्भ धारा 3 अलग-अलग कॉल एस को पारित की जा रही है, अनावश्यक, सरल उपयोग stream_context_set_default है और आपके कोड से उत्पन्न अनुरोध के लिए डिफ़ॉल्ट संदर्भ सेट करें।

कुछ स्थितियों जहाँ आप डिफ़ॉल्ट सेट लेकिन एक विशेष अनुरोध के लिए अलग संदर्भ करना चाहते हैं, यह एक अच्छा विचार एक और धारा बना सकते हैं और इसे पारित करने के लिए किया जाएगा।

धारा संदर्भ होते हैं राज्य, उदाहरण के लिए कुकीज़ या टीएलएस प्रारंभिक वार्तालाप जो एक कॉल से दूसरे में गुजरती हैं?

स्ट्रीम संदर्भ में राज्य नहीं है, हालांकि आप अतिरिक्त कोड के साथ इस तरह एक नकली प्राप्त कर सकते हैं। कोई भी राज्य, इसे कुकी या टीएलएस हैंडशेक होने दें, बस हेडर का अनुरोध करें। आपको उस जानकारी को आने वाले अनुरोध से पढ़ने और इसे स्ट्रीम में सेट करने की आवश्यकता होगी, और फिर उस स्ट्रीम को अन्य अनुरोध पर पास कर दें, इस प्रकार माता-पिता के अनुरोध के "राज्य" का मज़ाक उड़ाया जाए। ऐसा कहा जा रहा है - ऐसा मत करो, बस CURL का उपयोग करें।

एक तरफ, धाराओं की असली शक्ति आपके स्वयं के/कस्टम stream बना रही है। हेडर मैनिपुलेशन और स्टेट कंट्रोल कर्ल के साथ हासिल किया गया बहुत आसान (और बेहतर) है।

+0

यह सवाल है कि विषय को सबसे अच्छी तरह से विस्तृत करता है। Http://php.net/manual/en/function.stream-context-create.php#117361 की आलोचना के बारे में, मुझे लगता है कि यह बिंदु को याद करता है: यह सच है कि 'https' एक रैपर नाम नहीं है, 'tls 'और' एसएसएल' (synonymes) हैं। –

+0

मुझे सहायक प्रश्न के रूप में क्या छोड़ा गया है: क्या धारा संदर्भ में राज्य होता है, उदाहरण के लिए कुकीज या टीएलएस प्रारंभिक वार्ता जो एक कॉल से दूसरे में गुज़रती है? –

+0

हाय लोरेन्ज़, बक्षीस के लिए धन्यवाद। मैंने सहायक प्रश्न और एक टिप जोड़कर जवाब संपादित किया है। ;) – rock3t

1

ऐसा प्रतीत होता है कि आप कर सकते हैं। मैं xdebug_debug_zval का इस्तेमाल किया और अगर पीएचपी वह आंतरिक रूप से बनाए रखना था देखने के लिए कुछ सरल परीक्षण भाग गया

$context = stream_context_create(['https' => ['method' => 'GET']]); 
xdebug_debug_zval('context'); 
$stream = file_get_contents('https://secure.php.net/manual/en/function.file-get-contents.php', false, $context); 
xdebug_debug_zval('context'); 
$stream = fopen('https://secure.php.net/', 'r', false, $context); 
xdebug_debug_zval('context'); 

क्या मैं वापस मिल

संदर्भ था (मैं एक आंतरिक विकास सर्वर पर xdebug साथ पीएचपी 7.1.3 प्रयुक्त) :

(refcount = 1, is_ref = 0) संसाधन (2, धारा-संदर्भ)

संदर्भ:

(refcount = 1, is_ref = 0) संसाधन (2, धारा-संदर्भ)

संदर्भ:

(refcount = 2, is_ref = 0) संसाधन (2, धारा-संदर्भ)

दिलचस्प बात यह है कि दूसरी कॉल ने रेफकाउंट बढ़ाया, जिसका अर्थ यह आंतरिक रूप से संदर्भ द्वारा पारित किया गया था। यहां तक ​​कि $stream को अनसेट करने से भी इसे हटाया नहीं गया है या मुझे इसे फिर से कॉल करने से रोक दिया गया है।

संपादित

के बाद से सवाल संशोधित किया गया था ...

संदर्भ एक resource डेटा प्रकार पैदा करता है। चूंकि इसमें PHP डेटा का एक उदाहरण शामिल है, यह को संदर्भित रूप से संदर्भ से पारित किया गया है, जिसका अर्थ है कि PHP आंतरिक डेटा को सीधे पास कर रहा है और इसकी प्रतिलिपि बना रहा है। एक संदर्भ को नष्ट करने के लिए कोई मूल तरीका नहीं है।

+0

उत्तर के लिए धन्यवाद। यद्यपि यह कड़ाई से सवाल का जवाब देता है कि 'क्या स्ट्रीम स्ट्रीमटेक्स्ट पुन: प्रयोज्य है', यह मेरी अपेक्षा नहीं है। वास्तव में, ऐसे मामले हैं, जहां यह पुन: प्रयोज्य नहीं है, जैसे कि इसमें एक एसएसएल कनेक्शन शामिल होता है (टिप्पणियां देखें)। मैं बेहतर समझना चाहता हूं कि वास्तव में स्ट्रीमकॉन्टेक्स्ट वास्तव में क्या है। इसे कैसे समझें और इसका उपयोग न करें। –

+0

शायद आपको कोड को 'read_file' के लिए साझा करना चाहिए। मैं ऐसे मामले को दोहराना नहीं कर सकता जहां स्ट्रीम संदर्भ का पुन: उपयोग नहीं किया जा सके। PHP फ़ंक्शंस इसे संदर्भ * द्वारा पास करता है * इसलिए इसे कभी भी नष्ट नहीं किया जाना चाहिए – Machavity

1

यह जाहिरा तौर पर एक कनेक्शन वस्तु के रूप में कार्य करता है (डेटाबेस कनेक्शन के साथ की तरह एक ही तर्क) और एक समान तरीके से पुन: उपयोग किया जा सकता है:

<?php 
$default_opts = array(
    'http'=>array(
    'method'=>"GET", 
    'header'=>"Accept-language: en\r\n" . 
       "Cookie: foo=bar", 
    'proxy'=>"tcp://10.54.1.39:8000" 
) 
); 


$alternate_opts = array(
    'http'=>array(
    'method'=>"POST", 
    'header'=>"Content-type: application/x-www-form-urlencoded\r\n" . 
       "Content-length: " . strlen("baz=bomb"), 
    'content'=>"baz=bomb" 
) 
); 

$default = stream_context_get_default($default_opts); 
$alternate = stream_context_create($alternate_opts); 

/* Sends a regular GET request to proxy server at 10.54.1.39 
* For www.example.com using context options specified in $default_opts 
*/ 
readfile('http://www.example.com'); 

/* Sends a POST request directly to www.example.com 
* Using context options specified in $alternate_opts 
*/ 
readfile('http://www.example.com', false, $alternate); 

?> 
+1

ध्यान दें कि प्रश्न 'read_file' का उपयोग कर रहा है और 'readfile' नहीं है। यह एक मामूली अंतर नहीं है – Machavity

+0

हां वास्तव में ... वास्तव में मुझे नहीं पता कि read_file क्या है। मैं जो कहना चाहता था वह यह है कि संदर्भ कस्टम और डिफ़ॉल्ट हो सकते हैं। और कई बार दृश्यों के पीछे डिफ़ॉल्ट संदर्भ का उपयोग किया जा सकता है। इसके अलावा संदर्भों को बंद या पुनर्नवीनीकरण की आवश्यकता नहीं है। इसका मतलब यह होना चाहिए कि वे अनुरोधों के बीच किसी भी राज्य को एकत्र नहीं करते हैं। – DenisSt

-1

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

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