تقرأ file_get_contents('notes.txt') الملف كاملًا وتعيده نصًا واحدًا. وإذا تعذرت قراءة الملف تعيد false. وللكتابة، استخدم file_put_contents('notes.txt', $text)، التي تنشئ الملف أو تستبدل ما كان فيه.
المخرجات:
Buy milk
Call Ada
Write docs
29 bytes
3 lines
تكتب الكتلة notes.txt أولًا ثم تقرؤه، فيكون لديها ملف تعمل عليه. والمسار مثل 'notes.txt' نسبي إلى مجلد العمل الحالي؛ وفي تطبيق ويب، ابنِ المسار من مجلد السكربت نفسه بـ __DIR__ . '/notes.txt'.
الكتابة والإضافة بـ file_put_contents()
تعيد file_put_contents() عدد البايتات المكتوبة، أو false عند الفشل. وافتراضيًا تستبدل الملف. ويضيف العلم FILE_APPEND إلى النهاية بدلًا من ذلك، وهكذا تعمل السجلات البسيطة، ويمنع LOCK_EX طلبين من الكتابة في اللحظة نفسها:
المخرجات:
Wrote 8 bytes
started
step 1 done
step 2 done
replaced
abc
5 bytes
لتخزين مصفوفة واستعادتها مصفوفةً، اكتبها JSON بـ json_encode() واقرأها بـ json_decode().
قراءة ملف سطرًا سطرًا بـ file()
تقرأ file() ملفًا إلى مصفوفة فيها سطر واحد لكل عنصر. يحتفظ كل سطر بمحرف السطر الجديد في نهايته ما لم تمرر FILE_IGNORE_NEW_LINES، ويُسقط FILE_SKIP_EMPTY_LINES الأسطر الفارغة (ولا يعمل إلا مع FILE_IGNORE_NEW_LINES):
المخرجات:
string(9) "Buy milk
"
1. Buy milk
2. Call Ada
3. Write docs
3 tasks
تحمّل file() وfile_get_contents() الملف كاملًا في الذاكرة. وهذا مقبول لملفات الإعدادات والسجلات التي حجمها بضعة ميغابايتات. أما لملف من مئات الميغابايتات، فاقرأه سطرًا في كل مرة بـ fopen() وfgets() بدلًا من ذلك.
التحقق من وجود الملف قبل قراءته
عندما يكون الملف مفقودًا، تعيد file_get_contents() القيمة false وتطبع PHP تحذيرًا:
Warning: file_get_contents(missing.txt): Failed to open stream: No such file or directory in /home/index.php on line 2
افحص أولًا بـ is_file() (ملف موجود وليس مجلدًا) أو file_exists() (ملف أو مجلد)، وقارن النتيجة دائمًا بـ === false، لأن الملف الفارغ يعيد ""، وهو خاطئ منطقيًا أيضًا:
المخرجات:
empty.txt exists file
missing.txt missing
. exists directory
Cannot read missing.txt, using defaults
bool(false)
bool(true)
0 bytes
لا تُخفِ التحذير بـ @file_get_contents(). الفحص أولًا، أو معالجة false، يُبقي الخطأ مرئيًا عندما يحدث خلل آخر.
قراءة جزء من ملف
الوسيطان الرابع والخامس هما إزاحة البايت التي يُبدأ منها وعدد البايتات المقروءة. والإزاحة السالبة تُعدّ من نهاية الملف. وتتيح لك الوسائط المسماة تخطي الوسيطين اللذين بينهما:
المخرجات:
HEADER
line 2
last line
تعدّ الإزاحات البايتات لا المحارف. وفي UTF-8 يكون المحرف الياباني 3 بايتات، فتقطعه إزاحة في منتصفه إلى نصفين. وللعمل مع المحارف، اقرأ النص كاملًا واستخدم mb_substr().
عرض ملف نصي على صفحة ويب
محتويات الملف نص، والنص المطبوع في HTML يجب تهريبه، وإلا أصبح < في الملف وسمًا. تهرّبه htmlspecialchars() وتحوّل nl2br() الأسطر الجديدة إلى وسوم <br>. شغّله وانظر إلى تبويب Page:
احذف htmlspecialchars() وشغّله مرة أخرى: تنتهي الصفحة الآن عند "v1.2: Fixed"، لأن المتصفح يقرأ <title> وسمًا حقيقيًا ويبتلع كل ما بعده عنوانًا للصفحة. وتشرح صفحة htmlspecialchars() لماذا يهم ذلك لكل ما يستطيع المستخدم كتابته.
قراءة رابط بـ file_get_contents()
مع تفعيل allow_url_fopen (الافتراضي في php.ini)، تقرأ file_get_contents() الروابط أيضًا وتعيد جسم الاستجابة. ويضيف سياق التدفق طريقة الطلب والترويسات والجسم والمهلة:
<?php
$html = file_get_contents('https://example.com/');
$context = stream_context_create([
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/json\r\n",
'content' => json_encode(['name' => 'Ada']),
'timeout' => 5,
'ignore_errors' => true, // return the body of 4xx/5xx responses too
],
]);
$response = file_get_contents('https://api.example.com/users', false, $context);
if ($response === false) {
// DNS failure, timeout, or a refused connection
}
لإعادة المحاولة، والتحويلات المحدودة، ورموز الأخطاء الواضحة، تكون cURL أو مكتبة عميل HTTP مثل Guzzle الأداة الأفضل.
file_get_contents مقابل file() مقابل fopen()
| تريد | استخدم | الذاكرة |
|---|---|---|
| الملف كاملًا نصًا واحدًا | file_get_contents() | الملف كاملًا |
| الأسطر في مصفوفة | file($path, FILE_IGNORE_NEW_LINES) | الملف كاملًا |
| كتابة ملف أو استبداله في استدعاء واحد | file_put_contents() | البيانات التي تكتبها |
| إضافة سطر إلى سجل | file_put_contents($path, $line, FILE_APPEND | LOCK_EX) | سطر واحد |
| قراءة ملف كبير سطرًا سطرًا، أو صفوف CSV | fopen() مع fgets() أو fgetcsv() | سطر واحد |
| القراءة والكتابة في الملف المفتوح نفسه | fopen() مع r+ أو a+ أو c+ | ما تقرؤه |
تفتح الدوال ذات الاستدعاء الواحد الملف، وتقرأ أو تكتب، وتغلقه نيابة عنك، لذا فهي الخيار الافتراضي الصحيح. واستخدم fopen() عندما يكون الملف أكبر من أن يُحمل في الذاكرة أو تحتاج إلى إبقائه مفتوحًا بين العمليات.
الأسئلة الشائعة
كيف أقرأ ملفًا إلى نص في PHP؟
استدعِ file_get_contents('path/to/file.txt'). تعيد الملف كاملًا نصًا، أو false إذا تعذرت قراءة الملف، لذا قارن النتيجة بـ === false قبل استخدامها.
كيف أضيف إلى نهاية ملف في PHP؟
مرّر العلم FILE_APPEND: file_put_contents('log.txt', "new line\n", FILE_APPEND);. ودونه تستبدل file_put_contents() الملف كله. أضف LOCK_EX (FILE_APPEND | LOCK_EX) عندما قد تكتب عدة طلبات في الوقت نفسه.
كيف أقرأ ملفًا سطرًا سطرًا في PHP؟
للملفات الصغيرة، تعيد file('data.txt', FILE_IGNORE_NEW_LINES) مصفوفة فيها سطر واحد لكل عنصر. وللملفات الكبيرة، افتحه بـ fopen() واقرأ سطرًا واحدًا في كل مرة بـ fgets() في حلقة while، فلا يبقى في الذاكرة إلا سطر واحد.
لماذا تعيد file_get_contents القيمة false؟
الملف غير موجود، أو المسار نسبي إلى مجلد غير الذي تظنه، أو ليس لدى PHP صلاحية قراءته. وتطبع PHP أيضًا تحذيرًا مثل Failed to open stream: No such file or directory. افحص بـ is_file() وis_readable()، وابنِ المسارات من __DIR__.
هل تستطيع file_get_contents قراءة رابط؟
نعم، عندما يكون allow_url_fopen مفعّلًا في php.ini: تعيد file_get_contents('https://example.com/') جسم الاستجابة. وللترويسات أو بيانات POST أو المهلة، مرّر سياقًا من stream_context_create()؛ ولأي شيء أعقد، يعطي cURL معالجة أفضل للأخطاء.