باز کردن و بستن یک فایل، با توابع fopen و fclose در PHP

با استفاده از تابع fopen در PHP ، می توانیم یک فایل را باز کنیم و همچنین، تابع fclose ، می تواند برای بستن فایل باز شده، به کار رود. شیوه کلی استفاده از این دو تابع، به صورت زیر می باشد :


<?php
$file=fopen("example.txt","r");

// some codes

fclose($file);
?>

عبارت "r" که درون پرانتز تابع fopen نوشته شده است، تعیین کرده که تنها می خواهیم از فایل مورد نظر، اطلاعاتی را بخوانیم. برای موارد دیگر، مثل نوشتن در فایل، باید عبارت های بخصوص دیگری نوشته شود.

چنانچه بخواهیم، در صورتیکه فایل مورد نظر، قابل باز شدن نباشد (مثلا، اصلا فایل موجود نباشد) آنگاه یک پیام به کاربر نمایش داده شود، می توانیم کدهای زیر را بنویسیم :


<?php
    $file=fopen("welcome.txt","r") or exit("عدم موفقیت در باز کردن فایل");

    // some codes

    fclose($file);
?>

به مثال زیر توجه کنید :

فرض کنید در یک فایل با نام example.txt (دقت کنید که txt پسوند فایل است که نوع فایل را مشخص می کند)، عبارت ((hello)) نوشته شده است. اکنون ما قصد داریم که با دستورات PHP ، فایل example.txt را باز کرده و عبارت نوشته شده در آن را در خروجی، به کاربر نمایش بدهیم. برای این منظور، کدهای زیر را می نویسیم (فرض می شود که صفحه PHP شامل این کدها و همچنین فایل example.txt ، هر دو در یک فولدر قرار دارند) :

    <?php
$file=fopen("example.txt","r") or exit("عدم موفقیت در باز کردن فایل");
while(!feof($file)){
    echo fgetc($file);
}
fclose($file);
?>

نتیجه :

hello

خواندن خظ به خط فایل:

$file=fopen("example.txt","r");
while(!feof($file)){
    echo fgets($file);
}
fclose($file);
    

حالا این بار، عمدا نام فایل را اشتباه می نویسیم تا ببینیم آیا خروجی PHP ، همان پیام تعیین شده توسط ما، می باشد یا خیر (البته قبل از آن، پیامی خطایی نیز، توسط خود PHP ، نمایش داده می شود) :

    <?php
$file=fopen("another_name.txt","r") or exit("عدم موفقیت در باز کردن فایل");

while(!feof($file)){
    echo fgetc($file);
}

fclose($file);
?>

نتیجه :

عدم موفقیت در باز کردن فایل

ساخت یک فایل جدید، در PHP

دستور fopen در PHP ، برای باز کردن یک فایل به کار می رود، اما این دستور، برای ساخت یک فایل جدید نیز مورد استفاده قرار می گیرد. تنها نکته این است که باید برای دستور fopen ، حالت write که به معنای نوشتن در فایل است را انتخاب کنیم. این انتخاب، با نوشتن حرف w در پرانتز دستور fopen صورت می گیرد (w حرف اول کلمه write می باشد).

به مثال زیر توجه کنید :

مثال:

فرض کنید بخواهیم فایلی با نام myFile.txt بسازیم، برای این منظور، کدهای زیر را می نویسیم :

<?php
$FileName = "myFile.txt";
$FileHandle = fopen($FileName, 'w') or die("can't open file");
fclose($FileHandle);
?>

نتیجه :

فایلی با نام myFile.txt ، در همان محل فایل PHP صفحه، ساخته می شود (فایل دارای هیچ متنی نیست و خالی می باشد).

با استفاده از PHP ، می توانیم اطلاعات مورد نظرمان را درون فایل های متنی (text files) بنویسیم. برای این منظور، تابع fwrite در PHP به کار می رود. ابتدا باید فایل مورد نظر را با تابع fopen باز کنیم، سپس با تابع fwrite ، اطلاعات مورد نظرمان را در فایل متنی می نویسیم و در آخر، با تابع fclose ، فایل را می بندیم. البته با این روش، تمامی اطلاعات موجود در فایل، پاک می شود و فایل دوباره از نو نوشته می شود، اما در ادامه، روشی را هم برای نوشتن اطلاعات، در ادامه اطلاعات قبلی فایل، شرح خواهیم داد.

به مثال زیر توجه کنید :

مثال

<?php
$FileName = "myFile.txt";
$FileHandle = fopen($FileName, 'w') or die("can't open file");

