PDA

View Full Version : تغییر نسخه php و مشکل session_start()



farzad-kh
یک شنبه 17 خرداد 1394, 23:01 عصر
من یه برنامه روی لوکال نوشتم به خوبی کار میکرد بعد اینکه روی سرور آپلود کردم متوجه شدم این خطا رو میده چون نسخه php روی 5.3یا5.4 تنظیم شده بود اما وقتی که آوردم روی نسخه 5.2 دیگه خطا رو نمیداد... با حذف کردن session_start برنامه به درستی کار میکرد منتها من نمیدونم کاربری که میخواد بعدا ازین اسکریپت استفاده کنه نسخه php چند داره میخوام کاری کنم که روی همه نسخه ها جواب بده
کارایی رو هم که کردم اینا بود ولی حل نشد
از تابع ini_set سعی کردم نشد، شرط گذاشتم نشد.



if(isset($_SESSION){session_start();}

ini_set('session.auto_start','0');
چند تا مدل دیگه هم استفاده کردم اما نشد :(




اینم کد خطا ها:


Warning: session_start(): Cannot send session cookie - headers already sent by (output started at /url.php:3) in /url.php on line 2

Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at /url.php:3) in /url.php on line 2

-سیّد-
دوشنبه 18 خرداد 1394, 08:59 صبح
پیغام خطا رو به دقت بخونید. می‌گه نمی‌تونه کوکی‌های session رو بفرسته، چون headers already sent یعنی header های http قبلاً فرستاده شدن.
اگه بخوام خیلی سریع توضیح بدم، پروتوکل http شامل header و body هست. شما هر درخواستی که به یه سرور وب می‌فرستید، جوابی که می‌گیرید شامل یه header و یه body هست. کدهای html که توی خروجی می‌فرستید همگی توی بخش body قرار دارن. یه سری اطلاعات هم توی بخش header هستن، از جمله اطلاعات کوکی‌ها. حالا نکته اینجاس که این اطلاعات باید به ترتیب فرستاده بشن. یعنی اول باید header ها فرستاده بشن و بعد body. در نتیجه اگه شما یه جایی از کد یه خروجی بفرستید، یعنی دیگه header ها تموم شدن و body شروع شده. بعد از این کار دیگه نمی‌تونید دوباره header بفرستید.
پیغامی که اینجا می‌گیرید می‌گه قبلاً header ها فرستاده شدن یعنی یه جایی شما شروع به فرستادن خروجی کردید (با echo یا امثال اون). جاش رو هم به شما می‌گه: url.php خط ۳.

۲ تا اتفاق خیلی معمول توی کدهای php می‌افته که باعث می‌شه این خطا رو ببینید:

یکی این که کدهاتون رو به صورت UTF-8 با ویرایشگری درست کنید که اول فایل‌هاتون از BOM استفاده می‌کنه (توضیحات بیشتر (http://www.unicode.org/faq/utf_bom.html#BOM) - ویکیپدیا (http://en.wikipedia.org/wiki/Byte_order_mark)). این باعث می‌شه هر فایلی که استفاده کنید، اولش دو تا کاراکتر خاص بذاره که خوب این باعث می‌شه این کاراکترها برن توی خروجی و در نتیجه دیگه نتونید header بفرستید. مثلاً اگه از ++notepad استفاده کنید، می‌بینید که توی منوی Encoding یه چنین گزینه‌ای داره: Encode in UTF-8 without BOM. اگه توی همه‌ی فایل‌هاتون از این گزینه استفاده کنید این مشکل پیش نمیاد.

دلیل دیگه می‌تونه این باشه که وقتی که تگ php رو می‌بندید، یه enter اضافی هم تهش بزنید:


<?php
echo 'salam';
...
?>


این کار باعث می‌شه اون enter اضافی تهش توی خروجی فرستاده بشه و همون داستان قبلی. راه حل اینجا اینه که یا حواستون باشه که اون enter اضافی رو نزنید، یا این که کلاً تگ php رو در انتهای کار نبندید (این کار مشکلی ایجاد نمی‌کنه):


<?php
echo 'salam';
...



در این حالت صد تا enter هم که بزنید، چون داخل تگ php هستید، هیچ چیزی توی خروجی فرستاده نمی‌شه.

در نهایت یه راه حل دیگه هم هست که به دلایلی خیلی خوب نیست، ولی بالاخره جواب می‌ده و اگه نتونستید با روش‌های بالا مشکل رو پیدا کنید و حل کنید، می‌تونید از این روش استفاده کنید. این روش، استفاده از output buffer یا ob هست. به این صورت که شما قبل از انجام هر کاری از تابع ob_start استفاده می‌کنید (یعنی اولین خط کد می‌ذارید که حتماً قبل از هر چیزی اجرا بشه). با این کار، هر خروجی‌ای که فرستاده بشه (به صورت غیر عمد مثل مثال‌های بالا، یا به صورت عمدی اگه یه جا خروجی بدید) واقعاً فرستاده نمی‌شه و buffer می‌شه تا وقتی که خودتون بهش بگید بفرستش (یا اگه به انتهای اجرای کد شما برسه خودش می‌فرسته). در این صورت مشکل مورد نظر پیش نمیاد و خروجی فرستاده نمی‌شه و در نتیجه header ها رو هر جا که دلتون بخواد می‌تونید بفرستید.

farzad-kh
دوشنبه 18 خرداد 1394, 13:37 عصر
ممنون بابت توضیحاتت
خط سوم دقیقا همون session_start هست...
میدونید مشکل از چی بود؟
توی فایلم <html> رو قبل از اینکلود کردن فایلا آورده بودم..مرسی بابت راهنماییتون ... راستی اگه یدونه space هم باشه گیر میده و خطا...

-سیّد-
دوشنبه 18 خرداد 1394, 15:02 عصر
راستی اگه یدونه space هم باشه گیر میده و خطا...
بله دیگه
برای سیستم که فرقی نمی‌کنه یه space باشه یا ده خط نوشته. وقتی مفسر php به اولین جایی می‌رسه که یه خروجی داره، header ها رو می‌فرسته برن.

farzad-kh
چهارشنبه 20 خرداد 1394, 13:22 عصر
یه سوال چرا گفتید ob_start خوب نیس؟

-سیّد-
چهارشنبه 20 خرداد 1394, 21:00 عصر
یه سوال چرا گفتید ob_start خوب نیس؟
یکی از دلایلش اینه که اگر از ob استفاده کنید، متوجه نمی‌شید این مشکل output دادن از کجای کد بوده و در نتیجه ساختارمندی کدتون می‌تونه به هم بخوره. یعنی شما فرض کنید ob رو روشن کنید، اون وقت هر جای کد ممکنه header بفرستید و هر جای دیگه هم ممکنه خروجی بدید. در صورتی که ساختار کد خیلی براتون اهمیت نداره، این مسئله برای شما اهمیت نخواهد داشت.
یکی دیگه از دلایل اینه که در صورت استفاده از ob خروجی کامل توی RAM بافر می‌شه و در نهایت یکجا فرستاده می‌شه. این کار باعث می‌شه یه مقدار استفاده از منابع سخت‌افزاری بالا بره (البته شاید خیلی زیاد نباشه).

farzad-kh
چهارشنبه 20 خرداد 1394, 22:50 عصر
مرسی دقیقا چهارشنبه یجا رفتم برای استخدامی مدیر فنی شرکت اومد مصاحبه کنه گفتم این خطا رو داشتم الان حل شده بعد گفت باید از ob_start استفاده کنی من یاد حرف شما افتادم اینکه سوال پرسیدم... مرسی