1. What is File Manipulation in PHP?

Since PHP is a programming language that runs on the server side, it can freely perform operations such as creating, reading, writing, and deleting files on the server. This is called “file manipulation.”

Why is File Manipulation Necessary?

In actual web development, file manipulation is frequently used to save small-scale data where a database isn’t needed, or to record the system state.

  • Saving Logs: Recording error information and access history in text files.
  • CSV Output: Allowing users to download customer data or product lists in a format that can be opened in Excel.
  • Image Uploads: Saving profile images posted by users to the server.
  • Loading Config Files: Reading configuration data in formats like JSON and reflecting them in the program.

Unlike JavaScript (frontend), since you can access important files within the server, security awareness becomes extremely important.

2. [Basic] Basics of Reading and Writing Files (fopen, fwrite, fclose)

The most basic way to perform file manipulation in PHP is to follow three steps: “Open File (Open) -> Operate (Write/Read) -> Close (Close)”.
This is the same image as when we write in a notebook: “Open the notebook, write with a pen, and close it.”

Roles of Basic Functions

  • fopen(): Open a file (get a file pointer).
  • fwrite(): Write characters to a file.
  • fgets() / fread(): Read file content.
  • fclose(): Close a file (Important: Must close to release memory).

Practical Code: Writing to a File

Here, let’s look at an example of creating a file named “test.txt” and writing characters to it.

<?php
// Specify the file path to write to.
$filename = 'test.txt';

/*
* 1. fopen(filename, mode)
*
* - **Opens** the file and returns a file resource (file pointer).
* - $filename (filename): Specify the file path to open.
* - 'w' (mode): Specify the file open mode.
* - **'w' (write)**: Opens the file in **write-only** mode.
* - The file pointer is set to the **beginning of the file**.
* - If the file **already exists, its content is truncated (overwritten)**.
* - If the file **does not exist, a new file is created**.
* - Returns a file resource ($fp) on success, or **false** on failure.
*/
$fp = fopen($filename, 'w');

// Check if the file was opened successfully ($fp is not false).
if ($fp) {
    /*
    * 2. fwrite(file_pointer, data, [length])
    *
    * - **Writes** data to the file pointed to by the file pointer ($fp).
    * - Specify the string to write in the second argument. "\n" is a newline code.
    * - Returns the number of bytes written on success, or **false** on failure.
    */
    fwrite($fp, "Hello, PHP!\n");
    fwrite($fp, "This is the basics of file manipulation.");

    /*
    * 3. fclose(file_pointer)
    *
    * - **Closes** the open file resource ($fp).
    * - Must be executed at the end of file operations to **ensure content is saved** and release the file lock.
    * - Returns **true** on success, or **false** on failure.
    */
    fclose($fp);
    echo "Writing completed.";
} else {
    // Process when file open fails (e.g., no write permission to the folder).
    echo "Failed to open the file.";
}
?>

Important “Mode” Specification

The behavior changes depending on the “mode” specified in the second argument of fopen.

ModeDescriptionFeature
‘r’Read onlyRead from the beginning of the file. Writing not allowed.
‘w’Write onlyEmpties file content before writing (overwrite). Creates file if missing.
‘a’Append writeWrites to the end of the file. Original content is not deleted.

3. [Advanced] Convenient Bulk Read/Write Functions (file_get_contents and file_put_contents)

Recommended for beginners are convenient functions that can read/write in a single line, omitting steps like fopen and fclose. These are also often used in practice for simple file exchanges.

Writing Data in Bulk: file_put_contents

It automatically handles opening, writing to, and closing the file.

<?php
// Specify the destination file path.
$file = 'log.txt';
// Specify the content to write to the file.
// "\n" is a newline code.
$text = "An error occurred.\n";

