Menu
flag Ar iconالعربيةdown icon

fopen() في PHP: فتح الملفات وقراءتها وكتابتها مع شرح الأوضاع

تفتح fopen('data.txt', 'r') ملفًا وتعيد مقبضًا، أو false عند الفشل. اقرأ من المقبض بـ fgets() أو fread()، واكتب بـ fwrite()، وأغلقه بـ fclose(). ويحدد الوضع ('r' و'w' و'a' و'x' و'c' وصيغها مع +) ما يمكنك فعله.

تحتوي هذه الصفحة على محررات قابلة للتشغيل - حرّر، شغّل، وشاهد النتيجة فوراً.

تفتح fopen('data.txt', 'r') ملفًا وتعيد مقبضًا، مورد تدفق تأخذه دوال الملفات الأخرى وسيطًا أول. اقرأ بـ fgets() (سطر واحد) أو fread() (عدد من البايتات)، واكتب بـ fwrite()، وأغلق بـ fclose(). والوسيط الثاني هو الوضع: 'r' للقراءة، و'w' للكتابة، و'a' للإضافة.

المخرجات:

Got: apple
Got: banana
Got: cherry

تعيد fopen() القيمة false عندما لا تستطيع فتح الملف (غير موجود في الوضع r، أو مجلد مفقود، أو لا صلاحية)، وتطبع PHP تحذيرًا مثل:

Warning: fopen(missing.txt): Failed to open stream: No such file or directory in /home/index.php on line 2

لذا افحص false قبل استخدام المقبض. ولقراءة ملف صغير كامل أو كتابته في استدعاء واحد، تكون file_get_contents() وfile_put_contents() أقصر؛ أما fopen() فللملفات التي تقرؤها جزءًا جزءًا أو تبقيها مفتوحة.

أوضاع fopen

الوضعقراءةكتابةإذا كان الملف موجودًاإذا لم يكن موجودًايبدأ من
rنعملايفتحهيفشلالبداية
r+نعمنعميفتحه، ويحتفظ بالمحتوىيفشلالبداية
wلانعميُفرغهينشئهالبداية
w+نعمنعميُفرغهينشئهالبداية
aلانعميحتفظ بالمحتوىينشئهالنهاية، كل كتابة تُضاف
a+نعمنعميحتفظ بالمحتوىينشئهالنهاية، كل كتابة تُضاف
xلانعميفشلينشئهالبداية
x+نعمنعميفشلينشئهالبداية
cلانعميحتفظ بالمحتوىينشئهالبداية
c+نعمنعميحتفظ بالمحتوىينشئهالبداية

صفان يفاجئان الناس. يكتب r+ فوق البايتات الموجودة في مكانها، دون إدراج، ويكتب a+ دائمًا في النهاية، حتى بعد أن تحرّك المؤشر بـ fseek() (تحريكه لا يؤثر إلا في القراءة):

المخرجات:

Xbc
Xbc
Xbc
end

على Windows قد ترى 'rb' أو 'wb': العلم b يعني ثنائي ويمنع Windows من تحويل نهايات الأسطر. ولا يفعل شيئًا على Linux وmacOS، لذا فإضافته غير ضارة وقابلة للنقل.

قراءة ملف سطرًا سطرًا بـ fgets()

تعيد fgets() السطر التالي متضمنًا \n الخاص به، وfalse عند نهاية الملف. ولأن سطرًا واحدًا فقط يكون في الذاكرة في كل مرة، تتعامل هذه الحلقة مع ملف سجل بأي حجم، ويمكنك التوقف مبكرًا بـ break:

المخرجات:

2 errors in 5 lines
line 2: database timeout
line 4: disk full

قارن بـ false باستخدام !==، لا بـ while ($line = fgets($fh)) البسيطة: السطر الذي لا يحتوي إلا "0" دون سطر جديد (وقد يكون آخر سطر في الملف كذلك) خاطئ منطقيًا وسينهي الحلقة مبكرًا.

الكتابة والإضافة بـ fwrite()

تكتب fwrite() نصًا عند الموضع الحالي وتعيد عدد البايتات المكتوبة، أو false عند الفشل. وfputs() هي الدالة نفسها باسم آخر. افتح بـ 'a' للإضافة إلى نهاية ملف دون لمس ما فيه:

المخرجات:

wrote 12 bytes
wrote 13 bytes
wrote 15 bytes
visit /home
visit /about
visit /contact
visit /home

PHP_EOL هو نهاية السطر للنظام الذي تعمل عليه PHP (\n على Linux وmacOS، و\r\n على Windows). وللملفات التي تقرؤها برامج أخرى، اختر واحدة صراحة، عادة "\n".

قراءة ملفات CSV وكتابتها بـ fgetcsv() وfputcsv()

