Keramatifar
یک شنبه 28 آذر 1389, 19:39 عصر
بافر کردن خروجي و خطاي Cannot modify header information
بافر کردن خروجي (Output buffering) چيست؟
اگر خروجي کد، html يا جاوا اسکريپت باشد يا از echo و print در php استفاده کرده باشيد، اين اطلاعات به مرورگر فرستاده مي شود. با استفاده از بافر کردن خروجي، اين اطلاعات ابتدا بر روي سرور ذخيره می شود تا زماني که يا اجراي اسکريپت پايان يابد يا اين که شما دستوراتی را روي محتواي بافر اجرا نماييد.
در PHP، خروجي به صورت پيش فرض بافر نمي شود، محتويات خروجي همان طور که ايجاد مي شوند، به مرورگر فرستاده مي شوند. توابع به کار گرفته شده براي بافر کردن خروجي، خروجي را بافر نموده و ضمن ارسال، امکان کنترل بر روي آن را نيز مي دهند مانند مجوز فشرده سازي محتوا. همچنين اين توابع، اجازه ايجاد ترکيبي از هدرها (headers) و محتوا را با هم مي دهند بدون اين که خطاي "Cannot modify header information - headers already sent" صادر شود.
خطاي Cannot modify header information - headers already sent
خطاي بالا زماني نمايش داده مي شود که محتوا قبل از ارسال هدر (مانند تنظيم يک کوکي، ارسال به صفحه جديد و ...) به خروجي فرستاده شود. در نتيجه، هدرها بايد قبل از ارسال هر گونه خروجي، تنظيم شوند در غير اين صورت، خطاي بالا نمايش داده مي شود.
(کوکي به عنوان يک HTTP header توسط سرور وب به مرورگر وب فرستاده مي شود و سپس بدون تغيير توسط مرورگر با ارسال هر درخواست به سمت سرور ارسال مي شود)
بهترين روش اين است که مطمئن شويم همه هدرها قبل از ارسال خروجي ها، تنظيم شده اند. گاهي اوقات ساده تر اين است که از بافر کردن خروجي استفاده کنيم که موجب حذف اين پيغام خطا خواهد شد. هنگامي که بافر کردن خروجي فعال باشد، همه هدرها فرستاده خواهند شد در حالي که محتوا يا در پايان اسکريپت ارسال خواهد شد يا هنگامي که صريحا توسط اسکريپت با دستوراتي اجرا مي شود.
چگونه بافر خروجي را فعال نماييم
براي فعال نمودن بافر خروجي، ob_start(); را در ابتداي اسکريپت php اضافه مي نماييم قبل از اين که چيزي به مرورگر ارسال شود حتي يک فاصله در غير اين صورت خطا توليد مي شود. براي فعال نمودن فشرده سازي gzip نيز، کد زیر را نیز اضافه مي نماييم.
ob_start(“ob_gzhandler”);
گرفتن محتويات بافر خروجي
امکان اين که محتويات بافر را به عنوان يک رشته بگيريم وجود دارد لذا مي توانيم آن را در يک فايل مانند فايل log ذخيره يا به عنوان يک ايميل بفرستيم. همچنين در php توابعي براي چاپ خروجي به جاي در نظر گرفتن يک رشته نيز وجود دارد.
$content = ob_get_content();: گرفتن محتوا و بازگرداندن آن در متغير $content را نشان مي دهد يعني هر آن چه که شما چاپ نموده يا به صورت ديگري به سمت مرورگر فرستاده ايد که بين اين دستور و دستور ob_start() وجود دارد، در متغير $content ذخيره خواهد شد.
$content = ob_get_clean();
گرفتن محتوا و سپس خالي نمودن بافر را نشان مي دهد
ارسال محتويات بافر خروجي به مرورگر (flush)
بافر مي تواند در هر زماني به طور صريح با استفاده از توابع زير خالي و به سمت مرورگر ارسال شود.
تابع ob_flush()، محتواي بافر را براي مرورگر، ارسال و آن را خالي مي نمايد. در ضمن عمل بافرينگ در صورت خروجي بيشتر، ادامه مي يابد.
تابع ob_end_flush()، مانند تابع بالا عمل نموده با اين تفاوت که عمل بافرينگ را ادامه نمي دهد. در صورت وجود محتواي بيشتر، مستقيما به خروجي فرستاده مي شود.
تابع ob_get_flush(): مانند تابع ob_end_flush() عمل نموده محتوا را به صورت رشته بر مي گرداند.
خالي نمودن بافر خروجي
براي خالي نمودن محتويات جاري بافر خروجي از ob_end_clean() استفاده مي نماييم.
تابع ob_clean(): اگر بخواهيد هر آن چه در بافر خروجي ذخيره شده را خالي نموده تا براي مرورگر کلاينت ارسال نشود و يا يک صفحه جديد بسازيد، از اين تابع استفاده نماييد. اين تابع، مانند تابع ob_flush()، عمل بافرينگ را ادامه مي دهد.
تابع ob_end_clean(): مانند تابع ob_clean() عمل نموده با اين تفاوت که عمل بافرينگ را ادامه نمي دهد. يعني بافر را خالي و سپس بافرينگ را متوقف مي سازد.
مثال: تغيير مقدار يک قسمت از صفحه:
<?php
ob_start('changeValue');
?>
<html>
<body>
<p>Hello world!</p>
</body>
</html>
<?php
ob_end_flush();
function changeValue ($buffer)
{
$buffer = str_replace('Hello', 'Hi', $buffer);
return $buffer;
}
?>
منبع:
http://keramatifar.ir/ShowTopic.php?id=%2057
بافر کردن خروجي (Output buffering) چيست؟
اگر خروجي کد، html يا جاوا اسکريپت باشد يا از echo و print در php استفاده کرده باشيد، اين اطلاعات به مرورگر فرستاده مي شود. با استفاده از بافر کردن خروجي، اين اطلاعات ابتدا بر روي سرور ذخيره می شود تا زماني که يا اجراي اسکريپت پايان يابد يا اين که شما دستوراتی را روي محتواي بافر اجرا نماييد.
در PHP، خروجي به صورت پيش فرض بافر نمي شود، محتويات خروجي همان طور که ايجاد مي شوند، به مرورگر فرستاده مي شوند. توابع به کار گرفته شده براي بافر کردن خروجي، خروجي را بافر نموده و ضمن ارسال، امکان کنترل بر روي آن را نيز مي دهند مانند مجوز فشرده سازي محتوا. همچنين اين توابع، اجازه ايجاد ترکيبي از هدرها (headers) و محتوا را با هم مي دهند بدون اين که خطاي "Cannot modify header information - headers already sent" صادر شود.
خطاي Cannot modify header information - headers already sent
خطاي بالا زماني نمايش داده مي شود که محتوا قبل از ارسال هدر (مانند تنظيم يک کوکي، ارسال به صفحه جديد و ...) به خروجي فرستاده شود. در نتيجه، هدرها بايد قبل از ارسال هر گونه خروجي، تنظيم شوند در غير اين صورت، خطاي بالا نمايش داده مي شود.
(کوکي به عنوان يک HTTP header توسط سرور وب به مرورگر وب فرستاده مي شود و سپس بدون تغيير توسط مرورگر با ارسال هر درخواست به سمت سرور ارسال مي شود)
بهترين روش اين است که مطمئن شويم همه هدرها قبل از ارسال خروجي ها، تنظيم شده اند. گاهي اوقات ساده تر اين است که از بافر کردن خروجي استفاده کنيم که موجب حذف اين پيغام خطا خواهد شد. هنگامي که بافر کردن خروجي فعال باشد، همه هدرها فرستاده خواهند شد در حالي که محتوا يا در پايان اسکريپت ارسال خواهد شد يا هنگامي که صريحا توسط اسکريپت با دستوراتي اجرا مي شود.
چگونه بافر خروجي را فعال نماييم
براي فعال نمودن بافر خروجي، ob_start(); را در ابتداي اسکريپت php اضافه مي نماييم قبل از اين که چيزي به مرورگر ارسال شود حتي يک فاصله در غير اين صورت خطا توليد مي شود. براي فعال نمودن فشرده سازي gzip نيز، کد زیر را نیز اضافه مي نماييم.
ob_start(“ob_gzhandler”);
گرفتن محتويات بافر خروجي
امکان اين که محتويات بافر را به عنوان يک رشته بگيريم وجود دارد لذا مي توانيم آن را در يک فايل مانند فايل log ذخيره يا به عنوان يک ايميل بفرستيم. همچنين در php توابعي براي چاپ خروجي به جاي در نظر گرفتن يک رشته نيز وجود دارد.
$content = ob_get_content();: گرفتن محتوا و بازگرداندن آن در متغير $content را نشان مي دهد يعني هر آن چه که شما چاپ نموده يا به صورت ديگري به سمت مرورگر فرستاده ايد که بين اين دستور و دستور ob_start() وجود دارد، در متغير $content ذخيره خواهد شد.
$content = ob_get_clean();
گرفتن محتوا و سپس خالي نمودن بافر را نشان مي دهد
ارسال محتويات بافر خروجي به مرورگر (flush)
بافر مي تواند در هر زماني به طور صريح با استفاده از توابع زير خالي و به سمت مرورگر ارسال شود.
تابع ob_flush()، محتواي بافر را براي مرورگر، ارسال و آن را خالي مي نمايد. در ضمن عمل بافرينگ در صورت خروجي بيشتر، ادامه مي يابد.
تابع ob_end_flush()، مانند تابع بالا عمل نموده با اين تفاوت که عمل بافرينگ را ادامه نمي دهد. در صورت وجود محتواي بيشتر، مستقيما به خروجي فرستاده مي شود.
تابع ob_get_flush(): مانند تابع ob_end_flush() عمل نموده محتوا را به صورت رشته بر مي گرداند.
خالي نمودن بافر خروجي
براي خالي نمودن محتويات جاري بافر خروجي از ob_end_clean() استفاده مي نماييم.
تابع ob_clean(): اگر بخواهيد هر آن چه در بافر خروجي ذخيره شده را خالي نموده تا براي مرورگر کلاينت ارسال نشود و يا يک صفحه جديد بسازيد، از اين تابع استفاده نماييد. اين تابع، مانند تابع ob_flush()، عمل بافرينگ را ادامه مي دهد.
تابع ob_end_clean(): مانند تابع ob_clean() عمل نموده با اين تفاوت که عمل بافرينگ را ادامه نمي دهد. يعني بافر را خالي و سپس بافرينگ را متوقف مي سازد.
مثال: تغيير مقدار يک قسمت از صفحه:
<?php
ob_start('changeValue');
?>
<html>
<body>
<p>Hello world!</p>
</body>
</html>
<?php
ob_end_flush();
function changeValue ($buffer)
{
$buffer = str_replace('Hello', 'Hi', $buffer);
return $buffer;
}
?>
منبع:
http://keramatifar.ir/ShowTopic.php?id=%2057