PDA

View Full Version : چطوری اطلاعات یک فرم رو فقط یکبار بگیرم ؟



aliphp1
یک شنبه 22 مرداد 1391, 23:37 عصر
یک صفحه پی اچ پی دارم که اطلاعات یک فرم رو میگیره و در دیتابیس ذخیره می کنه
حالا اگه بعد از ارسال از صفحه اول در صفحه دوم صفحه رو رفرش کنم همه عملیات تکرار میشه
البته شرط گذاشتم که اگه فیلد های فرم خالی بود تکرار نشه و اگه مستقیم آدرس صفحه دوم رو بزنی اجرا نمیشه
ولی اگر بعد از یک بار پر کردن و ارسال به صفحه دوم در همون صفحه دوم دوم رفرش کنی عملیات را تکرار می کنه
نمی دونم تونستم درست منظورم رو بگم یا نه
دوستان لطفا کمک کنند

colors
دوشنبه 23 مرداد 1391, 00:10 صبح
درود

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

unset($_POST['title']);

aliphp1
دوشنبه 23 مرداد 1391, 00:55 صبح
درود

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

unset($_POST['title']);

این کار رو کردم ولی متاسفانه جواب نداد
خودم هم فکر می کنم بصورت منظقی باید با این دستور درست بشه ولی نمی دونم چرا کار نکرد
حتی متغیر های بعدی که اونها رو داخلشون ریخته بودم رو هم از بین بردم ولی متاسفانه بازم نشد و هنوز هم بارفرش عملیات انجام میشه

eshpilen
دوشنبه 23 مرداد 1391, 09:25 صبح
بابا موقعیکه مرورگر رو رفرش میکنید این مرورگر هست که تمام دیتای درخواست قبلی (POST) رو مجددا در یک درخواست جدید ارسال میکنه.
با unset کردن اطلاعات توی درخواست قبلی در سمت سرور هیچی نمیشه.
اون درخواست اصلا دیگه وجود نداره. با رفرش در مرورگر، یک درخواست جدید با کپی جدید و یکسانی از متغییرهای POST قبلی ارسال میشه.

M.Rahi
دوشنبه 23 مرداد 1391, 09:32 صبح
در صفحه 2 ، آخر کدهایی که نوشتی، مقادیر رو خالی کن و در اول کدها شرط بذار که اگر POST_$ مقدار داشت، بقیه کدها اجرا بشه.


if( isset($_POST) )
{
// continue...

unset($_POST);
}

موفق باشی

colors
دوشنبه 23 مرداد 1391, 10:03 صبح
خب بعد از insert کردن اطلاعاتت به بانک یا کاربررو انتقال بده یا اینکه یه بار صفحه رو رفرش کن. در صورت رفرش کردن مقادیر فرم از بین میرن و شرط نادرست میشه و ...
یا از تابع

header()
یا اگه قبلش چیزی چاپ کردیو حوصله ob رو نداری از

echo '<meta http-equiv="refresh" content="0">';

farhadfery
دوشنبه 23 مرداد 1391, 10:24 صبح
از کوکی یا سژن هم می شه. بعد از ثبت یه متغییر ست می کنی که فرم پست شده.
قبل از درج هم می گید. اگر این متغییر ست نشده و true نیست. عملیات درج انجام بشه.
------------
با js هم می شه
-------
کپجا هم می شه.
---------------------
به قول دوستمون ریدارکت هم می شه.

Unique
دوشنبه 23 مرداد 1391, 12:45 عصر
این سوال را چند روز پیش یک کاربر دیگه هم پرسیده بود !
این مسئله در مورد Refresh کاملا طبیعیه که جناب eshpilen هم توضیح دادند من دیگه نمیدم !
موضوع اینه که مثلا اگه شما یک فرم ثبت نام دارین ! و کاربری بعد از نمایش موفقیت ثبت نام صفحه را Refresh میکنه یا حالا هر فرمی ! من فقط مثال زدم ! فیلد های یکتایی مثل نام کاربری و Email و غیره هستند که باید قبل از insert کردن یج سطر جدید چک بشن و نگذاره یک کاربر دوبار فرم را post و یک مشخصات در سیستم ثبت کنه ! اگه هم فرمی هست که شما نمیتونین دو تا سطر را از طریق یک یا چند فیلد با هم تمیز بدین ! اونجا باید redirect کنین ! اما بازم کاربر ممکنه Back بزنه و اطلاعات دوباره ارسال بشه ! مخصوصا اگه با get باشه ! در کل این مسئله یک ایراد نیست !