$stringData = "www.kelidestan.com";
fwrite($FileHandle, $stringData);

fclose($FileHandle);
?>

نتیجه :

فایل با نام myFile.txt ، توسط PHP باز می شود و سپس عبارت www.kelidestan.com ، در ابتدای آن نوشته خواهد شد (اگر اطلاعاتی قبلا در آن موجود باشد، آن اطلاعات پاک می شود). دقت داشته باشید که اگر دستور fopen ، فایلی با این نام، پیدا نکند، یک فایل با این نام خواهد ساخت (این مورد، ویژگی دستور fopen می باشد).

نوشتن اطلاعات، در ادامه اطلاعات یک فایل موجود، با تابع fwrite در PHP :

همان طور که قبلا شرح دادیم، روش قبل باعث می شود که تمامی اطلاعات فایل متنی، حذف شده و فایل از نو نوشته شود. ولی شاید بخواهیم که اطلاعات جدید، در ادامه همان اطلاعات قبلی فایل نوشته شود، برای این منظور، کدهایی مشابه آن کدها باید بنویسیم و تنها تفاوت این است که این بار باید فایل را در حالت append (کلمه append به معنای افزودن یا الحاق کردن می باشد) باز کنیم. بنابراین درون پرانتز دستور fopen ، به جای حرف w که از اول کلمه write گرفته شده است، حرف a از اول کلمه append را می نویسیم تا فایل در حالت append باز شود.

به مثال زیر توجه کنید :

مثال

<?php
$FileName = "myFile.txt";
$FileHandle = fopen($FileName, 'a') or die("can't open file");

$stringData = "www.kelidestan.com";
fwrite($FileHandle, $stringData);

fclose($FileHandle);
?>

نتیجه :

فایل با نام myFile.txt ، توسط PHP باز می شود و سپس عبارت www.kelidestan.com ، بعد از اطلاعات موجود در آن، نوشته خواهد شد.

حذف فایل:

unlink('a.txt');

تغییر نام فایل:

rename("myFolder/myFile.png", "myFolder/myFile_new_name.png");

آپلود (upload) یک فایل، در PHP

معمولا سایت های کاربردی مختلف، قسمتی را برای آپلود (upload) فایل توسط کاربر قرار می دهند تا کاربر بتواند یک عکس، فایل فشرده شده (zip) یا هر نوع فایلی که مد نظر بوده است را بر روی سرور سایت، آپلود نماید. باید دقت داشت که هنگامی که به کاربر اجازه می دهیم که فایلی را بر روی سرور سایت ما آپلود کند، عملا راهی برای نفوذ به سایت خود، در اختیار وی قرار داده ایم، بنابراین برای اینکه از سوء استفاده های احتمالی جلوگیری کنیم، باید یک سری محدودیت را برای آپلود فایل اعمال نماییم. ابتدا یک کد ساده را برای آپلود فایل معرفی می کنیم، اما این کد به درد استفاده واقعی نمی خورد و تنها برای این است که با چگونگی کدنویسی برای آپلود فایل آشنا بشوید، پس از آن، یک کد حرفه ای تر را معرفی می کنیم که با اعمال یک سری محدودیت، امنیت را بیشتر می کند.

برای قسمت آپلود، ابتدا یک فرم HTML می سازیم و سپس اطلاعات حاصل از فرم را به یک فایل PHP می فرستیم تا بر روی آن اطلاعات، پردازش کند (این شیوه کلی ساخت فرم ها است). بنابراین یک فایل با نامی دلخواه می سازیم و کدهای زیر را درون آن می نویسیم (چون یک فرم HTML است، پس می تواند پسوند فایل، html یا php باشد) :

<html>
<body>

<form action="upload_file.php" method="post" enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file"><br>
<input type="submit" name="submit" value="Submit">
</form>

</body>
</html>
    

همان طور که از کد بالا مشخص است، این فرم، اطلاعات را با روش POST ، به فایل upload_file.php می فرستد تا این فایل، بر روی اطلاعات دریافتی، پردازش کند. مشخصه enctype برای فرم، مشخص می کند که نوع اطلاعاتی که کاربر ارسال می کند، چه می باشد. با انتخاب multipart/form-data برای این مشخصه، اعلام کرده ایم که اطلاعات ارسالی، به صورت اطلاعات دودویی (binary data) است.

درون تگ input ، مشخصه type را برابر file قرار داده ایم تا اعلام کنیم که نوع ورودی، به صورت فایل می باشد. بنابراین درون فرم، یک دکمه browse به کاربر نمایش داده می شود تا با آن بتواند فایل مورد نظر را از کامپیوتر خود انتخاب نماید.

