الدالة flock()‎ في PHP

من موسوعة حسوب
< PHP

(PHP 4, PHP 5, PHP 7)

تحمي الدالة flock()‎ ملفًا محدَّدًا أثناء إجراء عمليَّة عليه (مثل القراءة منه أو الكتابة عليه) إشارةً إلى أنَّ هذا الملف يُستعمل الآن.

الوصف

bool flock ( resource $handle , int $operation [, int &$wouldblock ] )

تُتيح لك هذه الدالة قفل أيَّ ملف ومنع الآخرين من القراءة منه أو الكتابة عليه وذلك أثناء إجراء عمليَّة ما على هذا الملف. يمكن استعمال هذه الدالة نظريًا على جميع الأنظمة (من ضمنها أغلب توزيعات لينكس وحتى ويندوز).

كان الملف في إصدار PHP 5.3.2 وما قبله يُحرَّر من القفل المُطبَّق عليه باستدعاء الدالة fcolse()‎ والتي تُستدعى تلقائيًّا عند إغلاق السكربت.

تدعم PHP وسيلة محمولة (portable) لقفل الملفات بطريقة اختياريَّة (advisory) أي يجب على جميع التطبيقات التي تحاول الوصول إلى الملف استعمال طريقة القفل ذاتها وإلَّا مُنعت من العمل. لا يمكن بصورة افتراضيَّة استعمال الدالة على الملف ذاته مرة أخرى أي أثناء قفل هذا الملف. إن طٌبِّقت مرة أخرى على ملف مُقفل، فستنتظر ريثما يُحرَّر القفل وتبقى آنذاك محجوبةً عن الخدمة إلا إذا مُرِّر المعامل الاختياري LOCK_NB إليها (وهو أحد ثوابت المعامل operation).

المعاملات

filename

موردٌ يشير إلى ملف فُتح باستعمال الدالة fopen()‎.

operation

قيمة هذا المعامل هي أحد العمليات التالية:

العمليَّة الوصف
LOCK_SH طلب الحصول على قفل مشاركة (shared lock، عند القراءة).
LOCK_EX طلب الحصول على قفل استثنائي (exclusive lock، عند الكتابة).
LOCK_UN إلغاء قفل النوعين السابقين.

يمكن أيضًا إضافة الخيار LOCK_NB إلى أحد العمليَّات السابقة باستعمال المعامل OR الثنائي (|) إن شككت أن الملف مُقفل سابقًا إذ سيؤدي ذلك إلى عدم حجب الدالة انتظارًا لإلغاء قفله.

wouldblock

معامل اختياري. تُمرَّر القيمة 1 إن أردت للدالة أن تنتظر إلغاء قفل الملف إن كان مُقفل سابقًا.

القيم المعادة

تُعاد القيمة TRUE عند نجاح العمليَّة، أو القيمة FALSE عند فشلها.

سجل التغييرات

الإصدار الوصف
5.5.22، 5.6.6 إضافة دعم للمعامل wouldblock على منصَّة ويندوز.
5.3.2 أصبح من غير الممكن إلغاء القفل تلقائيًّا عند إغلاق الملف، إذ يجب إلغاء قفل الملف الآن يدويًّا.

أمثلة

المثال 1: استعمال الدالة flock()‎

<?php

$fp = fopen("/tmp/lock.txt", "r+");

if (flock($fp, LOCK_EX)) {  // طلب إجراء قفل استثنائي للملف
    ftruncate($fp, 0);      // تقليص حجم الملف
    fwrite($fp, "Write something here\n");
    fflush($fp);            // تفريغ المخرجات المخزَّنة ضمن الملف قبل إلغاء القفل
    flock($fp, LOCK_UN);    // إلغاء القفل
} else {
    echo "Couldn't get the lock!";
}

fclose($fp);

?>

المثال 2: استعمال الدالة flock()‎ مع الخيار LOCK_NB

<?php
$fp = fopen('/tmp/lock.txt', 'r+');

//LOCK_EX مع العملية LOCK_NB تفعيل الخيار 
if(!flock($fp, LOCK_EX | LOCK_NB)) {
    echo 'Unable to obtain lock';
    exit(-1);
}

// ...

fclose($fp);
?>

ملاحظات

  • تَستعمل الدالة flock()‎ طريقة القفل الإجباريَّة (mandatory) عوضًا عن طريقة القفل الاختياريَّة (advisory) في ويندوز. طريقة القفل الاجباريَّة مدعومة على نظام التشغيل لينكس وبقية الأنظمة الشبيهة بيونكس عبر الآلية الاعتيادَّية التي تدعمها الدالة fcntl()‎ عندما يستدعيها النظام، ويمكن استعمال هذه الطريقة عندما يكون بت معرِّف المجموعة المالكة setgid في الأذونات مفَّعلًا (قيمته 1) وبت استثناء المجموعة غير مُفَّعل (قيمته 0). سيحتاج نظام الملفات على لينكس أيضًا أن يُوصَل (mount) باستعمال الخيار mand من أجل أن تعمل طريقة القفل الاجباريَّة.
  • لما كانت الدالة flock()‎ تحتاج مؤشر ملف يشير إلى الملف المطلوب، فافتح الملف في وضع الكتابة إن اضطررت في بعض الحالات الخاصة، مثل تقطيع الملف، إلى قفله لمنع أحد من الوصول إليه وذلك بتمرير المعامل w أو المعامل w+‎ إلى الدالة fopen()‎.
  • قد يُستعمل مع هذه الدالة مؤشرات الملف المُعادة باستعمال الدالة fopen()‎ فقط من أجل الملفات المحليَّة أو يُستعمل معها مؤشرات الملف التي تشير إلى مجرى لمساحة تخزين يملكها المستخدم والتي تُطبِّق التابع streamWrapper::stream_lock()‎.

تحذير: إسناد قيمة أخرى للمعامل handle في الشيفرة اللاحقة سيؤدي إلى إلغاء القفل للقيمة السابقة.

تحذير: تٌنفَّذ الدالة flock()‎ على بعض أنظمة التشغيل في مستوى العمليَّة نفسها، لذا ربما لن تتمكَّن عند استعمال واجهة برمجية API لخادم متعدِّد الخيوط (multithreaded) مثل ISAPI من الاعتماد على الدالة flock()‎ لحماية الملفات من سكربتات PHP أخرى تعمل بالتوازي مع مسار معالجة آخر على الخادم ذاته.

  • الدالة flock()‎ لا تدعم أنظمة ملفات قديمة جدًا مثل نظام الملفات FAT ومشتقاته، وستعيد القيمة FALSE دومًا عند استعمالها مع أنظمة الملفات تلك.

انظر أيضًا

  • الدالة fopen()‎: تفتح ملفًا أو عنوان URL.
  • الدالة fclose()‎: إغلاق مؤشر ملف مفتوح.
  • الدالة fgets()‎: تجلب سطرًا واحدًا من ملف.
  • الدالة fread()‎: تقرأ من الملف بطريقة آمنة ثنائيًّا.
  • الدالة fwrite()‎: تكتب على الملف بطريقة آمنة ثنائيًّا.
  • الدالة file()‎: تقرأ الملف بأكمله ثمَّ تضع محتوياته في مصفوفة.
  • الدالة fflush()‎: تفرِّغ ما في مخزن المخرجات في ملف محدَّد.
  • الدالة ftruncate()‎: تقلِّص حجم الملف إلى حجم محدَّد.

مصادر