ویرگول
ورودثبت نام
محسن موحد (آموزش برنامه نویسی)
محسن موحد (آموزش برنامه نویسی)
خواندن ۱ دقیقه·۳ سال پیش

Lock شدن فایل Session و معرفی تابع session_write_close


سلام.

قبلا کدی نوشته بودم که درخواست های Ajax رو بصورت موازی و همزمان به دو صفحه ی PHP ارسال میکرد.

( بطور عادی وقتی چند صفحه ی PHP رو همزمان باز میکنیم، انتظار داریم، همزمان اسکریپت ها اجرا بشن و هر صفحه بطور مجزا تفسیر بشه و صفحه ای منتظر پایان اجرای صفحه ی دیگه نباشه.)

ولی در پروژه ی من، وقتی درخواست ajax به صفحه ی اول میرفت، چون صفحه ی اول، چند ثانیه طول میکشید تا اجراش به پایان برسه، صفحه ی دوم، منتظر میماند تا صفحه ی اول اجراش به پایان برسه. البته این چند ثانیه ای که صفحه ی اول طول میکشید، چون زمانش مقداری زیاد بود(مثلا ۲۰ ثانیه)، من متوجه این مسئله شده بودم وگرنه به چشم نمیومد.

با سرچ متوجه شدم که علتش، استفاده از سشن بوده و session_start رو در این فایل ها صدا زده بودم.

یک مثال برای تست میارم تا متوجه مسئله بشید.

صفحه ی page۱.php رو بسازید و کدهای پایینو داخلش بذارید:

<?php session_start(); $_SESSION['fullname'] = 'Mohsen Movahed'; sleep(15); echo 'Page 1'; echo ''; echo $_SESSION['fullname'];

یک sleep به مدت ۱۵ ثانیه ایجاد کردم تا متوجه این مسئله بشیم.

صفحه ی page۲.php رو ایجاد کنید و کدهای پایینو داخلش بذارید:

<?php session_start(); echo 'Page 2';

حالا در مرورگر دو تا تب بازکنید و در تب اول page۱.php رو بزنید و در تب دوم page۲.php و همزمان اجرا بگیرید.

در حالت عادی page۲.php باید سریع اجرا بشه ولی وقتی اول page۱.php رو میزنید، page۲.php منتظر میمونه تا اجرای page۱.php به اتمام برسید.

علت این ماجرا اینه که PHP بصورت پیشفرض، سشن ها رو روی فایل ها مدیریت میکنه.

وقتی session_start اجرا میشه، فایل سشنی که مربوط به کاربر مورد نظر هست در حالت Lock قرار میگیرد تا زمانیکه اسکریپت به پایان برسد. چون ممکنه در حین اجرای اسکریپت تغییراتی در فایل سشن ایجاد شود.

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

در PHP بطور معمول دیتای مربوط به سشن، بعد از اتمام اسکریپت ذخیره میشود.

یعنی اینکه اسکریپت که به پایان رسید، بطور اتومات، محتوای سشن ذخیره میشود و فایل سشن مربوط به کاربر unlock میشود.

حالا ممکنه در یک اسکریپت(مثل page۱.php) ما نخوایم تا  پایان اجرای اسکریپت صبر کنیم.

در توابع سشن، تابعی وجود دارد با نام session_write_close که سشن جاری رو close میکنه و محتوای سشن رو داخلش ذخیره میکنه. حالا اگر در جایی نیاز پیدا کردیم میتونیم ازین تابع استفاده کنیم. ضمن اینکه اگر بخواهیم سشن رو روی دیتابیس مدیریت کنیم، اونجاهم برای پیاده سازیش نیاز به استفاده ازین تابع داریم.

برای حل مشکل اسکریپت، داخل page۱.php(چون طول میکشه و فایل سشن، زمان زیادی رو توو حالت lock میمونه) بعد از اینکه مقادیرو ست کردیم میتونیم با استفاده از تابع session_write_close بگیم سشن جاری close بشه:

<?php session_start(); $_SESSION['fullname'] = 'Mohsen Movahed'; session_write_close(); // Ends the current session and store session data sleep(15); echo 'Page 1'; echo ''; echo $_SESSION['fullname'];

حالا میتونید یکبار دیگه page۱.php رو اجرا کنید و بعد page۲.php و میبینید مشکل حل شده!

با دونستن کاربردش، حالا جایی که نیاز داشتین میتونین ازش بهره ببرین.

یک نکته هم برای استارت کردن سشن:

ممکنه در پروژه هاتون اگر ساختار درستی رو رعایت نکرده باشید یا حجم پروژه بالا باشه و یا هر دلیل دیگه در صفحات مختلفی، سشن رو استارت کنید و اگر در حین اجرای اسکریپت، سشن از قبل در صفحه ای استارت شده باشه و مجدد فراخوانی بشه یک Notice اتفاق میوفته که میگه سشن قبلا استارت شده بنابراین میتونید سشن هاتونو به این شکل استارت کنید:

if(session_status() !== PHP_SESSION_ACTIVE) { session_start(); }

خروجی های session_status رو ببینید.

* چون در مورد سشن مطلب اوردم بد نیست این مطلبم اضافه کنم، جدای ازینکه Session ID روی Cookie مرورگر LifeTime داره، خود Session هم روی سرور یک LifeTime داره میتونید در موردش داخل داک PHP تحقیق کنید.

phpبرنامه نویسیsessionprogramming
برنامه نویس متخصص PHP، Mysql، Javascript، HTML، CSS، Node.js، Android، Laravel، Yii2 - مدیر پشتیبانی فنی و سرپرست منتورها در شرکت 7learn.com
شاید از این پست‌ها خوشتان بیاید