ظاهر فرم، به صورت زیر خواهد بود :


یک فایل با نام upload_file.php می سازیم و کدهای زیر را درون آن می نویسیم :

<?php
if ($_FILES["file"]["error"] > 0){
    echo "Error: " . $_FILES["file"]["error"] . "
"; }else{ echo "Upload: " . $_FILES["file"]["name"] . "
"; echo "Type: " . $_FILES["file"]["type"] . "
"; echo "Size: " . ($_FILES["file"]["size"] / 1024) . " kB
"; echo "Stored in: " . $_FILES["file"]["tmp_name"]; } ?>

متغیر$_FILES، یک متغیر فوق سراسری (superglobal) می باشد.

ایجاد یک سری محدودیت برای آپلود فایل :

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

این بار، کدهای فایل upload_file.php را به صورت زیر می نویسیم :


<?php
$allowedExts = array("gif", "jpeg", "jpg", "png");
$temp = explode(".", $_FILES["file"]["name"]);
$extension = end($temp);
if ((($_FILES["file"]["type"] == "image/gif")
    ($_FILES["file"]["type"] == "image/jpeg")
    ($_FILES["file"]["type"] == "image/jpg")
    ($_FILES["file"]["type"] == "image/pjpeg")
    ($_FILES["file"]["type"] == "image/x-png")
    ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 20000)
&& in_array($extension, $allowedExts)){
    if ($_FILES["file"]["error"] > 0){
        echo "Error: " . $_FILES["file"]["error"] . "<br>";
    }else{
        echo "Upload: " . $_FILES["file"]["name"] . "<br>";
        echo "Type: " . $_FILES["file"]["type"] . "<br>";
        echo "Size: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
        echo "Stored in: " . $_FILES["file"]["tmp_name"];
    }
}else{
    echo "Invalid file";
}
?>

در کد بالا تعیین کرده ایم که نوع فایلی که کاربر آپلود می کند، تنها می تواند gif یا jpeg یا png باشد و حداکثر حجم آن نیز باید 20 کیلوبایت (kB) باشد (فایل های بزرگتر، آپلود نخواهند شد). اگر کاربر، فایلی را انتخاب کند که در شرایط فوق صدق نکند، آنگاه یک پیام با عنوان Invalid file به وی نمایش داده می شود.

ذخیره فایل آپلود شده :

با کد قبل، تنها یک کپی از فایل، به صورت موقت نگهداری می شود. عمر این نسخه کپی از فایل، تنها تا پایان اجرای کدها می باشد، بنابراین باید کدهایمان را به گونه ای تغییر بدهیم که بتوانیم فایل را در یک فولدر از سایت، ذخیره نماییم. کدهای فایل upload_file.php را به صورت زیر تکمیل می کنیم :

<?php
$allowedExts = array("gif", "jpeg", "jpg", "png");
$temp = explode(".", $_FILES["file"]["name"]);
$extension = end($temp);
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/pjpeg")
|| ($_FILES["file"]["type"] == "image/x-png")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 20000)
&& in_array($extension, $allowedExts)){
    if ($_FILES["file"]["error"] > 0){
        echo "Return Code: " . $_FILES["file"]["error"] . "<br>";
    }else{
        echo "Upload: " . $_FILES["file"]["name"] . "<br>";
        echo "Type: " . $_FILES["file"]["type"] . "<br>";
        echo "Size: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
        echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br>";

        if (file_exists("upload/" . $_FILES["file"]["name"])){
            echo $_FILES["file"]["name"] . " already exists. ";
        }else{
            move_uploaded_file($_FILES["file"]["tmp_name"],
            "upload/" . $_FILES["file"]["name"]);
            echo "Stored in: " . "upload/" . $_FILES["file"]["name"];
        }
    }
}else{
    echo "Invalid file";
}
?>

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

کد بالا ابتدا چک می کند که آیا فایل درون فولدر upload وجود دارد یا خیر و چنانچه فایل وجود نداشته باشد، یک کپی از آن را در فولدر upload ذخیره خواهد کرد. در صورتی که فایلی با آن نام درون فولدر upload وجود داشته باشد، یک پیام نمایش داده می شود که فایل هم اکنون وجود دارد و بنابراین فایل جدید، ذخیره نخواهد شد.

نکته

چنانچه بخواهیم که بجای نام اصلی فایل، یک نام دیگر برای آن انتخاب کنیم، باید به جای این بخش از کدها :

