PDA

View Full Version : حرفه ای: کار با output buffering



alimooghashang
جمعه 06 فروردین 1389, 19:50 عصر
با سلام
چطوری میشه یه با output buffering کار کرد؟
مثل من میخوام یه while بنویسم که از 0 تا 5000 بنویسه ولی هرکدوم را که echo میکنه روی صفحه به کاربر نشون بده!!!

نه اینکه مثلا یهو 100 تاشو نشون بده

با تشکر

digitak
شنبه 07 فروردین 1389, 12:51 عصر
منم نیاز دارم !
کسی بلده بگه

digitak
شنبه 07 فروردین 1389, 15:51 عصر
من توی php.net جستجو کردم و یه کد خیلی خوب پردا کردم که این کار رو امجام میده :
توی خط اول باید بگی که می خوای از این OB(Output Buffering) استفاده کنی !

ob_start();

بعد هر بار که می خوای خروجی ارسال بشه باید یه فلاش زده بشه اونم با تابع های زیر :


ob_flush();
flush();


اینم یه نمونه کد :


<?PHP
ob_start(); // Start output buffer (if not enabled in php.ini)
for($i=0; $i < 10; $i++)
{
echo $i, ' ';
ob_flush();
flush();
sleep(1);
}
?>

امیـرحسین
شنبه 07 فروردین 1389, 18:26 عصر
من از اونجاییکه به این موضوع علاقمند بودم رفتم php.net رو بالا پایین کردم و تونستم کد پست قبلی رو تکمیل کنم.
نکته اول اینکه ob_start باید یکبار اجرا بشه. این کار رو توسط تابع ()ob_get_level انجام میدهند. با این شرط کد بالا باید کار کنه ولی مرورگرها اگر خروجی بافر از 256 بایت کمتر باشه، صفحه رو آپدیت نمی کنند. پس با چاپ i$ که یک فقط یک کاراکتره، خروجی تغییر نمی کنه.
کد زیر یک Progress Bar که با این توابع ساخته شده و من از یکی از کامنتهای تابع flush (http://www.php.net/manual/en/function.flush.php#81749) برش داشتم:
<html>
<head>
<style type="text/css">
div {
margin: 1px; height: 20px; padding: 1px; border: 1px solid #000; width: 275px;
background: #fff; color: #000; float: left; clear: right; top: 38px; z-index: 9
}
.percents {
background: #FFF; border: 1px solid C#‎‎‎CC; margin: 1px; height: 20px;
position:absolute; width:275px; z-index:10; left: 10px; top: 38px; text-align: center;
}
.blocks {
background: #EEE; border: 1px solid C#‎‎‎CC; margin: 1px; height: 20px; width: 10px;
position: absolute; z-index:11; left: 12px; top: 38px; filter: alpha(opacity=50);
-moz-opacity: 0.5; opacity: 0.5; -khtml-opacity: .5
}
</style>
</head>
<body>

<?php

if (ob_get_level() == 0) {
ob_start();
}

echo str_pad('Loading... ', 256)."<br />\n";
$d = 1;
for ($i = 0; $i < 25; $i++) {
$d = $d + 11;
$m=$d+10;
//This div will show loading percents
echo '<div class="percents">' . $i*4 . '%&nbsp;complete</div>';
//This div will show progress bar
echo '<div class="blocks" style="left: '.$d.'px">&nbsp;</div>';
flush();
ob_flush();
sleep(1);
}
ob_end_flush();
?>
<div class="percents" style="z-index:12">Done.</div>
</body>
</html>
تابع flush همه اطلاعاتی که باید به بافر بفرستاده بشه رو همون موقع به بافر میفرسته و تابع ob_flush که بعدش میاد، محتوای بافر رو به خروجی یا مرورگر میفرسته که چاپ شه.

alimooghashang
یک شنبه 08 فروردین 1389, 19:59 عصر
مرسی
دقیقا همین را میخواستم

alimooghashang
یک شنبه 08 فروردین 1389, 20:01 عصر
حالا یه سوال دیگه
میشه قبل از اینکه ob_flush میدیم که برای کاربر نشون بده، سورس قبلی رو بعنوان string بگیریم و تغییر بدیم و بعد نشون بدیم؟

امیـرحسین
یک شنبه 08 فروردین 1389, 20:53 عصر
شاید با SESSION بشه.