Getting Started with Adobe After Effects - Part 6: Motion Blur


Upload Image Close it
Select File

A step-by-step guide to learn PHP

Authors

Getting Started with PHP

Getting Started with PHP - Part 6: Interacting with the Filesystem

Oct 9 2012 12:00AM by grantwparks   

PHP provides an enormous list of functions to interact with the file system. There's a separate listing of directory functions. They may not all be meaningful on every operating system. Some functions report or manipulate information about a file (e.g. file_exists, filesize) and some functions are more focused on reading or writing the contents of files (e.g. fread, fputs). The first type of function is very common in command line scripts; automating a process with a script requires doing a lot of checking on files' status before attempting something. In a previous script, the dirname() function was used. It returns the directory for a full file path.

echo dirname (__FILE__);

C:\Users\grantwparks\workspace\phpweb\public

Notice this is the file system path to the script directory. And since it's running on Windows, the path separator is the backslash.

Directory Listing

scandir() returns a directories file names in an array

<?php
$dir = dirname (__FILE__);
$files = scandir ($dir);
print_r ($files);

[25-Aug-2012 01:56:39 UTC] Array
(
    [0] => .
    [1] => ..
    [2] => 6.1.php
    [3] => edit_profile.php
    [4] => form.php
    [5] => fs.php
    [6] => index.html
    [7] => index.php
    [8] => simpleform.html
    [9] => test.php
)

This is the list of files in my /public directory. That's interesting, but only shows the file names. Let's print some information about the files.

<?php
function getFileBody ($dir) {
  $files = scandir ($dir);
  $html = array(
    "<tr><td>file name</td><td>readable?</td>” 
    .”<td>writable?</td><td>file?/td><td>size</td></tr>"
  );

  foreach ($files as $file) {
    $fullPath = $dir .DIRECTORY_SEPARATOR  .$file;
    $html[] = sprintf ("<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>",
      $file,
      (is_readable($fullPath) ? "yes" : "no"),
      (is_writable($fullPath) ? "yes" : "no"),
      (is_file($fullPath) ? "yes" : "no"),
      filesize($fullPath));
  }
  return implode ('', $html);
}
?>
<table>
  <tbody>
  <?php 
    echo getFileBody (dirname (__FILE__));
  ?>
  </tbody>
</table>

file name   	readable?	writable?	file?	size
.   		yes		yes		no	4096
..  		yes		yes		no	4096
6.1.php 	yes		yes		yes	862
6.2.php 	yes		yes		yes	465
edit_profile.php    yes		yes		yes	1796
file.csv    	yes		yes		yes	61
form.php    	yes		yes		yes	540
fs.php  		yes		yes		yes	342
index.html  	yes		yes		yes	161
index.php   	yes		yes		yes	328
simpleform.html yes		yes		yes	506
test.php    	yes		yes		yes	4816

Notice the “files” . and .., they represent the current and parent directory so is_file() returned false for them.

File Input/Output

The most basic thing would be reading the contents of a file. There happen to be many functions to do that. fread, fscanf and a few that begin with “fget”. If sample.txt contains some text to read

<?php 
  if ($fp = fopen('sample.txt', 'r')) {
    echo fread ($fp, 500); // fread requires a length limit
    rewind ($fp);
    echo '<br/>';
    echo fgets ($fp);
    rewind ($fp);
    echo '<br/>';
    echo fgetc ($fp);
    fclose ($fp);
}
?>

some text to read
some text to read
s

The rewind() calls are necessary, because the file pointer is at the end of file after each of the first two reads.

Use fopen() to open a “resource” (it will open URLs as well as files). The arguments are a file name (a full path can be used, here the current directory is the default) and “mode”. There are many mode options, and one should research to find if there are operating system-dependent flags to use. But the primary flags control

  • Opening for reading, writing or both (r, w, r+, w+)
  • What the behavior should be if the file exists. In write mode, an existing file will normally be reused, but fopen(file, 'x') will fail if the file exists.
  • Where to position the file pointer. Beginning of file is the default, use 'a', 'a+' – for append – to position at the end of file.

Working With CSV Files

Jumping right ahead to writing, how about saving an array as a comma-separated value file (.csv) which can be opened by any spreadsheet,

if ($fp = fopen('file.csv', 'w')) {

    fputcsv ($fp, array (
    	'id'      => 124,
    	'name'    => "John Doe",
    	'age'     => 32,
    	'eyes'    => 'green',
    	'social'  => '111-555-0101'
    ));

    fclose ($fp);
}

After opening the file for writing fputcsv() saves the array. Open file.csv in a spreadsheet application (you might have to tell it to use comma separators).

file CSV

