PDA

View Full Version : تابع ob_start و ob_end_flush



esmahdi
چهارشنبه 20 مهر 1390, 12:20 عصر
سلام
ببخشید خواستم بدونم توابع ob_start و ob_end_flush چه کاربردی دارند.
تو اینترنت و انجمن که جستجو کردم چیز خاصی متوجه نشدم.
آیا این توابع تاثیری تو امنیت هم دارند؟
با تشکر

webpower
چهارشنبه 20 مهر 1390, 13:01 عصر
امنیتش رو نمیدونم ولی یه ربطی به headerها داره بعضی اوقات که کوکی فرستاده نمیشه و ارور header already sent میده به کمک این دو تابع میشه مشکل رو حل کرد

Freedom777
چهارشنبه 20 مهر 1390, 13:26 عصر
ob که اول اسم این دو تابع هست به معنای Output buffering هست.
موقعی که ob_start رو اجرا میکنید، خروجی های شما (بطور مثال رشته هایی که echo میکنید) بافر (ذخیره موقت در حافظه) میشه بجای اینکه همون موقع فورا به کلاینت ارسال بشه، و موقعی که ob_end_flush رو اجرا میکنید هرچی در بافر ذخیره شده به کلاینت ارسال شده و بافر خالی میشه.

قاعدتا اینا نباید هیچ ربطی به امنیت داشته باشن.

ضمنا ممکنه Output buffering بصورت پیشفرض فعال باشه.

Freedom777
چهارشنبه 20 مهر 1390, 20:46 عصر
البته باید توجه داشته باشید که استفاده از ob_flush برای اطمینان از اینکه خروجی ها فورا به سمت کلاینت ارسال میشن کافی نیست.
باید بعد از استفاده از ob_flush یا ob_end_flush، تابع flush رو هم اجرا کنید. چون بافرشدگی های دیگری در سطوح دیگر و حتی در آپاچی وجود دارن که این تابع سعی میکنه محتوای تمام اون بافرها رو ارسال کنه. اینکه میگم سعی میکنه بخاطر اینکه در بعضی موارد که البته تعدادش باید خیلی کم باشه، ممکنه PHP نتونه بافر وب سرور رو ارسال کنه.

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

Freedom777
چهارشنبه 20 مهر 1390, 20:54 عصر
اینکه از Output buffering برای جلوگیری از خطای headers already sent استفاده میشه بخاطر اینه که در پروتکل HTTP تمام هدرها باید قبل از محتوای اصلی سند (بدنهء سند) به کلاینت ارسال بشن. بنابراین وقتی شما یک چیزی رو echo میکنید، که طبیعتا اون چیز بخشی از محتوای اصلی سند بحساب میاد، بعدش دیگه نمیشه هیچ هدری رو ارسال کرد؛ چون بخش مربوط به هدرها قبلا ارسال و انتهای اون برای مرورگر علامتگذاری شده و هرچیز دیگری که بعدش توسط مرورگر دریافت بشه بعنوان جزیی از بدنهء سند تلقی میشه.

اما وقتی از Output buffering استفاده میشه، PHP خروجی echo های ما رو فورا به کلاینت ارسال نمیکنه و بنابراین هنوز میتونه هدرها رو بپذیره و بعد موقعی که ob_flush اجرا میشه همهء هدرها رو یکجا قبل از بدنهء سند به کلاینت ارسال میکنه و بعدش هم تمام محتوای اصلی سند رو.

idocsidocs
پنج شنبه 21 مهر 1390, 18:21 عصر
اینکه از Output buffering برای جلوگیری از خطای headers already sent استفاده میشه بخاطر اینه که در پروتکل HTTP تمام هدرها باید قبل از محتوای اصلی سند (بدنهء سند) به کلاینت ارسال بشن.من توی کتابهای آموزشی خوندم که مشکل قرار گرفتن توابع هدر در ابتدای صفحه فقط توی پی اچ پی هست و زبانهایی مثل جاوا و ای اس پی این مشکل رو ندارن.

پس در نتیجه این مشکل مربوط به پروتکل HTTP نیست. نظرتون چیه؟

