گیک فارسی

نوشته های یک گیک فارسی از فعالیت ها ،‌ علاقه مندی ها و نقد هایش

توضیحات مختصر و مفید در مورد خطای Headers Already Sent در PHP

نویسنده:
25 ژوئن 15

یکی از متداول ترین پرسش های برنامه نویسان در انجمن‌های PHP در مورد خطای Headers Already Sent هست.PHP به صورت عادی اطلاعات را Buffer نمیکنه ، یعنی خروجی ها را در لحظه ارسال میکنه ، خیلی ساده اگه بخوام بگم ، ارسال ها را به دو دسته تقسیم میکنیم یکی Header ها و دیگری Content یا همون محتوا ،‌Header ها قبل از محتوا ارسال میشن و این یک قرارداد بر اساس HTTP Protocol هست.

headers already sent

PHP وقتی شما اولین مقدار حالا بایت یا کاراکتر یا هر چی را ارسال میکنید ابتدا Header های استاندارد و اونهایی که شما با تابع ()header ارسال کردین را میفرسته و بعدش شروع به ارسال محتوا میکنه. حالا اگه شما بعد از ارسال محتوا تابع ()header را صدا بزنین خیلی طبیعیه که PHP بگه Header ها را ارسال کردم و نمیشه شما Header دیگری بفرستی !

این محتوا بعضی مواقع میتونه یک Space هم باشه یا کاراکتری که به چشم نمیاد مثل BOM که ادیتور ها برای فایل های یونیکد اضافه میکنن یا خطایی که PHP داره در موردش توی خروجی توضیح میده یا ممکنه خود شما بدون اینکه متوجه باشین دارین یک مقداری را با echo یا print ارسال میکنید.
در زمانی که این خطا را میبینید PHP در انتهای توضیح با Output Started At اشاره میکنه که اولین خروجی در چه فایلی و کجاش ارسال شده که میشه با بررسی اون فایل متوجه مشکل شد و اون را رفع کرد. راه دیگه این هست که با یک درخواست Http از یک نرم افزار مثل wget توی لینوکس یا هر چیز متشابه دیگه توی ویندوز بیایم و خروجی را بررسی کنیم و ببینیم داره چی ارسال میشه و بعدش اون مقدار را توی فایل هامون جستجو و مرتفع کنیم.

اگه بخوایم این حالت را نداشته باشیم و رفتاری شبیه به ASP .NET داشته باشیم باید به PHP بگیم خروجی را در لحظه ارسال نکنه و اون را Buffer کنه و در آخر همه را با هم اعم از Header و خروجی ارسال کنه. برای این کار از Output Buffering استفاده میکنیم. برای این کار قبل از شروع کد ها تابع ()ob_start را صدا میزنیم و در آخر هم ()ob_end_flush باعث ارسال اطلاعات به مرورگر کاربر میشه.

به طور کلی Output Buffering را فقط زمانی توصیه میکنم که واقعاً قصد دخل و تصرف در محتوا قبل از ارسال به کاربر را داشته باشین و در غیر این صورت روش معمول کفایت میکنه و بهتره با کمی صبر و بررسی مشکل ارسال Header را بررسی کنید.