fputcsv() really only puts the values of the array, and the data doesn't mean much by itself. It should be easy to add column headers. The arraykeys function will return an array whose values are the keys of its argument array. If the code is changed to also save the arraykeys, then the output will contain a row for column headers, in the form of the keys.

$myArray = array (
    'id'      => 124,
    'name'    => "John Doe",
    'age'     => 32,
    'eyes'    => 'green',
    'social'  => '111-555-0101'
);
fputcsv ($fp, array_keys ($myArray));
fputcsv ($fp, $myArray);

The keys of the array now appear as the first line of the file.

csv headers

How about reading a .csv? Most Web email applications (e.g. gmail) allow exporting a contact list to .csv. Such a file can be read

if ($fp = fopen('google.csv', 'r')) {
  $columns = fgetcsv ($fp);
  print_r($columns);
  fclose ($fp);
}

This file has column headers in its first row, like the one we just wrote. We can essentially reverse the process by reading the first row and using its values as keys for the rest of the rows' columns. Adding a loop to read the rest of the rows in the file after reading $columns

$keyedRows = array ();
while (($row = fgetcsv($fp)) !== false) {
  $keyedRows[] = array_combine ($columns, $row);
}

fgetcsv, like a lot of file functions, returns false at end of file. array_combine() returns a new array whose keys are the values of the first argument and values come from the second argument. Now $keyedRows is an array of all my contact information and every entry in the array is a key/value array for a single contact.

Array (
  [Name] => Joe Contact
  [Given Name] => Joe
  [Additional Name] => 
  [Family Name] => Contact
  ...
  [Organization 1 - Location] => 
  [Organization 1 - Job Description] => 
  [Website 1 - Type] => 
  [Website 1 - Value] => 
  [Jot 1 - Type] => 
  [Jot 1 - Value] => 
)

There are generally many unused fields in the contact file, making it very hard to read. An advanced array function, array_map(), can be used to create an array from an existing one. There are other ways to do the same thing, but “map” is a more recent concept that promotes separating the logic of working with one entry in the array from looping through it. First, we create the function to return a new array entry in place of each original entry.

function unsparseIt ($contact) {
  foreach ($contact as $key => $value) {
    if ($value == '')
      unset ($contact[$key]);
  }
  return $contact;
}

Recall that the $contact argument is a copy of the original value, so even though its fields are unset in the loop that only changes the copy, which still has to be returned as the new array entry. Unsetting array entries “destroys” them and removes them from the array. array_map then calls this function for every entry in its second array argument

$prunedArray = array_map ('unsparseIt', $keyedRows);

$prunedArray now contains a compact version of $keyedRows, with all empty fields removed.

Array (
  [Name] => Joe Contact
  [Given Name] => Joe
  [Family Name] => Contact
  [Group Membership] => * My Contacts
  [E-mail 1 - Type] => * 
  [E-mail 1 - Value] => contactj@acme.com
  [Phone 1 - Type] => Work
  [Phone 1 - Value] => 303-555-3000
  [Organization 1 - Name] => Acme Board of Directors
)

The convenient thing about fgetcsv and fputcsv is that they handle things like escaping commas in values.

Simplest Reading for Small Files

fileget_contents($filename) is one of the simplest, most versatile ways to read files. The filename argument may be a URL. “Proxying” another page or embedding an RSS feed is easy. If you open a script with the following in your browser, you'll see the php.net documentation as if it were your own page.

<?php
  print (file_get_contents("http://php.net/manual/en/function.file-get-contents.php"));
?>

Using PHP's Configuration Parsing

It's very common in PHP to need configuration information defined in its own file and used by the code. A useful function is parseini_file function. Instead of inventing a new configuration file format, it allows one to use the same format as in php.ini and read settings into an array so that values can be directly accessed without creating a bunch of global variables.

[section 1]
env = prod
foo = bar

[othersettings]
bar = foo

$config = parse_ini_file ("myconfig.ini", true);
print_r ($config);

// passing true as 2nd arg will return an array that's
// indexed by [sections]
$config = parse_ini_file ("myconfig.ini", true);
print_r ($config);

Array (
  [env] => prod
  [foo] => bar
  [bar] => foo
)

Array (
  [section 1] => Array (
      [env] => prod
      [foo] => bar
    )
  [othersettings] => Array (
      [bar] => foo
    )
)

If I created a file myconfig.ini with


grantwparks
174 · 1% · 280
5



Submit

Your Comment


Sign Up or Login to post a comment.

"Getting Started with PHP - Part 6: Interacting with the Filesystem" rated 5 out of 5 by 5 readers
Getting Started with PHP - Part 6: Interacting with the Filesystem , 5.0 out of 5 based on 5 ratings
    Copyright © Rivera Informatic Private Ltd Contact us      Privacy Policy      Terms of use      Report Abuse      Advertising      [ZULU1097]