MMSHFE
پنج شنبه 21 مهر 1390, 19:16 عصر
من توی کتابهای آموزشی خوندم که مشکل قرار گرفتن توابع هدر در ابتدای صفحه فقط توی پی اچ پی هست و زبانهایی مثل جاوا و ای اس پی این مشکل رو ندارن.
پس در نتیجه این مشکل مربوط به پروتکل HTTP نیست. نظرتون چیه؟
دوست عزيز اين مسئله، يك مشكل نيست. اتفاقاً يك مزيت در PHP هست كه ميتونيد محتواي صفحه رو قطعه قطعه براي كلاينت بفرستين اما توي پروتكل HTTP اعلام شده كه اگه بخشي از داده ها دريافت بشه، ديگه نميشه هدر رو تغيير داد. براي رفع اين مشكل، از بافر خروجي استفاده ميشه. موفق باشيد.

...!M.J!...
پنج شنبه 21 مهر 1390, 19:31 عصر
دوستان حالا که این بحث مطرح شد من یک سوال تو ذهنم مونده بپرسم:لبخند:

همونطور که میدونید نمیشه یک قطعه کد رو که بافر کرد حجم زیادی داشته باشه وگرنه سرعت رو از دستور echo بیشتر میاره پایین( فک کنم برای خروجی های کمتر از 4kb)
حالا اینجا سوال من اینه که فرق این دوتا چیه:


<?php
ob_start();
php?>
<ul >
<li><a href="#nogo24"></a></li>
<li><a href="#nogo24"></a></li>
<li><a href="#nogo24"></a></li>
<li><a href="#nogo24"></a></li>
<li><a href="#nogo24"></a></li>
</ul>
<?php
echo ob_get_clean();
?>php


با اینجور نوشتن:


<?php
$html.= <li><a href="#nogo24"></a></li>
$html.= <li><a href="#nogo24"></a></li>
$html.= <li><a href="#nogo24"></a></li>
$html.= <li><a href="#nogo24"></a></li>
echo $html;
php?>

Freedom777
جمعه 22 مهر 1390, 09:56 صبح
من توی کتابهای آموزشی خوندم که مشکل قرار گرفتن توابع هدر در ابتدای صفحه فقط توی پی اچ پی هست و زبانهایی مثل جاوا و ای اس پی این مشکل رو ندارن.

پس در نتیجه این مشکل مربوط به پروتکل HTTP نیست. نظرتون چیه؟

بنظرم چون PHP برنامه رو خط به خط از بالا تا پایین اجرا میکنه این مشکل پیش میاد.
ولی مثلا جاوا اول برنامه رو به بایت کد کامپایل میکنه. بنابراین قبل از کامپایل یک بار برنامه رو از اول تا آخر خونده و میتونه همهء هدرها رو شناسایی و یک جا جمع کنه و قبل از هرچیز دیگه ای به کلاینت بفرسته.
البته شایدم دقیقا اینطور نباشه. بهرحال خواستم بگم ساختار خود زبان و روش اجرا میتونن نقش داشته باشن.

اگر منظورت از asp همون asp.net هست، درمورد اونم میشه همین رو گفت.

شاید در PHP هم میشد این مسئله رو به شکلی پیاده سازی کرد و در زبانهای اسکریپتی/تفسیری دیگه هم پیاده سازی شده باشه. بهرحال PHP هم لزوما زبان از هر جهت کامل و بدون نقص و ضعفی نیست.
پروتکل HTTP اینطور کار میکنه. حالا هر زبانی میتونه روش و محدودیت های خودش رو داشته باشه. دلیل نمیشه چون جاوا یا زبان دیگری این محدودیت رو نداره، برخلاف این قضیه عمل بکنه. این امکانات سطح بالاتر و هوشمندی ای هست که در سطح زبان و/یا ساختار اجرای اون در اختیار برنامه نویس قرار میگیره.

Keramatifar
جمعه 22 مهر 1390, 11:52 صبح
http://keramatifar.ir/ShowTopic.php?id=57

Freedom777
جمعه 22 مهر 1390, 13:04 عصر
چیزهایی رو که گفتم اصلاح میکنم.
این گفته در مقالهء آقای کرامتی صحیح هست:

هنگامي که بافر کردن خروجي فعال باشد، همه هدرها فرستاده خواهند شد در حالي که محتوا يا در پايان اسکريپت ارسال خواهد شد يا هنگامي که صريحا توسط اسکريپت با دستوراتي اجرا مي شود.یعنی هدرها همون موقع فرستاده میشن، اما محتوا هست که بافر میشه و دست آخر ارسال میشه.
بنده طوری گفتم که هدرها هم بافر میشن. اما درواقع هدرها بافر نمیشن.
بهرحال نتیجه همونه و در اثر بافر کردن هست که امکان‌پذیر میشه تمام هدرها هرکجا که باشن قبل از خروجی معمولی (بدنهء سند) ارسال بشن.