/*
* file_put_contents(filename, data, flag)
*
* 1. $file (filename): Specify the target file path.
* - If the file does not exist, a new one is created.
* - Fails if there are no write permissions.
* 2. $text (data): Specify the string or data to write.
* 3. FILE_APPEND (flag): Optional flag.
* - If **FILE_APPEND** is specified, it **appends** to the end of existing content.
* - If not specified (default), existing content is **overwritten** and replaced with new content.
*
* This function returns the number of bytes written on success, or **false** on failure.
*/
file_put_contents($file, $text, FILE_APPEND);
?>

Reading Data in Bulk: file_get_contents

Retrieves the entire content of a file as a string.

<?php
// Specify the file path you want to read.
$file = 'log.txt';

/*
* 🔔 Standard Practice for File Reading (Best Practice)
*
* 1. file_exists(filepath):
* - Checks **whether the specified $file exists** as a boolean (true/false).
* - If you execute file_get_contents when the file doesn't exist, PHP issues a warning and processing may fail.
* - Doing this check improves stability.
*/
if (file_exists($file)) {
    /*
    * file_get_contents(filename):
    *
    * - Reads the entire file into memory **as a string** and returns the content.
    * - Automatically performs the sequence of opening, reading, and closing the file.
    * - Returns file content (string) on success, or **false** on failure.
    *
    * ⚠️ Note: Reading very large files may consume a lot of memory, so in such cases, using stream_get_contents or fopen/fread is more appropriate.
    */
    $content = file_get_contents($file);

    /*
    * nl2br(string):
    *
    * - **Converts newline codes (\n, \r\n, etc.) in the string to HTML <br> tags**.
    * - This allows newlines in the file to be displayed as newlines in the browser.
    */
    echo nl2br($content);
} else {
    // Process when file does not exist (e.g., display error message).
    echo 'File not found: ' . $file;
}
?>

Point:
If you read a very large file (e.g., several GBs) with file_get_contents, an error may occur due to insufficient memory. In that case, use the method of reading little by little using the basic fopen (stream processing).

4. Steps to Upload Image Files and Security Measures

Cases where users upload images via contact forms on websites or SNS features. Here, coordination between HTML forms and PHP is required.

1. Preparation on the HTML Side (enctype attribute is mandatory)

Be sure to specify enctype="multipart/form-data" in the form tag. Without this, file data will not be sent.

<form action="upload.php" method="post" enctype="multipart/form-data">
    <input type="file" name="upload_image">
    <input type="submit" value="Upload">
</form>

2. Saving Process on PHP Side: move_uploaded_file

The sent file is saved in a temporary location, so move it to the location where you want to save it.

<?php
// Information on uploaded files is in $_FILES
if (!empty($_FILES['upload_image']['name'])) {
    
    // Security Measure 1: Rename to avoid filename collisions or Japanese filenames
    // Commonly done by generating a unique ID with uniqid() and attaching the original extension
    $filename = date('YmdHis') . '_' . $_FILES['upload_image']['name'];
    $save_path = 'uploads/' . $filename;

    // Security Measure 2: Simple check if it is an image file (MIME type verification)
    $allow_types = ['image/jpeg', 'image/png', 'image/gif'];
    if (in_array($_FILES['upload_image']['type'], $allow_types)) {
        
        // Move from temporary folder to specified location
        if (move_uploaded_file($_FILES['upload_image']['tmp_name'], $save_path)) {
            echo "Upload successful!";
        } else {
            echo "Failed to save.";
        }
    } else {
        echo "File format not allowed.";
    }
}
?>

Security Measures You Must Take

Files uploaded by users could be viruses or malicious programs (like Web shells).

  • Extension check: Do not allow upload of executable files like .php.
  • Filename renaming: Do not use the filename given by the user as is; save it with a random name changed on the system side.
  • Save location permissions: Configure server settings (e.g., .htaccess) so that programs cannot be executed within the upload folder.

5. How to Get File Metadata and Delete Files

It is also important to use functions that handle metadata such as “Does the file exist?” or “How big is it?”, not just looking at the file contents.

