<?php
ob_start();
?>
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Test Page</title>
</head>
<body>
<?php  header("Location: panel.php");  ?>
</body>
</html>

برای رفع مشکل عدم ریدایرکت با تابع header این پست رو دنبال کنید و نگران نباشید

همونطور که در پست  آشنایی با تابع headerدر php   شرح دادیم یکی از کاربردهای تابع header ریدایرکت کاربر به صفحات دیگر میباشد ولی گاهی اوقات این عمل به مشکل بر میخوره و دلیلش رو هم در اینجا میگم 

همونطور که میدونید زبان php یک زبان مفسری است ، یعنی مفسر آپاچی وقتی فایل های php شما رو باز میکنه ، خط به خط کدها رو تفسیر و برای مرورگر میفرسته که با شروع ارسال اولین خط از یک فایل اطلاعات هدر هم پر میشه و به مرورگر ارسال میشه و کم کم خط های بعدی تفسیر و نتیجه به مرورگر ارسال میشه ، نکته همینجاست که چون مرورگر بصورت پیشفرض در زمان آغاز به ارسال یک فایل به مرورگر کلاینت اطلاعاتی تحت عنوان هدر رو میسازه و برای مرورگر ارسال میکنه بنابراین وقتی ما بعد از ارسال هدر در خطوط پایین تر از تابع header استفاده میکنیم اجازه تغییر در اطلاعات هدر رو نمیده و پیغام میده که هدر از قبل ساخته شده و برای مرورگر ارسال شده و شما دیگر نمی توانید آنرا تغییر دهید . البته ما فرض رو بر این گذاشتیم که شما مطلب آشنایی با تابع header در php  رو مطالعه نموده اید و با این تابع آشنا هستید.

معمولا خطای این تابع در اکثر مواقع بشکل زیر ظاهر میشود :

 (Warning: Cannot modify header information – headers already sent by (output 

لذا همونطور که گفتیم شما قبل از دستور header به خروجی مقداری رو ارسال کردید و همین عامل باعث شده که اطلاعات هدر توسط خود سرور تولید و برای مرورگر ارسال بشه و دیگر به شما اجازه نده که هدر رو تغییر بدید.

برای حل این مشکل php یک تابع خوب در نظر گرفته که شما میتونید این تابع رو فراخوانی کنید تا سیستم بافرینگ برای اون صفحه فعال بشه 

بافرینگ برای این هستش که سرور بجای ارسال خط به خط خروجی به مرورگر همه اطلاعات رو درون حافظه بافر خودش ذخیره میکنه و وقتی به پایان فایل رسید این اطلاعات رو یکجا از حافظه بافر بر میداره و برای مرورگر میفرسته که حتی این روش مزیت های زیادی دهم برای سرور داره و کارائی سرور بدلیل مکانیزم عمل این نوع ارسال بسیار بالا میره و در ترافیک مصرفی و منابع مصرفی کامپیوتر سرور نیز صرفه جویی میشه که میتونید در اینترنت مقالات زیادی رو در این باره پیدا کنید.

البته شما میتونستید حتی بدون فعال کردن خاصیت بافرینگ php این مشکل رو حل کنید و اونم به این شکل که از تابع header قبل از ارسال چیزی به مرورگر استفاده کنید ولی در بسیاری از مواقع ما در اواسط یک صفحه و بعد از ارسال یکسری مقادیر نیاز داریم تا هدر رو تغییر بدیم که در اینصورت بهترین راهکار همون بافر کردن اطلاعات تا پایان تصمیم گیری اسکریپت هست .

برای فعال کردن خاصیت بافرینگ سرور به دو روش میتونید اقدام کنید : یکی اینکه وارد فایل php.ini بشید و این خاصیت رو فعال کنید . روش دیگر اینکه با استفاده از تابعی بنام ob_start این خاصیت رو فعال کنید ک تفاوتشون در این هست که اگر از روش اول استفاده کنید سرور در ارسال اطلاعات کلیه فایلهای شما به روش بافرینگ اقدام خواهد کرد ولی اگر از تابع استفاده کنید سرور فقط در ارسال فایلهایی از خاصیت بافرینگ استفاده خواهد کرد که این تابع استارت زده شده باشد .

محل نوشتن این تابع هم دقیقا در ابتدای صفحه و قبل از هر دستوری(حتی قبل از سشن ها) میباشد .

تابع ob_start هم می توانید بدون پارامتر فراخوانی بشه و هم با پارامتر که پارامترهایی هم که می پذیره اعم از حداکثر حجم بافرینگ و زمان انقضا هست که میتونید در مستندات php جزئیاتش رو بخونید ولی میخوام در اینجا یکی از پارامترهای خوبش رو بگم که برای فشرده سازی اطلاعات کاربرد داره که بصورت رشته ای باید به تابع داده بشه - بصورت زیر :

 

<?php
ob_start("ob_gzhandler");
?>

 

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

 

<?php
ob_start();
?>
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Test Page</title>
</head>
<body>
<?php  header("Location: panel.php");


ob_flush();
?>
</body>
</html>

تابع زیر فقط اطلاعات بافر تا اون نقطه از صفحه رو که نگه داشته رو میفرسته و همچنان سرور به پر کردن بافر ادامه میده

ob_flush();

وقتی که تصمیم گرفتیم تا اطلاعات بافر رو با تابع بالا  به مرورگر ارسال کنیم ، سرور همچنان به ذخیره محتوا درون حافظه بافر ادامه میده ولی ما میتونیم با استفاده از تابع زیر به سرور بگیم که دیگه توی بافر چیزی رو ذخیره نکن :

ob_end_flush();

و حتی می تونیم کل محتویات ذخیره شده در حافظه بافر رو با تابع زیر پاکسازی کنیم :

ob_clean();

ولی اگر php همچنان در حال ذخیره سازی در بافر باشه ، حتی بعد از اجرای تابع فوق ذخیره سازی از نقطه پاکسازی به بعد ادامه خواهد داشت که میتونیم با استفاده از تابع زیر به php بفهمانیم که وقتی بافر رو پاک کردی ، دیگر ذخیره سازی هم انجام نده :

ob_end_clean();

 

و در آخر هم یه تابع دیگه هم داریم که میتونیم با استفاده از اون محتویات داخل بافر رو در هر لحظه بدست بیاریم :

ob_get_content();