السلام عليكم و رحمة الله ويركاته .
هذا الدرس ضمن سلسة دروس الدورة التالية لتعلم لغة php !
التعامل مع الملفات و المجلدات .
من الصعب برمجة تطبيق ويب دون التفاعل مع أي مصدر خارجي كقواعد البيانات أو الملفات و خصوصا ً انشاء الملفات و المجلدات و حذفها و تعديلها ...
أولا ً : التعامل مع الملفات
المسار هو طريقة للتعبير عن عنوان ملف أو مجلد في نظام التشغيل ,و المسارات نوعان : مسارات نسبية ومسارات مطلقة , المسارات النسبية تبدأ من المسار الحالي حتى نصل الى القيد المطلوب (القيد = مجلد أو ملف) مثلا مسار الملف file1.txt الموجود في المجلد folder الموجود في مجلد البرنامج الذي نقوم بتنفيذه يكون كالتالي :
folder/file1.txt
اما إذا كان الملف file1.txt موجودا ً في المجلد الأب للمجلد التالي (أي المجلد الذي يسبقه) يكون المسار كالتالي :
../file1.txt
أي ان النقطتين تشيران الى أن الملف المطلوب في المجلد الأب للمجلد الحالي , ويوجد أيضا النقطة الواحدة "." التي تشير الى المجلد الحالي حيث يمكن استبدال المسار الأول كما يلي :
./folder/file1.txt
اما الروابط المطلقة فهي تُشير الى مسار الملف أيا ً كان المجلد الذي يوجد فيه البرنامج .
للحصول على المسار كاملا ً نستخدم الدالة realpath التي تقبل وسيطا ً وحيدا ً هو المسار النسبي للملف :
<?phpecho realpath('file1.txt');?>وفي حال لم يُحدد الوسيط فيستم اعادة المسار المطلق للمجلد الحالي .
التأكد من وجود ملف :
في بعض الأحيان يلزم معرفة إذا كان ملف مُعين بمساره موجود أم لا , ولمعرفة ذلك نقوم باستدعاء الدالة file_exists التي تقبل وسيطا ً وحيدا ً هو مسار الملف و تُعيد القيمة true في حال وجوده :
<?php
if(file_exists('file1.txt') === true)
{
echo 'file "file.txt" exists';
}
echo '<br>';
if(file_exists('file2.txt') === false)
{
echo 'file "file2.txt" does not exists';
}
?>
الحصول على حجم تخزين ملف :
في حال اردنا معرفة حجم ملف , نستخدم الدالة filesize التي تقبل وسيطا ً واحدا ً هو مسار الملف , وتُعيد هذه الدالة حجم الملف مقدرا ً بالبايت , وللحصول على الحجم مقدراً بالكيلوبايت أو الميغابايت , نقسم على 1024 أو (1024*1024) على التوالي وبالترتيب :
<?php
$size = filesize('file1.txt');
echo 'The size of file1.txt is : '. floor($size / 1024) .' KB';
?>
استخراج امتداد ملف :
كما تعلم لكل نوع من الملفات امتداد معين خاص بها , حيث يكون الامتداد مسبوقا ً بنقطة , فلذلك نقوم باستخراج الامتداد عن طريق الدالة explode - التي سبق شرحها في درس التعامل مع المصفوفات - حيث يكون امتداد الملف هو اخر سلسلة نصية تكون مسبوفة بنقطة "." كما في المثال التالي :
<?php
$file = 'file.example.txt';
$ext = explode('.', $file);
echo 'The file extension is : ' . $ext[count($ext) - 1];
//استخدمنا الدالة count للحصول على عدد عناصر المصفوفة $ext ومن ثم انقصنا منها 1 للحصول على مفتاح اخر عنصر .
?>
الحصول على وقت تعديل أو تغيير أو الوصول لملف :
للحصول على بصمة الوقت التي تمثل آخر وقت لتغيير ملف ما , نستخدم الدالة filectime , حيث تقبل هذه الدالة وسيطا ً واحدا ً هو مسار الملف .
أما للحصول على بصمة الوقت لآخر تعديل على الملف , نستخدم الدالة filemtime , وتقبل هذه الدالة - كما في الدالة السابقة - وسيطا ً وحيدا ً هو مسار الملف .
الفرق التقني بين الدالة filectime و الدالة filemtime هو أن الدالة filectime تُعيد جميع التغيرات على ملف سواء ً على محتوياته أم على صلاحيات الوصول إليه أم تغيير المستخدم المالك له . أما الدالة filemtime فهي تشير الى آخر تعديل في محتويات الملف فقط .
ملاحظة : الحرف c في الدالة filectime يدل على كلمة change , أما الحرف m في الدالة الثانية فهو يدل على الكلمة modification .
<?php
echo date("m/d/Y H:i:s", filemtime('file1.txt'));
?>والدالة fileatime تُعيد بصمة وقت آخر وصول للملف أو false في حال فشلها , وكما في الدوال السابقة فهي تقبل مسار ملف ما كوسيط .
الحصول على صلاحيات ملف :
بعد معرفة وجود قيد ما سواءً أكان ملفاً أم مجلداً , علينا أن نعلم ما هي الأفعال التي يمكننا القيام بها على القيد , أ] هل لدينا الصلاحيات للقراءة و الكتابة و التنفيذ .
في php نستخدم الدوال is_readable , is_writable , is_ executable لمعرفة امكانية القراءة أو الكتابة أو التنفيذ على التوالي وبالترتيب .
تُعيد هذه الدوال true في حال نجاحها أو false ماعدا ذلك , وتقبل وسيطا ً وحيدا ً هو مسار القيد .
المثال التالي يختبر إمكانية القراءة والكتابة و التنفيذ والحصول على حجم الملف وغيرها من المعلومات المتعلقة بالملف file1.txt :
<?php
$file = 'file1.txt';
echo '<pre>';
if(file_exists($file) === true)
{
echo "Displaying file information for file $file ...<br>";
echo 'File path :' .realpath($file). '<br>';
echo 'File size :'. floor(filesize($file) / 1024). 'KB <br>';
echo 'Last File changing time : ' .date("m/d/Y H:i:s", filectime('file1.txt')). '<br>';
echo 'Last File modification time : '. date("m/d/Y H:i:s", filemtime('file1.txt')). '<br>';
echo 'Last File access : ' .date("m/d/Y H:i:s", fileatime('file1.txt')). '<br>';
echo 'Is readable? : ';
echo is_readable($file) == true ? 'true' : 'false';
echo '<br>';
echo 'Is writable? : ';
echo is_writable($file) == true ? 'true' : 'false';
echo '<br>';
echo 'Is executable? : ';
echo is_executable($file) == true ? 'true' : 'false';
echo '<br>';
}
else
{
echo "File $file is not exists ...<br>";
}
echo '</pre>';
?>مثال على إخراج الكود السابق :
Displaying file information for file file1.txt ... File path :/opt/lampp/htdocs/image/file1.txt File size :8KB Last File changing time : 01/25/2013 21:57:47 Laast File modification time : 01/25/2013 20:40:03 Last File access : 01/25/2013 20:40:05 Is readable? : true Is writable? : true Is executable? : false
حذف ملف :
هل انت متأكد من أنك تريد حذف الملف , استخدم الدالة unlink :) , تقبل هذه الدالة وسيطا ً واحدا ً هو مسار الملف المُراد حذفه , وبالتأكيد يجب أن تكون لديك صلاحيات كتابة على الملف المُحدد حتى تستطيع حذفه عدا ذلك سيتم اظهار خطأ E_WARNING .
<?phpunlink('file1.txt');?>
تغيير صلاحيات قيد :
كما في نظام linux والانظمة الشبيهة باليونكس , حيث نستخدم الأمر chmod لتغيير صلاحيات قيد ما , نستخدم الدالة chmod في لغة php للقيام بالمهمة ذاتها .
لكن php لا تقبل الاعلان عن الصلاحيات كسلسلة نصية مثلا ً "a-wx" , وإنما تحصرها فقط باستخدام الصلاحيات بالارقام في النظام الثماني , أي تكون الصلاحية مكونة من اربعة ارقام الرقم الاول هو صفر , أما الارقام الثلاث الباقية هي عبارة عن الصلاحيات للمستخدم و لمجوعة المستخدم و لبقية المستخدمين على التوالي و بالترتيب , الجدول التالي يوضح الارقام والمصلاحيات المقابلة لها :
* الرقم 0 يشير الى عدم اعطاء أي صلاحية
* الرقم 1 يشير الى اعطاء صلاحية التنفيذ فقط .
* الرقم 2 يشير الى اعطاء صلاحية الكتابة فقط .
* الرقم 3 يشير الى اعطاء صلاحية الكتابة والتنفيذ .
* الرقم 4 يشير الى اعطاء صلاحية القراءة فقط .
* الرقم 5 يشير الى اعطاء صلاحية القراءة والتنفيذ .
* الرقم 6 يشير الى اعطاء صلاحية القراءة و الكتابة .
* الرقم 7 يشير الى اعطاء صلاحية القراءة والكتابة والتنفيذ .
نقبل هذه دالة chmod وسيطين , الاول هو مسار القيد المُراد تغيير صلاحياته , والثاني هو الصلاحية , مثال :
<?php
chmod('folder/file1.txt', 0600); # القراءة والكتابة للمستخدم , لاشيئ لبقية المستخدمين
chmod('folder/file1.txt', 0755); # القراءة والكتابة والتنفيذ للمالك , القراءة و التنفيذ لبقية المستخدمين
?>
نسخ أو نقل ملف :
نستعمل الدالة copy لنسخ الملفات , تقبل هذا الدالة وسيطين الاول هو مسار الملف المُراد نسخة و الثاني هو المسار الجديد . في حال وجود ملف في المسار الجديد فسيتم استبداله تلقائيا ً .
copy($source, $dest);
اما لنقل ملف فنستخدم الدالة rename التي تقوم اساسا ً بتغيير اسم الملف لكن يمكن استخدامها لنقله , تقبل هذه الدالة وسيطين الاول هو مسار الملف و الثاني هو مسار الملف الجديد :
rename($oldname, $newname);
مثال :
<?php
copy ('file1.txt', 'file2.txt');
rename('file2.txt', '../file.txt');
?>
قراءة الملفات والكتابة عليها :
قبل اجراء أي عمليات على الملف , علينا تهيئته وذلك بانشاء مقبض للملف عن طريق الدالة fopen التي تقبل وسيطين الوسيط الأول هو مسار الملف , أما الوسيط الثاني هو الوضع المراد فتح الملف به , الجدول التالي يبين الاوضاع المختلفة لفتح ملف :
* الوضع r : يفتح الملف للقراءة فقط مع وضع مؤشر الملف في بدايته (سنتحدث لاحقا ً عن مؤشر الملف وكيفية تحريكه) .
* الوضع r+ : يقوم بفتح الملف للقراءة والكتابة مع وضع مؤشر الملف في بدايته .
* الوضع w : يقوم بفتح الملف للكتابة فقط ويقوم بمسح جميع محتوياته , وإذا لم يكن الملف موجودا ً سوف يقوم بانشاءه .
* الوضع w+ : كما في الوضع w , لكنه يقوم بفتح الملف للقراءة والكتابة .
* الوضع a : يقوم بفتح الملف للكتابة فقط ويضع مؤشر الملف عند نهايته , إذا لم يكن الملف موجودا ً يقوم بإنشاءه .
* الوضع a+ : يقوم بفتح الملف للقراءة و الكتابة ويضع مؤشر الملف عند نهايته , إذا لم يكن الملف موجودا ً يقوم بإنشاءه .
الفرق بين a و w يكمن في أن w يقوم بحذف محتويات الملف , بينما الوضع a يحافظ على محتويات الملف و يضع المؤشر عند نهايته .
يمكن اضافة الحرف b الى الاحرف السابقة لفتح الملف بالنظام الثنائي , ويفيد هذا الوضع عند القراءة أو الكتابة على ملفات غير نصية .
يجب أن تكون لديك الصلاحية للقراءة أو الكتابة (حسب الوضع الذي تقوم باستخدامه) على الملف , ما عدا ذلك سيتم توليد رسالة خطأ مفادها أنك لا تملك الصلاحيات الكافية للقيام بتلك المهمة .
يمكنك باستخدام الدالة fopen الاشارة الى ملفات خارج السيرفر المُنفذ عليه البرنامج , عن طريق بروتوكول HTTP أو ftp أو غيرهم ....
<?php
$handle = fopen("file.txt", "r");
$handle = fopen("./folder/file.zip", "wb");
$handle = fopen("http://www.example.com/", "r");
$handle = fopen("ftp://user:password@example.com/somefile.txt", "w");
?>ويتم تحرير الذاكرة باغلاق مقبض الملف عن طريق الدالة fclose التي تقبل وسيطا وحيدا ً هو مقبض الملف المُنشئ بواسطة الدالة السابقة .
ملاحظة : انشاء مقبض لملف لا يقتصر على الدالة fopen حيث يوجد دوال اخرى مثل الدالة fsockopen التي تقوم بانشاء مقبض لملف عن طريق اتصال socket , وهذا الموضوع خارج عن نطاق درسنا حاليا ً.
قراءة البيانات من ملف :
بعد انشاء مقبض الملف باستخدام الدالة fopen , نقوم باستخدام الدالة fread للقراءة من الملف وتقبل وسيطين : الاول هو مقبض الملف , والثاني هو عدد البايتات التي سيتم قراءتها من الملف بدءاً من مكان وجود مؤشر القراءة :
fread($handle, $length);
ولقراءة الملف باكمله نقوم بتحدبد قيمة الوسيط length بجحم الملف عن طريق الدالة filesize كما في المثال التالي الذي يقوم بطباعة محتويات الملف file1.txt :
<?php $filename = 'file1.txt'; $handle = fopen($filename, 'r'); $contents = fread($handle, filesize($filename)); echo $contents; fclose($handle); ?>
الدالة fgets شبيهة جدا ً بالدالة fread وتقوم بنفس العمل تقريبا ً حيث في معظم الاحيان يمكن استخدام fgets عوضا عن fread , حيث الفرق الاساسي بينهما هو ان الدالة fgets لا تتطلب تحديد عدد البايتات التي يجب قراءتها من الملف حيث تكون القيمة الافتراضية للوسيط length هي 1024 بايت . وكلا الدالتين تقومان بالتوقف عن القراءة عندما تصلان الى نهاية الملفEOF (End Of File)
الكتابة على ملف :
من اهم العمليات التي يمكن اجراءها على ملف هو اضافة و تعديل محتواه , ويتم ذلك في لغة php عن طريقة الدالة fwrite التي تقوم بكتابة البيانات المُمررة اليها الى ملف , طبعا يحب فتح الملف بوضع يسمح بالكتابة عليه كما في الوضعين (w , a) , الدالة fwrite تقبل ثلاثة وسطاء , الوسيط الاول هو مقبض الملف والثاني هو البيانات المُراد كتابتها و الثالث اختياري يمثل عدد البايتات التي سيتم كتابتها , فاذا تم تحديد الوسيط الثالث فان الكتابة على الملف سوف تتوقف عندما يصبح عدد البايتات المكتوبة مساويا لقيمة هذا الوسيط , الشكل العام للدالة fwrite هو :
fwrite($handle, $string, $length);
لا تنسى ان الدالة fwrite تقوم بطباعة رسالة خطأ عند عدم توفر صلاحيات للكتابة .
المثال التالي يقوم بطباعة الجملة "Hello World !!" على الملف file1.txt :
<?php $filename = 'file1.txt'; $handle = fopen($filename, 'w+'); fwrite($handle, 'Hello World !!'); fclose($handle); ?>
الدالة fputs هي دالة مكافئة Alias للدالة fwrite , اي انها تقوم بنفس العمل تماما ً وتأخذ الوسائط ذاتها .
الدالة feof :
تقوم هذه الدالة باعادة true في حال وصل مؤشر القراءة الى نهاية الملف و false عدا ذلك و تُفيد عندما نقوم بالدوران على محتويات ملف لقراءته , وتقبل هذه الدالة وسيطا وحيدا ً هو مقبض الملف .
<?php
$file = fopen('file1.txt', 'r');
while(!feof($file))
{
echo fgets($file). '<br>';
}
fclose($file);
?>
تغيير مكان المؤشر :
لتغيير مكان المؤشر سواء عند القراءة أو الكتابة نستخدم الدالة fseek التي تقبل وسيطين اجباريين , الاول هو مقبض الملف والثاني هو offset الذي سوف يتم وضع المؤشر عنده .
fseek($handle, $offset);
ملاحظة : عند فتح الملف بوضع a أو a+ فإن الكتابة سوف تكون في اخر الملف حتى لو قمت بتغيير مكان المؤشر .
الدالتين file_get_contents و file_put_contents :
تقوم الدالة file_get_contents بقراءة ملف بأكمله على شكل سلسلة نصية و يُمرر لها مسار الملف كوسيط , شكلها العام :
file_get_contents($filename);
اما الدالة file_put_contents فتقوم بكتابة البيانات المُمررة اليها بالوسيط الثاني على الملف الذي يتم تحديده بمساره والذي يشكل الوسيط الاول :
file_put_contents($filename, $data);
وتقوم هذه الدالة بانشاء الملف اذا لم يكن موجودا ً , وفي حال وجوده تقوم بمسح جميع محتوياته !
ايهما استخدم fopen ومن ثم اقرأ الملف عن طريق fread ام استخدم file_get_contents ؟
بشكل بسيط اذا كنت تريد قراءة جميع محتويات ملف ما فاستخدم file_get_contents اما اذا كنت تريد قراءة عدد محدد من البايتات فاستخدم fread وذلك لتوفير اكبر قدر ممكن من الذاكرة .
ثانيا ً : التعامل مع المجلدات
يمكن باستخدام php القيام بمختلف العمليات على المجلدات كانشاءها و حذفها وتغيير صلاحيات الوصول إليها .
القراءة من مجلد :
كما في دالة fopen عند التعامل مع الملفات , تُستخدم الدالة opendir للحصول على مقبض للمجلد , حيث تقبل الدالة opendir وسيطا ً واحدا ً هو مسار المجلد , الشكل العام لتعريف هذه الدالة هو :
$resorce = opendir($path);
وايضا ً لتحرير الذاكرة وإغلاق مقبض الملف , نستخدم الدالة closedir التي تقوم بعمل مشابه للدالة fclose , تقبل هذه الدالة وسيطا ً واحدا ً هو مقبض المجلد الذي قُمنا بإنشاءه باستخدام الدالة opendir :
closedir($handle);
قراءة محتويات مجلد :
تستخدم الدالة readdir لقراءة القيد التالي من مجلد تم انشاء مقبضه بواسطة الدالة opendir , حيث تقوم هذه الدالة بقراءة قيود الملفات على التتالي وحسب ترتيب نظام الملفات المُستخدم . تقبل هذه الدالة وسيطا ً واحدا ً هو مقبض المجلد و تُعيد القيد (اسم الملف أو المجلد) , وللمرور على جميع قيود المجلد نستخدم حلقة التكرار while . ولتطبيق الدوال الثلاث السابقة نجرب المثال التالي :
<?php
$dir = opendir('folder');
while (($file = readdir($dir) )!== false)
{
echo $file.'<br>';
}
closedir($dir);
?>في البداية قمنا بانشاء مقبض للمجلد ومن ثم حلقة تكرار يتم فيها طباعة اسم الملف أو المجلد ومن ثم قمنا بتحرير الذاكرة واغلاق المقبض .
لاحظ وجود قيدين ممثلين بـ "." و ".." , و للتخلص منهم نعدل بالكود السابق لكي يتأكد من أن القيد لا يساوي احدى هاتين القيمتين :
<?php
$dir = opendir('folder');
while (($file = readdir($dir) )!== false)
{
if($file == '.' OR $file == '..')
{
continue;
}
echo $file.'<br>';
}
closedir($dir);
?>حذف المجلدات :
لحذف مجلد نستخدم الدالة rmdir التي تقبل وسيطا ً واحدا ً هو مسار المجلد المُراد حذفه , لكن يجب أن يكون هذا المجلد فارغا ً أما اذا كان المجلد يحوي أي ملف او مجلد فرعي , فلن يتم تنفيذ هذه التعليمة و سيتم توليد رسالة خطأ .
لكن اذا اردنا حذف مجلد يحوي ملفات ومجلدات فرعية , فيجب علينا أولا ً أن نقوم بحذف جميع محتوياته قبل محاولة استدعاء الدالة السابقة :
<?php
function remove_dir($path)
{
if(is_dir($path) === false)
{
return false;
}
$dir = opendir($path);
while (($file = readdir($dir) )!== false)
{
if($file == '.' OR $file == '..')
{
continue;
}
if(is_file($path.'/'.$file))
{
unlink($path.'/'.$file);
}
elseif(is_dir($path.'/'.$file))
{
remove_dir($path.'/'.$file);
}
}
rmdir($path);
closedir($dir);
}
remove_dir('folder');
?>إنشاء مجلد : بالطبع يمكنك باستخدام php انشاء المجلدات وتعيين صلاحيات الوصول إليها , ويتم ذلك بواسطة الدالة mkdir التي تقبل وسيطين , الأول اجباري هو اسم المجلد والثاني إختياري هو صلاحيات الوصول للمجلد , ويكون شكلها العام كالتالي :
mkdir($pathname, $mode);
وبشكل افتراضي يكون mode مساويا ً للقيمة 0777 , أي صلاحيات القراءة والكتابة والتنفيذ لجميع المستخدمين .