move_uploaded_file($_FILES["file"]["tmp_name"],
"upload/" . $_FILES["file"]["name"]);
echo "Stored in: " . "upload/" . $_FILES["file"]["name"];        
        

کد زیر را بنویسیم :


$new_name="myImage.png";
move_uploaded_file($_FILES["file"]["tmp_name"],
"upload/" . $new_name);
echo "Stored in: " . "upload/" . $new_name;        
        

البته من تنها به عنوان مثال، نام myImage.png را انتخاب کردم تا بدانید که کدام قسمت را باید تغییر بدهید، در صورتیکه یک کد کامل، باید شامل تشخیص نوع فایل نیز باشد تا نام جدید فایل، دارای پسوند مناسب باشد.

نکته

اگر بخواهیم که فایل در فولدری غیر از فولدر upload ذخیره شود، باید کلمه upload را در کدها، به نام فولدر مورد نظرمان تغییر بدهیم.

توضیحات بیشتر در مورد کدها :

در ادامه، نکاتی را در مورد کدها ذکر خواهیم کرد.

نکته

با استفاده از کدهای زیر، پسوند فایل را تشخیص داده و در یک متغیر ذخیره می کنیم :

$temp = explode(".", $_FILES["file"]["name"]);
$extension = end($temp);  
        

تابع explode یک علامت و یک رشته (string) را دریافت می کند و سپس، رشته مورد نظر را بر اساس علامتی که تعیین کرده ایم، به چندین رشته تجزیه کرده و به صورت یک آرایه رشته ای بر می گرداند. دقت کنید که متغیر فوق سراسری$_FILES، حاوی اطلاعات فایل در حال آپلود می باشد، بنابراین، عبارت زیر، نام فایل در حال آپلود را به ما می دهد :


  $_FILES["file"]["name"]     
       

بنابراین به تابع explode ، نام فایل در حال آپلود را داده ایم و همچنین علامت نقطه (.) را به عنوان علامت مورد نظرمان برای تجزیه رشته (string) انتخاب نموده ایم، بنابراین مثلا فرض کنید که کاربر فایلی با نام myFile.number2.png را برای آپلود انتخاب کند، آنگاه تابع explode ، یک آرایه رشته ای، حاوی سه رشته زیر را بر می گرداند :

myFile
                number2
                png

این آرایه رشته ای، در$tempذخیره می شود. سپس با تابع end ، آخرین عنصر تابع را در متغیر$extensionذخیره می کنیم، زیرا پسوند فایل، همان آخرین رشته قرار گرفته در آرایه رشته ای می باشد. بنابراین پسوند را در متغیر$extensionخواهیم داشت و با آن، می توانیم نوع فایل انتخاب شده توسط کاربر را تشخیص بدهیم.

نکته

یکی از شرط هایی که برای چک کردن صحیح بودن فایل انتخاب شده برای آپلود، در کدها نوشته ایم، به صورت زیر می باشد :

 in_array($extension, $allowedExts))       
        

تابع in_array برای چک کردن وجود یک مقدار در یک آرایه می باشد. اگر مقدار ذخیره شده در متغیر$extensionکه همان پسوند فایل انتخاب شده می باشد، در آرایه$allowedExtsموجود باشد، آنگاه تابع in_array ، مقدار 1 را برمی گرداند و در غیر این صورت، مقدار 0 را برمی گرداند. آرایه$allowedExtsهمان آرایه حاوی پسوندهای مجاز برای آپلود فایل می باشد که قبلا آن را به این صورت تعریف کردیم :

       $allowedExts = array("gif", "jpeg", "jpg", "png"); 
        

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

نکته

گاهی اوقات برخی فایل ها، دارای پسوند با حروف بزرگ می باشند، به عنوان مثال، به جای image.png ، فایل دارای نام image.PNG می باشد. بنابراین پسوند آنها به عنوان پسوند مجاز شناسایی نمی شود. برای در نظر گرفتن این مورد نیز می توانید خط زیر از کدها را :

       $allowedExts = array("gif", "jpeg", "jpg", "png"); 
        

به کد زیر تغییر بدهید :


$allowedExts = array("gif", "GIF", "jpeg", "JPEG", "jpg", "JPG", "png", "PNG");       
        

باز کردن یک فایل متنی و جایگزین کردن برخی عبارت ها (رشته ها - strings) با عبارت های دیگر و ذخیره به صورت یک فایل جدید، با کدهای PHP