farhadfery
دوشنبه 23 مرداد 1391, 13:31 عصر
این سوال را چند روز پیش یک کاربر دیگه هم پرسیده بود !
سلام به اقای unique.
اقا بخش php سایت به خاطر انعطاف بی حد و بی معنی مدیرش. سطحش خیلی امده پایین. من به مدیر بخش هم گفتم با این کارشون بچه هایی هم که کمی حرفه ای ترند مجبورا اینجا را ترک کنند.
تو را خدا ببینید همین سوال یا مثلا تنظیم ckeditor یا ساعت و مشابه اینها بارها و بارها به صورت تکراری پرسیده شده!! چون کاربر پیش خودش می گه (البته نه همه) من که توبیخ نمی شم . همچنین برای چی زحمت به خودو بدم. یه سرچ کوچیک تو انجمن بزنم.
--------
از اینطرف هم قبلنها (قدیما). هر کی سوال تکراری می پرسید کسی جواب نمی داد تا شخص متوجه و متذکر بشه. اما با مدیریت نادرست. بجه ها یاد گرفتن که سوال را هر چی می خواد باشه جواب بدهند.
---------
شاید صدهزار تا پست فقط در مورد این داریم که php را از کجا شروع کنم!
----------------------

aliphp1
چهارشنبه 25 مرداد 1391, 19:00 عصر
ببینید دوستان می دونم که میشه ب هدر کاربر ور به صفحه دیکه ای هدایت کرد ولی قضیه اینطوری هست که بعد از ثبت اطلاعات در دیتابیس در صفحه دوم همون اطلاعات رو به کاربر نمایش میده که اینا براتون ثبت شده
حالا اگر ریدایرکت بشه اون اطلاعات رو نمی تونه ببینه
میخوام هم اطلاعات رو ببینه هم اگر رفرش کرد روند تکرار نشه و اطلاعات دوباره داخل دیتابیس اضافه نشه
لطفا کمک کنید

colors
چهارشنبه 25 مرداد 1391, 19:45 عصر
خب قرار نیست حتما اطلاعات ارسال شده فرم رو بهش نشون بدی! اطلاعاتو تو بانک ذخیره کن و کاربررو به یه صفحه دیگه انتقال بده و اونجا رکورد مربطه رو از جدول بگیرو بهش نشون بده

eshpilen
چهارشنبه 25 مرداد 1391, 20:11 عصر
ببینید دوستان می دونم که میشه ب هدر کاربر ور به صفحه دیکه ای هدایت کرد ولی قضیه اینطوری هست که بعد از ثبت اطلاعات در دیتابیس در صفحه دوم همون اطلاعات رو به کاربر نمایش میده که اینا براتون ثبت شده
حالا اگر ریدایرکت بشه اون اطلاعات رو نمی تونه ببینه
میخوام هم اطلاعات رو ببینه هم اگر رفرش کرد روند تکرار نشه و اطلاعات دوباره داخل دیتابیس اضافه نشه
لطفا کمک کنید
من واسه پروژهء سیستم رجیستر و لاگین خودم از این روش استفاده کردم:
واسه هر فرمی یک آیدی رندوم تولید میکنم:

$form_id=random_string(5);

echo '<input type="hidden" name="form_id" value="', $form_id, '">';
بعد فرم که سابمیت میشه و اطلاعات پذیرفته و بر اساس اونها عمل میشه (مثلا درج رکورد در دیتابیس یا هر عمل دیگری که نتیجهء اون اطلاعاته)، میام و دست آخر که همهء عملیات با موفقیت انجام شده، مقدار اون آیدی رو در یک کوکی در سمت کلاینت ذخیره میکنم:

$cookie=new hm_cookie('reg8log_submitted_forms');
$cookie->secure=$https;
$tmp14=$cookie->get();

if($tmp14!==false) $tmp14=$tmp14.','.$_POST['form_id'];
else $tmp14=$_POST['form_id'];

$tmp14=implode(',', array_slice(explode(',', $tmp14), -20));

$cookie->set(null, $tmp14);
خب بعد توی همین صفحاتی که فرم رو پردازش میکنم در ابتداش چنین کدی رو دارم که چک میکنه آیا آیدی فرم ارسال شده با یکی از آیدی های موجود در این کوکی تطابق داره یا نه و اگر تطابق داشته باشه به معنای اینه که اون فرم قبلا ارسال و پردازش شده، و بنابراین یک پیام خطا مبنی بر این واقعیت به کاربر میدم و پردازش رو متوقف میکنم:

if(isset($_COOKIE['reg8log_submitted_forms'], $_POST['form_id'])) {
if(in_array($_POST['form_id'], explode(',', $_COOKIE['reg8log_submitted_forms']))) {
$failure_msg="<h3>Your request is already processed!</h3>";
$no_specialchars=true;
require $index_dir.'include/page/page_failure.php';
exit;
}
}

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