در این آموزش با چند تابع PHP آشنا می شوید که برای تمام کارهای ساده ی شما در زمینه نوشتن و خواندن در فایل ها کافیست. یاد میگیرید که چطور یک فایل را بخوانید، درون یک فایل بنویسید، درون یک فایل متنی بنویسید و موجود بودن یا نبودن یک فایل را چک کنید.

خوشبختانه PHP توابع زیادی برای خواندن و نوشتن فایل های دیتا دارد. در این آموزش قصد داریم ساده ترین راه های خواندن دیتا از یک فایل محلی یا راه دور را به شما نشان دهیم و شما را با روش استفاده از flag ها برای نوشتن موارد مورد نظر خود در فایل آشنا کنیم.

بررسی وجود یا عدم وجود یک فایل

ابتدایی ترین مرحله برای نوشتن یا خواندن دیتا در یک فایل، بررسی موجود بودن یا نبودن آن فایل است. وقتی بخواهیم دیتا را از فایلی که وجود ندارد بخوانیم PHP هشداری به ما می دهد که احتمال دارد موجب کرش کردن کد ما شود.

ساده ترین راه برای بررسی موجودیت یک فایل در PHP استفاده از تابع file_exists($filename)  است. این تابع اگر فایل یا مسیری برابر با $filename داده شده وجود داشته باشد true  و اگر موجود نباشد false  را برمیگرداند. شاید بدانید اما لازم است به این نکته نیز اشاره کنیم که $filename  لزومی ندارد اسم یک فایل باشد، بلکه می تواند یک مسیر مشخص یا نسبیباشد. به طور مثال می توانیم از prime_numbers.txt یا science/project/periodic_table.txt استفاده کنیم.

بهتر است این نکته را نیز به خاطر داشته باشید که این تابع برای فایل هایی که موجود هستند اما به علت محدودیت هایی قابل دسترسی نیستند نیز مقدار false را برمیگرداند.

تابع دیگری که می توان برای بررسی موجود بودن یا نبودن یک فایل به کار برد is_file() است. این تابع در مقایسه با file_exists() تنها در صورتی مقدار true برمی گرداند که مسیر مشخص شده به یک فایل اشاره کند نه یک دایرکتوری.

 

مطمئن شدن از وجود قطعی فایل

اگر کدی که در حال نوشتن آن هستید عملیات های زیادی را روی یک فایل خاص انجام دهد ممکن است نتایج اشتباهی را در کاربرد توابعی که در بالا گفته شد به دست بیاورید. علت این موضوع این است که اجرای هر دو تابع file_exists()  و is_file()  به منظور ارتقاء عملکرد، Cache می شود. همچنین PHP مقادیر برگردانده شده را با تابع های دیگری از file system مثل filesize()، filemtime()و غیره Cache میکند.

می توانید با فراخوانی clearstatcache()  مطمئن شوید که همه ی اطلاعات آن فایل که در حال دست یافتن به آن هستید به روز هستند.

در کل برای این کار فقط یک مشکل وجود دارد و آن وقتی رخ می دهد که یک فایل مشخص چندین بار در یک اسکریپت برای بررسی موقعیتش مورد دسترسی قرار گیرد. همچنین اگر با استفاده از تابع unlink() فایل درون اسکریپت را حذف کنید دیتای Cache  شده پاک می شود. اگر میخواهید با مشکلات مربوط به cache روبرو نشوید باید این نکته را بدانید و به علاوه آگاه باشید که وقتی اطلاعات شما ناکارآمد می شود یا وقتی در تلاش برای دسترسی به اطلاعات مربوط به یک فایل، نتایج نامطلوبی از آن دریافت می کنید میتوانید Cache  را پاک کنید.

 

خواندن دیتا از یک فایل در PHP

یکی از ساده ترین راه های خواندن دیتا از یک فایل در PHP استفاده از تابع file_get_contents($filename, $use_include_path, $context, $offset, $maxlen)  است. این تابع به راحتی کل فایل را خوانده و آن را به صورت یک رشته به شما می دهد. همه ی پارامترها بجز پارامتر اول اختیاری هستند.

پارامتر دوم یک مقدار باینری یا دودویی میگیرد تا تعیین کند که باید در include path مشخص شده دنبال یک فایل بگردد یا نه که این عمل را نیز با استفاده از تابع  set_include_path()  انجام می دهد.

از پارامتر سوم می توانید برای تعیین مجموعه ای از آپشن ها برای تنظیم مجدد روش دسترسی فایل ها کمک بگیرید. می توانید با استفاده از این پارامتر مقادیر header مثل  Cookies  و Host  و همچنین متدHTTP  را مشخص کنید.

