في هذا الدرس 6تصفّح المواضيع
على عكس الدالة البسيطة explode(",", $line)، تحلل الدالة fgetcsv() الحقول المحاطة بعلامات تنصيص بدقة حتى لو احتوت بداخلها على فواصل أو علامات تنصيص مزدوجة.
- في PHP 8.4+ مرّر دائماً نصاً فارغاً للمعامل
escape: ""(أو المعامل الخامس"") لتعطيل الهروب القديم بالشرطة العكسية وتجنب تنبيهات الإلغاء. - اقرأ الصف الأول قبل الحلقة إذا كان ملف CSV يبدأ بسطر أسماء الأعمدة، ثم اربطه بكل صف بيانات عبر
array_combine(). - تُرجع
fgetcsv()مصفوفة مفهرسة بحقول كل صف، وتُرجعfalseعند وصول المؤشر إلى نهاية الملف.
تمرير "" كمعامل خامس يتوافق مع معيار RFC 4180 في PHP 8.4 ويحافظ على الفاصلة الموجودة داخل الحقل "Jeddah, SA".
<?php
$fp = fopen('php://memory', 'r+');
fwrite($fp, "id,name,city\n10,\"Noura\",\"Jeddah, SA\"\n");
rewind($fp);
$cols = fgetcsv($fp, 0, ',', '"', '');
$row = fgetcsv($fp, 0, ',', '"', '');
$record = array_combine($cols, $row);
echo $record['name'] . " -> " . $record['city'] . "\n";
fclose($fp);
تنسق الدالة fputcsv() مصفوفة من القيم كسطر CSV قياسي وتكتبه مباشرة داخل مجرى الملف المفتوح.
- تحيط
fputcsv()تلقائياً الحقول التي تحتوي على مسافات أو فواصل بعلامات تنصيص مزدوجة وتضاعف أي علامة"داخلية. - مرّر المعامل
escape: ""صراحةً ليستخدم PHP 8.4+ مضاعفة علامات التنصيص القياسية وفق RFC 4180 دون أي تحذيرات. - تُرجع الدالة عدد البايتات المكتوبة في المجرى عند النجاح، أو
falseعند الفشل.
تؤمّن fputcsv() تلقائياً علامة التنصيص داخل النص 15" Pro Laptop بتحويلها إلى "15"" Pro Laptop".
<?php
$fp = fopen('php://memory', 'r+');
$rows = [
['sku', 'title', 'price'],
['A-1', '15" Pro Laptop', 4200],
];
foreach ($rows as $r) {
fputcsv($fp, $r, ',', '"', '');
}
rewind($fp);
echo trim(stream_get_contents($fp)) . "\n";
fclose($fp);
لا تقسم مسارات الملفات يدوياً عبر explode(".", $path)؛ بل اعتمد على الدوال القياسية pathinfo() وbasename() وdirname() وrealpath().
- تُرجع
pathinfo($path)مصفوفة ترابطية بالمفاتيحdirnameوbasenameوextensionوfilename. - مرّر ثابتاً محدداً مثل
PATHINFO_EXTENSIONأوPATHINFO_FILENAMEلاستخراج عنصر نصي واحد مباشرة. - تحول الدالة
realpath($path)المسارات النسبية (../) والروابط الرمزية إلى مسار مطلق حقيقي، أو تُرجعfalseإذا كان الملف غير موجود.
رغم وجود عدة نقاط في الاسم q4.sales.csv، تفصل pathinfo() اسم الملف "q4.sales" عن الامتداد الأخير "csv" بدقة.
<?php
$path = '/var/www/storage/reports/q4.sales.csv';
$info = pathinfo($path);
$ext = strtolower(pathinfo($path, PATHINFO_EXTENSION));
$realDir = realpath(__DIR__);
echo $info['filename'] . " | ext: $ext | real: " . ($realDir !== false ? 'ok' : 'no') . "\n";
أدِر مجلدات التخزين في تطبيقك برمجياً باستخدام is_dir() والإنشاء المتداخل عبر mkdir() والحذف عبر rmdir().
- افحص الشرط
!is_dir($dir)قبل إنشاء المجلد حتى لا يصدر PHP تحذيراً إذا كان المجلد موجوداً بالفعل. - مرّر القيمة
trueللمعامل الثالث (recursive) فيmkdir($dir, 0755, true)لإنشاء سلسلة المجلدات الأبوية المتداخلة في خطوة واحدة. - لا تحذف الدالة
rmdir($dir)إلا المجلدات الفارغة تماماً؛ لذا يجب حذف أي ملفات بداخلها عبرunlink()أولاً.
تنشئ mkdir($nested, 0755, true) المجلد الأساسي والمجلد الفرعي 2026 معاً، ثم تحذفهما rmdir() من الأعمق إلى الأعلى.
<?php
$base = sys_get_temp_dir() . '/ct_exports_' . getmypid();
$nested = "$base/2026";
if (!is_dir($nested)) {
mkdir($nested, 0755, true);
}
$created = is_dir($nested);
rmdir($nested);
rmdir($base);
echo "Nested created: " . ($created ? 'yes' : 'no') . " | Cleaned: " . (!is_dir($base) ? 'yes' : 'no') . "\n";
استعرض محتويات المجلدات إما بجلب جميع المدخلات عبر scandir() أو بمطابقة أنماط الامتدادات والأسماء مباشرة عبر glob().
- تُرجع
scandir($dir)مصفوفة بجميع الأسماء داخل المجلد بما فيها مدخلا المجلد الحالي والأب"."و"..". - استبعد مدخلي النقطة والنقطتين بنظافة عبر التعبير
array_diff(scandir($dir), [".", ".."]). - تُرجع الدالة
glob("$dir/*.csv")المسارات المطابقة لنمط البحث فقط وتتجاهل"."و".."تلقائياً.
تطابق glob("$dir/*.csv") الملف a.csv فقط، بينما تُرجع scandir($dir) بعد استبعاد ["." , ".."] الملفين معاً.
<?php
$dir = sys_get_temp_dir() . '/ct_scan_' . getmypid();
mkdir($dir, 0755, true);
file_put_contents("$dir/a.csv", "1");
file_put_contents("$dir/b.txt", "2");
$csvs = glob("$dir/*.csv");
$all = array_values(array_diff(scandir($dir), ['.', '..']));
echo "CSV count: " . count($csvs) . " | All: " . implode(',', $all) . "\n";
unlink("$dir/a.csv");
unlink("$dir/b.txt");
rmdir($dir);
استخدم هذا الجدول المرجعي لاختيار الدالة الأنسب لمعالجة ملفات CSV أو تحليل المسارات أو استعراض المجلدات في PHP 8.4.
- مرّر دائماً المعامل
escape: ""للدوالfgetcsv()وfputcsv()وstr_getcsv()في PHP 8.4+. - استخدم
realpath()معstr_starts_with()لمنع ثغرات القفز بين المجلدات (../../) قبل فتح أي اسم ملف يرسله المستخدم. - فضّل
glob()عند الفلترة حسب امتداد الملف، وscandir()عند الرغبة في فحص كل محتويات المجلد.
تحلل الدالة str_getcsv($line, ",", "\"", "") سطر CSV النصي في الذاكرة بنفس قواعد RFC 4180 الخاصة بالدالة fgetcsv().
| الدالة | المهمة الأساسية | أهم معامل أو نصيحة في PHP 8.4 | قيمة الإرجاع |
|---|---|---|---|
fgetcsv($fp, 0, ",", "\"", "") | Read one CSV row from stream | Pass escape: "" explicitly | array|false |
fputcsv($fp, $row, ",", "\"", "") | Write one CSV row to stream | Pass escape: "" explicitly | int|false (bytes) |
pathinfo($path, $flags) | Extract dirname, basename, extension | Use PATHINFO_EXTENSION | array|string |
mkdir($p, 0755, true) / glob($pat) | Create nested dirs / Match files | recursive: true / omits . and .. | bool / array|false |
<?php
$line = '205,"Monitor 27""",1499.50';
$parsed = str_getcsv($line, ',', '"', '');
$ext = pathinfo('exports/monitors_2026.csv', PATHINFO_EXTENSION);
echo $parsed[1] . " | Price: " . $parsed[2] . " | Ext: $ext\n";
ملخص الدرس
حصاد الدرسمراجعة مركّزة لأهم المفاهيم والقواعد الهندسية التي أتقنتها في هذا الدرس قبل التطبيق العملي
ماذا تعلّمت في هذا الدرس؟
استخدم هذا الجدول المرجعي لاختيار الدالة الأنسب لمعالجة ملفات CSV أو تحليل المسارات أو استعراض المجلدات في PHP 8.4. مرّر دائماً المعامل escape: "" للدوال fgetcsv() وfputcsv() وstr_getcsv() في PHP 8.4+. استخدم realpath() مع str_starts_with() لمنع ثغرات القفز بين المجلدات (../../) قبل فتح أي اسم ملف يرسله المستخدم. فضّل glob() عند الفلترة حسب امتداد الملف، وscandir() عند الرغبة في فحص كل محتويات المجلد.
سجّل الدخول لحفظ تقدمك
تابع إنجاز المواضيع والمصطلحات والمهام، وكمّل من آخر خطوة على أي جهاز.
المصطلحات4
راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.
- 01 CSV & Directories ملفات CSV والمجلدات
- اقرأ وصدّر جداول CSV عبر fgetcsv وfputcsv، وأدر المجلدات والمسارات بأمان باستخدام scandir وglob وpathinfo في PHP 8.
- للمراجعة
- 02 Reading CSV Rows with fgetcsv قراءة صفوف CSV عبر fgetcsv
- المفهوم الأساسي لقسم قراءة صفوف CSV عبر fgetcsv في لغة PHP الحديثة.
- للمراجعة
- 03 Exporting CSV Files with fputcsv تصدير بيانات CSV عبر fputcsv
- الصياغة البرمجية والتطبيق العملي المباشر لقسم تصدير بيانات CSV عبر fputcsv.
- للمراجعة
- 04 Inspecting Paths with pathinfo تحليل المسارات والامتدادات بـ pathinfo و realpath
- قواعد التحقق وأفضل الممارسات القياسية الخاصة بقسم تحليل المسارات والامتدادات بـ pathinfo و realpath.
- للمراجعة
لا توجد بطاقات تطابق البحث والتصفية.
اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.
الاختصارات4
راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.
- 01 PHP PHP
- PHP: Hypertext Preprocessor
- لغة البرمجة النصية على جانب الخادم لبناء تطبيقات الويب الديناميكية وواجهات البرمجة.
- للمراجعة
- 02 CLI CLI
- Command-Line Interface
- واجهة سطر الأوامر التي تتيح تشغيل ملفات PHP مباشرة عبر الطرفية.
- للمراجعة
- 03 FPM FPM
- FastCGI Process Manager
- مدير عمليات FastCGI عالي الأداء لمعالجة طلبات خادم الويب في PHP.
- للمراجعة
- 04 HTML HTML
- HyperText Markup Language
- لغة الترميز القياسية التي يولدها محرك PHP ويرسلها إلى متصفح العميل بعد التنفيذ.
- للمراجعة
لا توجد بطاقات تطابق البحث والتصفية.
اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.
مهامك قبل الاختبار
خطوة صغيرة كل مرة. وإنجاز تقدر ترجع له.
-
أنشئ ملف PHP محلياً ونفّذ المثال البرمجي المشروح في قسم قراءة صفوف CSV عبر fgetcsv للتحقق من المخرجات.
-
بدّل بين الحالات الثلاث في المحاكي التفاعلي ضمن قسم تصدير بيانات CSV عبر fputcsv وقارن مخرجات التنفيذ.
تأشير المهمة إقرار منك بإتمامها، وليس تصحيحًا آليًا للكود. يُحفظ تقدمك في حسابك.
اختبر فهمك.
ووصلها للإتقان.
كل سؤال خطوة لقدّام. اختار، اكتب كود، وشوف نتيجتك فورًا.
أكمل المهام، واجمع كل الإجابات الصحيحة. أقل من 100%؟ راجع وأعد المحاولة.
الأسئلة متاحة للاطلاع. سجّل الدخول للتفاعل وحفظ تقدمك.
لمحة عن التحدي8 أسئلة تنتظرك +
لماذا يجب تمرير نص فارغ "" لمعامل الهروب ($escape) في دالتي fgetcsv() وfputcsv() في PHP 8.4؟
ألغى PHP 8.4 الاعتماد الضمني على الشرطة العكسية لأنها تفسد الحقول المنتهية بـ \ واعتمد النص الفارغ وفق RFC 4180.
لماذا تُعد دالة fgetcsv() أكثر أماناً ودقة من explode(",", $line) عند قراءة ملفات CSV؟
تقسم explode(",") النص عند أي فاصلة بشكل أعمى فتفسد الحقول التي تحتوي على فاصلة بداخلها.
أي ثابت في دالة pathinfo() يستخرج امتداد الملف فقط بدون النقطة؟
تُرجع pathinfo("report.pdf", PATHINFO_EXTENSION) النص "pdf".
ماذا تُرجع الدالة realpath($path) إذا كان الملف أو المجلد الهدف غير موجود فعلياً على القرص؟
تتحقق realpath() من وجود المسار فعلياً على القرص وتُرجع false إذا كان مفقوداً.
ما القيمة التي تُمرر كمعامل ثالث في mkdir("/var/app/storage/logs/2026", 0755, ...) لإنشاء جميع المجلدات الأبوية المفقودة تلقائياً؟
تفعيل $recursive = true ينشئ سلسلة المجلدات المتداخلة بالكامل.
ماذا يحدث عند استدعاء rmdir($dir) على مجلد لا يزال يحتوي بداخله على ملفين؟
يجب حذف جميع الملفات داخل المجلد عبر unlink() أولاً قبل حذف المجلد بـ rmdir().
ما المدخلان الخاصان اللذان يظهران دائماً ضمن المصفوفة التي تُرجعها الدالة scandir($dir)؟
تُدرج scandir() دائماً "." و".." ويتم استبعادهما عادةً عبر array_diff().
ما الدالة التي تُرجع مصفوفة بمسارات الملفات المطابقة لنمط بحث مثل "exports/*.csv"؟
تبحث الدالة glob() عن المسارات المطابقة لأنماط النجمة وعلامة الاستفهام.