Timothy's Dev Stuff

A collection of code snippets and other developer things.

CSV and TXT File Reading and Writing in PHP

The need for this information began with the requirement that we would be provided a CSV spreadsheet with information that would need to be extracted, modified, and recompiled into a new CSV which could then be imported to a website. As an extra feature, I decided that I would like to have some kind of logging take place and a message upon completion. The file we are reading would always have the same name and a function that reads that file, does things, logs things, and spits out an export file. To go into those details is beyond the scope of this post but the provided examples will get you going. I kept it simple for now, since the task is not that complex.

To start, I created the functions that will create our files. The way these functions are written, everything happens in the same directory as the PHP script. They can be modified to specify a directory if needed. The same process is used for our log file and our “export” file. We get the date and time to use for file naming, prepend that to a string that is more descriptive of the file contents (which includes the file type), then create the file using fopen() with the argument of ‘w’. This will create the file if it doesn’t already exist. Then we close the file using fclose() and finally return the file name as a string. The returned file name is used in our “processing” function to write to the created files.
/**
 * Create a log file in the same directory
 */
function create_log_file() {
    $todays_date_and_time = date("YmdHi");
    $file_name = $todays_date_and_time . '_log.txt';
    $fp = fopen( $file_name, 'w' );
	fclose( $fp );
    return $file_name;
}

/**
 * Create the export file in the same directory
 */
function create_export_file() {
    $todays_date_and_time = date("YmdHi");
    $file_name = $todays_date_and_time . '_export.csv';
    $fp = fopen( $file_name, 'w' );
	fclose( $fp );
    return $file_name;
}
Next, I created a function that would make it easy to write to the log file. This function accepts two arguments. The first is the file name (which our other function returned) then our message as a string. The function will create a timestamped string, open the specified file in append mode with the ‘a’ argument, then append the message to the file and close it.
/**
 * Write to the specified log file
 * $log_file_name is the name of the file to be written to and is generated with the create_log_file function
 * $message will be added to the log file along with a timestamp
 */
function write_to_log( $log_file_name, $message ) {
    $timestamp = date("Ymd h:i:s A");
    $log_file = fopen($log_file_name, "a");
    fwrite($log_file, "\n{$timestamp}: {$message}");
	fclose( $log_file );
}
From here, we can open the export file in append mode using something like $export_file = fopen( $export_file_name, ‘a’ ); where $export_file_name contains the returned string from our create_export_file() function. With that file open, we can write to it by adding arrays of data with fputcsv( $export_file, $my_array );. This function will essentially append the array to the current spreadsheet row with each index entered in a new cell. And logging our progress is as simple as write_to_log($log_file_name, “Operation complete.”);, where the file name variable contains the string returned from the function that created the log file.

Since this runs when the page/script is accessed, it might be nice to give some kind of visual cue that something happened. I chose to do this by echoing the following HTML on the page once the operation completed successfully.

echo "<h1>Operation Complete &#128077;</h1><p>The file, {$file_name}, was processed successfully. The exported file is <a href='/{$export_file_name}'>{$export_file_name}</a>.</p>";

Additional features to consider would include data validation, error checking and handling, or even an interface that allows the user to upload a file to start the process. Below are some of the resources I used to get through this task.