پارامتر $offset  نقطه ی شروع خوانش در فایل اولیه را مشخص می کند. با ایجاد یک مقدار منفی، از آخر شروع به شمارش می کند. قابلیت استفاده از آفست های منفی فقط در PHP 7.1.0 اضافه شد و باید گفت که آفست فقط با فایل های محلی کار می کند و فایل های ریموت را پشتیبانی نمی کند.

تابع file_get_contents()  به طور پیش فرض به یکباره کل فایل را میخواند. شما می توانید با دادن یک مقدار به پارامتر $maxlen  رفتار آن را تغییر دهید. طول کاراکترهایی که قرار است خوانده شوند از مقدار آفست شمرده می شود.

این تابع اگر موفق به خواندن دیتا از فایلی که مشخص کرده اید نشود  false  را برمیگرداند. البته می تواند مقادیری که به false ارزیابی می شوند را نیز برگرداند. پس با استفاده از عملگر ===  مطمئن شوید که آیا واقعا مقدار false را برمیگرداند.

می توانید از این تابع برای باز کردن فایل های ریموت استفاده کنید اما این امکان فقط در صورتی وجود دارد که مقدار گزینه ی allow-url-fopen  در php.ini ، true یا 1 باشد.

 

نوشتن دیتا در یک فایل در PHP

یکی از ساده ترین راه ها برای نوشتن داده در یک فایل در PHP کمک گرفتن از تابعfile_put_contents($filename, $data, $flags, $context)  است.

پارامتر $filename مشخص می کند که داده در چه فایلی نوشته شود. پارامتر دوم داده ای است که میخواهید درون فایل بنویسید که اکثر اوقات به صورت یک رشته است اما می تواند آرایه یا منبع Stream هم باشد.

به خاطر داشته باشید که در صورت عدم وجود فایل، PHP به طور خودکار یک فایل را با نام داده شده ایجاد می کند. البته دایرکتوری ای برای شما ایجاد نمی کند، این یعنی می توانید فایل را با نام [file name].txt بدون هیچگونه هشداری ذخیره کنید. دقت کنید که قرار دادن Biology/Evolution/[file name].txt برای $filename در صورتی که Biology/Evolution وجود نداشته باشد، موجب دریافت خطا می شود.

پارامتر $flags چگونگی نوشته شدن محتوا در فایل را مشخص می کند. این پارامتر می تواند هر سه مقدار زیر را داشته یا فاقد آنها باشد:

FILE_USE_INCLUDE_PATH این مقدار به PHP دستور جستجوی نام فایل داده شده در دایرکتوری include را می دهد.

FILE_APPEND این مورد به PHP می گوید که داده ی وارد شده به تابع را به داده ی موجود در فایل اضافه کن. این مورد می تواند هنگام ذخیره کردن داده در فایلی مثل Log یا یک دفترچه ی شخصی به کار برود. ثبت داده ی جدید مثل دمای هوا یا وقایعی که روزانه برایتان اتفاق می افتد با این روش دچار اشتباه و تکرار نمی شود.

LOCK_EX این مورد به PHP می گوید قبل از شروع به نوشتن دیتا در فایل آن را قفل گذاری کند. این کار می تواند از اتفاقات غیرمنتظره هنگام نوشتن یا خواندن داده توسط دو اسکریپت مختلف از روی یک فایل جلوگیری کند. با این مقدارِ خاص می توانید قفل گذاری ارزشمندی داشته باشید. می توانید در مورد این قفل ها در اسناد PHP در زمینه ی تابع flock() بیشتر مطالعه کنید.

این تابع تعداد بایت هایی که به موفقیت و عدم موفقیت در فایل نوشته شده اند را برمیگرداند. البته باید از عملگر برابری کامل برای بررسی موفق بودن یا نبودن نوشتن محتوا در فایل استفاده کنید. چون کدی که صفر بایت در فایل می نویسد همچنان False ارزیابی می شود.   

نوشتن و خواندن داده در فایل

می توانید به وب سایت Project Gutenberg سری بزنید و فایل ها را با استفاده از تابع file_get_contents()  دانلود کنید. وقتی داده را در یک رشته دارید می توانید با استفاده از تابعfile_put_contents()  آن را در یک فایل محلی نیز ذخیره کنید. مثال زیر این موضوع را برای شما روشن می کند: 

 $filename = 'http://www.gutenberg.org/cache/epub/1228/pg1228.txt';
 
$book_content = file_get_contents($filename);
file_put_contents('Biology/Evolution/On the Origin of Species [Charles Darwin].txt', $book_content, LOCK_EX);
 

می توانید صفحات وب یا محتوا را از وب سایت هایی مثل ویکی پدیا نیز به همین روش ذخیره کنید.