تكتب fputcsv() مصفوفة صفًا واحدًا في CSV وتضع علامات تنصيص حول الحقول التي تحتوي فواصل أو علامات تنصيص أو أسطرًا جديدة. وتقرأ fgetcsv() صفًا واحدًا مصفوفةً. مرّر الفاصل ومحرف الإحاطة ومحرف هروب فارغًا صراحة: هذا يعطي CSV قياسيًا، وتطبع PHP 8.4 إشعار إهمال عندما يُحذف وسيط الهروب.

المخرجات:

name,city,note
Ada,London,"likes ""math"", a lot"
Linus,Helsinki,kernel

Ada lives in London: likes "math", a lot
Linus lives in Helsinki: kernel

تقسيم الأسطر بـ explode(',', $line) ينكسر حالما يحتوي حقل فاصلة؛ وتعالج fgetcsv() علامات التنصيص نيابة عنك. ولملف مفصول بفواصل منقوطة (شائع في ملفات Excel المصدّرة في أوروبا)، مرّر ';' فاصلًا.

التنقل في ملف بـ fseek() وftell() وrewind()

للملف المفتوح موضع. تبدأ القراءات والكتابات منه وتحرّكه إلى الأمام. تخبرك ftell() بمكانه، وتنقله fseek() إلى إزاحة بايت، وتعيده rewind() إلى البداية. ومع w+ يمكنك كتابة ملف وقراءته عبر المقبض نفسه:

المخرجات:

11
world
hello world

قفل ملف بـ flock()

طلبان يقرآن عدادًا، ويضيفان واحدًا، ويكتبانه في الوقت نفسه قد يقرآ كلاهما 41 ويكتبا كلاهما 42. تجعل flock() مع LOCK_EX الطلب الثاني ينتظر حتى يحرر الأول القفل. والوضع c+ هو الصحيح هنا: ينشئ الملف عند الحاجة، وعلى عكس w+، لا يُفرغه قبل أن تمسك القفل.

المخرجات:

Visitor number 1
Visitor number 2
Visitor number 3

الأقفال استشارية: لا توقف إلا الشيفرة الأخرى التي تستدعي flock() أيضًا. ولإضافة سطر واحد، تفعل file_put_contents($path, $line, FILE_APPEND | LOCK_EX) الشيء نفسه في استدعاء واحد.

خطأ شائع: while (!feof($fh))

تمر دروس قديمة كثيرة بحلقة على feof(). لا تعيد true إلا بعد أن تكون قراءة قد اصطدمت بالنهاية فعلًا، فتعمل الحلقة مرة أكثر من عدد الأسطر وتعيد fgets() الأخيرة false:

المخرجات:

string(2) "a
"
string(2) "b
"
string(2) "c
"
bool(false)
4 rounds for 3 lines

تصبح قيمة false الزائدة تلك صفًا فارغًا في تقرير أو عنصرًا فارغًا في مصفوفة. اجعل الحلقة على القراءة نفسها، while (($line = fgets($fh)) !== false)، كما تفعل كل الأمثلة الأخرى في هذه الصفحة.

الأسئلة الشائعة

ما هي أوضاع fopen في PHP؟

r للقراءة، وw للكتابة بعد إفراغ الملف، وa للكتابة في النهاية، وx لإنشاء ملف جديد ويفشل إذا كان موجودًا، وc للكتابة دون إفراغه. وإضافة + (r+ وw+ وa+ وx+ وc+) تسمح بالقراءة والكتابة معًا. وكل وضع ما عدا r وr+ ينشئ الملف عندما يكون مفقودًا.

ما الفرق بين w وa في fopen؟

يُفرغ w الملف حالما يُفتح ويكتب من البداية. ويحتفظ a بالمحتوى وتذهب كل fwrite() إلى نهاية الملف، حتى بعد fseek()، وهذا يجعله الوضع المناسب لملفات السجلات.

كيف أقرأ ملف CSV في PHP؟

افتحه بـ fopen($path, 'r') واستدعِ fgetcsv() في حلقة: while (($row = fgetcsv($fh, null, ',', '"', '')) !== false) { ... }. يعيد كل استدعاء صفًا واحدًا مصفوفةً من الحقول، مع معالجة علامات التنصيص والفواصل المضمنة نيابة عنك.

هل أحتاج إلى استدعاء fclose في PHP؟

تغلق PHP كل ملف مفتوح عند انتهاء السكربت، لذا يعمل السكربت القصير دونها. استدعِ fclose() مع ذلك حالما تنتهي: فهي تفرغ الكتابات المخزنة مؤقتًا، وتحرر الأقفال المأخوذة بـ flock()، وتمنع السكربت الطويل التشغيل من نفاد مقابض الملفات.

رسم توضيحي للغات البرمجة في Coddy

تعلّم البرمجة مع Coddy

ابدأ الآن