List of Frequently Used Functions

  • file_exists($path): Check if a file or directory exists (Most important).
  • unlink($path): Delete a file.
  • filesize($path): Get file capacity (in bytes).
  • filemtime($path): Get last modified time of the file.

Practical Code: Deleting Old Files

A safe way to write code is to check for “existence” before “deletion.”

<?php
$file = 'old_data.txt';

if (file_exists($file)) {
    // Execute deletion
    if (unlink($file)) {
        echo "File deleted.";
    } else {
        echo "Failed to delete.";
    }
} else {
    echo "File to delete not found.";
}
?>

6. Creating, Deleting, and Listing Directories (Folders)

You can also operate folders (directories) themselves in PHP, not just files.

Basic Functions for Directory Operations

  • mkdir($path, $mode): Create directory (Make Directory).
  • rmdir($path): Delete directory (Remove Directory).
    ※Note: Cannot delete if files remain inside.
  • scandir($path): Get a list of files in the directory.

Practical Code: Creating Yearly Storage Folders

This is an example of creating a folder like “2025” if it doesn’t exist, and displaying its contents.

<?php
$dir = '2025_data';

// 1. Create if folder doesn't exist (specify permissions like 0777 according to environment)
if (!file_exists($dir)) {
    mkdir($dir, 0777); 
    echo "Folder created.<br>";
}

// 2. Get list of files in folder
$files = scandir($dir);

// scandir also gets "." and "..", so exclude them from display
foreach ($files as $file) {
    if ($file !== '.' && $file !== '..') {
        echo "Filename: " . $file . "<br>";
    }
}
?>

7. Concrete Practical Examples of Handling CSV and Text Files

Combining the knowledge so far, here are code examples for scenes often encountered in practice.

Example 1: Reading a CSV File and Displaying it as a Table

A program that reads a member list (CSV) created in Excel etc., and displays it on a web screen.

<?php
$csv_file = 'member_list.csv';

if (($handle = fopen($csv_file, "r")) !== FALSE) {
    echo "<table border='1'>";
    
    // Get one line of CSV as an array with fgetcsv
    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
        echo "<tr>";
        // Display array contents as columns
        foreach ($data as $cell) {
            echo "<td>" . htmlspecialchars($cell) . "</td>";
        }
        echo "</tr>";
    }
    echo "</table>";
    fclose($handle);
}
?>

Example 2: Creating a Simple Access Log

Records the date/time and IP address every time the page is viewed.

<?php
$log_file = 'access_log.txt';

// Get date/time and IP address
$log_data = date("Y-m-d H:i:s") . " - " . $_SERVER['REMOTE_ADDR'] . "\n";

// Save in append mode
file_put_contents($log_file, $log_data, FILE_APPEND | LOCK_EX);
?>

※ Adding LOCK_EX applies a lock (exclusive control) so others cannot write while writing, preventing data corruption.

8. Precautions and Error Handling in File Manipulation

Finally, let’s summarize points where beginners often stumble in file manipulation.

1. Permission Errors

The most common is the Permission denied error.
This occurs when PHP (the web server) does not have “write permission” for the specified directory or file.

Solution: You need to change the permissions of the save destination folder to “755” or “777” using FTP software or SSH commands (chmod) to allow writing.

2. Path Specification Mistakes

If the file is not found (No such file or directory), the path (location of the file) specification is incorrect.

  • Relative path: ../images/photo.jpg (Location viewed from current place)
  • Absolute path: /var/www/html/images/photo.jpg (Location from the root of the server)

In PHP, using __DIR__ (directory of the current file) to specify the absolute path reduces mistakes.
Example: include __DIR__ . '/config.php';

3. Concurrent Access Conflicts

Multiple people access websites simultaneously. If they try to write to the same file at the same time, data may disappear or become corrupted.

Solution: Use “exclusive control” to make other processes wait while writing, using the LOCK_EX flag of file_put_contents or the flock() function.

File manipulation is an important technique that greatly expands the scope of web applications. Start with reading and writing simple text files, then gradually challenge yourself with image uploads and CSV integration.