به موضوع فایل های محلی بازمیگردیم. موقعیتی را تصور کنید که در آن مجموعه ای از فایل های متنی را دارید و میخواهید محتوای آنها را تجزیه و تحلیل کنید و مواردی مثل کلمات پرتکرار آنها را ببینید. این کار را به راحتی و با استفاده از چند تابع درونسازی شده ی PHP میتوان انجام داد:

$filename = 'On the Origin of Species [Charles Darwin].txt';
$book_content = file_get_contents($filename);
 
$book_content_lowercase = strtolower($book_content);
 
$individual_words = explode(' ', $book_content_lowercase);
echo "There are about ".count($individual_words)." words in the book: ".substr($filename, 0, -4).".\n";
 
$word_frequency = array_count_values($individual_words);
echo "Total number of unique words in the book are ".count($word_frequency).".\n";
echo "The word 'Elephant' occurs ".$word_frequency["elephant"]." times in the book.\n";
echo "The word 'Ant' occurs ".$word_frequency["ant"]." times in the book.\n";
 
if(isset($word_frequency["evolution"])) {
    echo "The word 'Evolution' occurs ".$word_frequency["evolution"]." times in the book.\n";
} else {
    echo "The word 'Evolution' does not occur even once in the book.\n";
}
 
arsort($word_frequency);
echo "The most used word in the book is: '".key($word_frequency)."'.\n";
 
/* Output of all the code above
 
There are about 147520 words in the book: On the Origin of Species [Charles Darwin].
Total number of unique words in the book are 22758.
The word 'Elephant' occurs 3 times in the book.
The word 'Ant' occurs 6 times in the book.
The word 'Evolution' does not occur even once in the book.
The most used word in the book is: 'the'.

ما تمام متن را به حروف کوچک تبدیل کرده و کاری کردیم که هر کلمه با یک فاصله از دیگر کلمات جدا شود. سپس متن با استفاده از explode() به یک آرایه تبدیل شده تا تحلیل تک به تک کلمات آسانتر شود.  جالب است که کلمه ی evolution حتی یک بار هم در کل این کتاب که در مورد نظریه ی تکامل است، وجود نداشت.

این تنها نمونه ای بود از تحلیل خودکار انبوهی از متن. شما هم می توانید چنین کارهایی را با هر متنی که در یک فایل ذخیره شده انجام دهید.

 

واقعه نگاری داده با FILE_APPEND

یکی از نمونه های بسیار مفید می تواند واقعه نگاری یا لاگ برداشتن از اطلاعات در بازه های زمانی کوتاه باشد. این کار می تواند شامل یکی از کارهای روزانه، اطلاعات آب و هوا یا اطلاعات کندوی زنبور عسلی باشد که پرورش می دهید. زمانی که داده را در یک رشته در دسترس دارید می توانید به راحتی آن را در یک فایل نگهداری و با استفاده از پرچم FILE_APPEND  با file_put_contents() به داده ی موجود اضافه کنید.

$filename = "bee-colony.txt";
 
$present = date('l | jS \of F Y h:i:s A', time());
$entry = $present."\n";
 
// A pseudo function which could be replaced with something real.
$bee_information = gather_bee_data();
$entry .= "$bee_information.\n\n";
 
file_put_contents($filename, $entry, FILE_APPEND|LOCK_EX);

از همین کد می توان برای نگهداری مقالات کاربردی روزانه ی ویکی پدیا به طور روزانه در یک فایل یا برای پیگیری مقالات خبری و سرخط خبرها در طول دوره های هفته ای و ماهانه نیز استفاده کرد. برای این کار میتوانید کدی برای دست کاری داده بنویسید و بعد با استفاده از چیزی شبیه به قطعه کد بالا آن را ذخیره کنید.

 

جمع بندی

راه های زیاد دیگری نیز برای خواندن و نوشتن داده در فایل ها در PHP وجود دارد. البتهfile_get_contents()  و file_put_contents()  بدون اضافه کردن موارد غیرضروری، تمام نیازهای اولیه ی شما در این زمینه را تامین می کنند.

تنها زمانی ممکن است با file_get_contents()  به مشکل بخورید که فایلی که قصد خواندن آن را دارید خیلی بزرگ، یعنی مثلا دو گیگابایت یا بیشتر، باشد. علت این مسئله این است کهfile_get_contents()  تمام فایل را به یکباره در مموری بارگذاری می کند و در این حالت احتمال پر شدن مموری با این فایل های بزرگ زیاد است. در این شرایط باید از توابعی مثل fgets() و fread() برای خواندن بخش کوچکی از فایل استفاده کنید. اگر می خواهید از اولین مراحل نصب و اجرای php و محیط شبیه ساز آن تا پیشرفته ترین قسمت های کار با پایگاه داده و مباحث امنیتی و... را بیاموزید، پیشنهاد ما به شما دوره آموزش جامع صفر تا صد PHP با MySQL در دو سطح مقدماتی و پیشرفته است.