2012-05-14 16 views
19

निष्पादित करना जारी रखें मेरे पास ob_start() और संबंधित ob_flush() है। मैं डेटा के एक हिस्से को फ्लश करना चाहता हूं और बाकी को निष्पादित करना जारी रखूंगा। ob_flush() का उपयोग करने में मदद नहीं मिली। यदि ब्राउज़र में लोडिंग दिखाए बिना भी संभव हो तो बाकी की जरूरत है।ब्राउज़र पर डेटा कैसे फ़्लश करें लेकिन

संपादित करें:

मैं ajax

+0

पहले ob_flush करने के बाद, क्या आप अन्य आउटपुट दिखाना चाहते हैं? या क्या आप चाहते हैं कि ग्राहक पूरी तरह से पूरा होने तक अनुरोध कर सके और फिर पृष्ठभूमि में कुछ प्रकार की प्रसंस्करण जारी रहे? – Corbin

+0

पृष्ठभूमि में जारी रखें – aWebDeveloper

+0

ठीक है, मेरे उत्तर को अपडेट किया है। – Corbin

उत्तर

15

ob_flush उपयोग करने के लिए नहीं करना चाहती बफर लिखता है। दूसरे शब्दों में, ob_flush PHP को अपाचे (या nginx/lighttpd/जो कुछ भी) आउटपुट देने के लिए बताता है और उसके बाद PHP को इसके बारे में भूल जाता है। एक बार अपाचे के आउटपुट होने के बाद, यह जो कुछ भी चाहता है वह करता है। (दूसरे शब्दों में, ob_flush के बाद यह आपके नियंत्रण से बाहर है या नहीं, यह तुरंत ब्राउज़र पर लिखा जाता है)।

तो, संक्षिप्त उत्तर: ऐसा करने के लिए कोई गारंटीकृत तरीका नहीं है।

बस एक अनुमान है, आप शायद AJAX की तलाश कर रहे हैं। जब भी लोग आपके द्वारा किए जा रहे पृष्ठ सामग्री लोड करते समय हेरफेर करने की कोशिश कर रहे हैं, तो AJAX लगभग हमेशा सही पथ है।

यदि आप पृष्ठभूमि में कोई कार्य जारी रखना चाहते हैं, तो आप विस्तृत here के रूप में ignore_user_abort का उपयोग कर सकते हैं, हालांकि, यह अक्सर इष्टतम दृष्टिकोण नहीं है। आप अनिवार्य रूप से उस धागे पर नियंत्रण खो देते हैं, और मेरी राय में, एक वेब सर्वर धागा नहीं है जहां भारी प्रसंस्करण संबंधित है।

मैं इसे वेब चेहरे से बाहर निकालने का प्रयास करूंगा। इसका मतलब क्रॉन एंट्री या PHP के अंदर से पृष्ठभूमि प्रक्रिया को उत्पन्न करना हो सकता है (एक प्रक्रिया जो स्क्रिप्ट निष्पादन के अंदर से शुरू होती है, स्क्रिप्ट के साथ मर नहीं जाएगी, और स्क्रिप्ट मरने से पहले खत्म होने की प्रतीक्षा नहीं करेगा)।

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

+1

जब कोई नया उपयोगकर्ता लॉग इन करता है तो मैं बहुत कुछ सहेजना चाहता हूं डेटा। यह डेटा तत्काल सहेजा जाना चाहिए, लेकिन उपयोगकर्ता को बाधित नहीं करना i.e ब्राउज़र पर लोडिंग दिखा रहा है – aWebDeveloper

1

मेरे पास एक लेख है जो यह बताता है कि यह मेरे ब्लॉग पर apache/mod_php का उपयोग करके कैसे प्राप्त किया जा सकता है : http://codehackit.blogspot.com/2011/07/how-to-kill-http-connection-and.html आशा इस मदद करता है, चियर्स

+7

यदि आप यहां पर काम करते हैं, तो यह एक छोटा सा स्निपेट जोड़ता है, तो यह उपयोगी होगा, इसलिए यदि आपकी साइट कभी भी नीचे जाती है, तो हमारे पास अभी भी इसका जवाब है। आपके ब्लॉग पोस्ट में लिखा गया कोड काम करता है। हालांकि, अगर आपने अपनी सामग्री को gzip करने से पहले अपाचे को बताया है, तो यह अब काम नहीं करेगा (चूंकि लंबाई अब और सही नहीं होगी) – Zombaya

-1

उपयोग:

header("Content-Length: $len"); 

..where $len डेटा की लंबाई ग्राहक के लिए प्लावित किया जाना है।

मैं पृष्ठभूमि पता करने के लिए कब और कहाँ यह काम करने के लिए जा रहा है नहीं है, लेकिन मैं कुछ ब्राउज़रों पर की कोशिश की है, और सभी के साथ तुरंत लौट आए:

<?PHP 
    header("Content-length:5"); 
    echo "this is more than 5"; 
    sleep(5); 
?> 

संपादित करें: क्रोम, आईई, और ओपेरा ने this दिखाया, जबकि फ़ायरफ़ॉक्स ने this is more than 5 दिखाया। हालांकि उन सभी ने इसके बाद अनुरोध बंद कर दिया।

+0

यही कारण है कि सामग्री-लंबाई वास्तविक सामग्री के बराबर लंबाई की होनी चाहिए। और gzip से सावधान रहें, क्योंकि इससे आपकी प्रतिक्रिया की लंबाई में संशोधन होगा। – Zombaya

+0

@ ज़ोम्बाया, मैं नहीं देखता कि यह कैसे प्रासंगिक है। जब तक वह एक निश्चित राशि के बाद अपने आउटपुट को काटने की कोशिश नहीं कर रहा है, तब तक आवश्यक डेटा भेजने के बाद अनुरोध समाप्त करने के लिए काम करना चाहिए। – mowwwalker

+0

ठीक है, जब मैंने इसे करने की कोशिश की और लंबाई वास्तविक लंबाई से मेल नहीं खाती, तो कनेक्शन हमेशा बंद नहीं होता और लोडिंग पर नहीं रहता। – Zombaya

15

मैंने पहले भी यह किया है और यह मैं कैसे इसे हल है:

ob_start(); 

/* 
* Generate your output here 
*/ 

// Ignore connection-closing by the client/user 
ignore_user_abort(true); 

// Set your timelimit to a length long enough for your script to run, 
// but not so long it will bog down your server in case multiple versions run 
// or this script get's in an endless loop. 
if ( 
    !ini_get('safe_mode') 
    && strpos(ini_get('disable_functions'), 'set_time_limit') === FALSE 
){ 
    set_time_limit(60); 
} 

// Get your output and send it to the client 
$content = ob_get_contents();   // Get the content of the output buffer 
ob_end_clean();      // Close current output buffer 
$len = strlen($content);    // Get the length 
header('Connection: close');   // Tell the client to close connection 
header("Content-Length: $len");  // Close connection after $len characters 
echo $content;      // Output content 
flush();        // Force php-output-cache to flush to browser. 
            // See caveats below. 

// Optional: kill all other output buffering 
while (ob_get_level() > 0) { 
    ob_end_clean(); 
} 

जैसा कि मैंने पहले टिप्पणी के एक जोड़े में कहा, आप अपनी सामग्री gzipping के लिए बाहर देखना चाहिए, क्योंकि ऐसा करना बदल देगा आपकी सामग्री की लंबाई, लेकिन इसके बारे में हेडर नहीं बदलना।यह आपके आउटपुट को बफर भी कर सकता है, इसलिए यह तुरंत क्लाइंट को नहीं भेजेगा।
आप apache_setenv('no-gzip', '1'); का उपयोग करके अपाचे को अपनी सामग्री को gzip नहीं करने का प्रयास कर सकते हैं। लेकिन यदि आप अपने पृष्ठ पर जाने के लिए रीराइट-नियमों का उपयोग करते हैं, तो यह काम नहीं करेगा, तब से यह उन पर्यावरण चर को भी संशोधित करेगा। कम से कम, यह मेरे लिए ऐसा किया।

manual में उपयोगकर्ता को अपनी सामग्री को फ़्लश करने के बारे में अधिक चेतावनी देखें।

+0

बस एक एफवाईआई PHP फ़ंक्शन ob_get_content ** एस ** –

+1

जानबूझकर त्रुटि को स्पॉट करें। $ लेन! = $ आकार; –

+1

@LukeOliff, हेड-अप के लिए धन्यवाद, इसे बदल दिया। – Zombaya

4
इस

मेरी समारोह

function bg_process($fn, $arr) { 
    $call = function($fn, $arr){ 
     header('Connection: close'); 
     header('Content-length: '.ob_get_length()); 
     ob_flush(); 
     flush(); 
     call_user_func_array($fn, $arr); 
     }; 
    register_shutdown_function($call, $fn, $arr); 
    } 

है समारोह अंत में निष्पादित किया जाना लपेट, php के बाद कनेक्शन बंद। और निश्चित रूप से ब्राउज़र बफरिंग बंद कर देगा।

function test() { 
    while (true) { 
     echo 'this text will never seen by user'; 
     } 
    } 

यह कैसे समारोह

bg_process('test'); 

पहला तर्क callable है, दूसरा तर्क एक सरणी एक अनुक्रमित सरणी

नोट के साथ 'परीक्षण' समारोह के लिए पारित किया जा रहा है कॉल करने के लिए है: मैं स्क्रिप्ट की शुरुआत में ob_start() का उपयोग नहीं करता हूं।

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