فرض کنید که یک فایل متنی با نام file_1.php داریم و می خواهیم که تگ های <tag1> را به تگ های <tag2> تبدیل کنیم (جایگزین کردن عبارت ها) و سپس نتیجه را به صورت یک فایل با نام file_2.php ذخیره نماییم، برای این منظور، کدهای PHP زیر را می نویسیم :

$data = file_get_contents("path/file_1.php");
$data = str_replace("word1", "word2", $data);
file_put_contents("path/file_2.php", $data);

بدست اوردن محتویات یک پوشه:

$directory = "C://";
$files = scandir($directory);

echo "<pre>";
print_r($files);
echo "<pre>";

به دست آوردن لیست نام تمامی فایل ها و زیرپوشه های موجود در یک پوشه

function listFolderFiles($dir){
    $ffs = scandir($dir);
    echo '<ol>';
    foreach($ffs as $ff){
        if($ff != '.' && $ff != '..'){
            echo '<li>'.$ff;
            if(is_dir($dir.'/'.$ff)) listFolderFiles($dir.'/'.$ff);
            echo '</li>';
        }
    }
    echo '</ol>';
}    
listFolderFiles($folder_path);
    

به دست آوردن پسوند یک فایل:

$file_path = '/myFolder/myFile.txt';
$extension = pathinfo($file_path, PATHINFO_EXTENSION);
echo $extension;
    

ساخت یک فایل به صورت موقتی:(temorary)

$temp = tmpfile();
fwrite($temp, "www.kelidestan.com");
fseek($temp, 0);
echo fread($temp, 1024);
fclose($temp); // this removes the file

چک کردن وجود داشتن یک فایل:

if (file_exists('myFile.txt')) {
    // your code
}
    

پردازش بر روی اطلاعات فایل های XML ، با SimpleXML در PHP

در PHP ، روش هایی مثل XML Expat Parser و XML DOM و XML SimpleXML برای پردازش اطلاعات فایل های XML وجود دارد، که در این مبحث، قصد داریم اندکی در مورد SimpleXML شرح بدهیم.

فرض کنید یک فایل XML با نام example.xml داریم که دارای کدهای زیر می باشد (یک سری تگ را با نام های دلخواه در آن تعریف کرده ایم) :

<?xml version="1.0" encoding="UTF-8"?>
<information>
<name>hamid</name>
<age>20</age>
<language>persian</language>
<city>tehran</city>
</information>

برای دیدن ساختار اطلاعات موجود در فایل example.xml ، کدهای PHP زیر را در یک فایل PHP نوشته و فایل PHP را اجرا می کنیم :

$xml=simplexml_load_file("example.xml");
echo "<pre>";
print_r($xml);
echo "<pre>";

نتیجه :

    SimpleXMLElement Object
(
    [name] => hamid
    [age] => 20
    [language] => persian
    [city] => tehran
)
    

اکنون فرض کنید که تنها بخواهیم اطلاعات مربوط به تگ (tag) با نام name را نمایش بدهیم، برای این منظور، کدهای PHP زیر را می نویسیم :

$xml=simplexml_load_file("example.xml");
$name=$xml->name;
echo $name  
    

نتیجه :

hamid

دسترسی به مشخصه های (attributes) تگ ها (tags) در فایل XML :

همان طور که می دانید، در فایل XML ، هر تگ (tag) می تواند دارای تعدادی مشخصه (attribute) باشد. مثلا فرض کنید تگ name که در مثال قبل به کار بردیم، دارای یک مشخصه با نام family باشد :

<name family="heidari">hamid</name>

بنابراین باید روشی نیز برای فراخوانی مشخصه های تگ ها داشته باشیم. برای آشنایی با روش فراخوانی مشخصه ها در فایل XML ، به مثال زیر توجه کنید :

مثال

همان فایل example.xml مثال قبل را این بار کمی تغییر می دهیم (افزودن یک مشخصه به تگ name) :

<?xml version="1.0" encoding="UTF-8"?>
<information>
<name>hamid</name>
<age>20</age>
<language>persian</language>
<city>tehran</city>
</information>
    

حال ابتدا کل ساختار فایل XML را با کدهای PHP نمایش می دهیم :

$xml=simplexml_load_file("example.xml");
echo "<pre>";
print_r($xml);
echo "<pre>";

نتیجه :

    SimpleXMLElement Object
(
    [name] => hamid
    [age] => 20
    [language] => persian
    [city] => tehran
)

اکنون تنها مشخصه family از تگ name را نمایش می دهیم :

$xml=simplexml_load_file("example.xml");
$family = $xml->name->attributes()->family;
echo $family;

نتیجه:

heidari