PHP file() API Function

PHP file() API Function

===

PHP file() API Function

The PHP file() API function dates back to the first release of PHP 4. The PHP file_get_contents() API function arrived later, in PHP 4.3.0, but there is still older PHP code that uses the PHP file() API function.

The PHP file() API function returns an indexed array. Each value in the array contains

a single line of the file. The following PHP code prints the first line of the data.txt file, including the EOL character sequence at the end of the line:

$a = file ( 'data.txt' ); print $a [ 0 ];

In PHP 5, an optional second parameter was added, the flags parameter. The flags had three options that could be combined using the bitwise OR operator (|):

FILE_IGNORE_NEW_LINES FILE_USE_INCLUDE_PATH FILE_SKIP_EMPTY_LINES

The first one, FILE_IGNORE_NEW_LINES, is the most commonly used. It instructs the PHP file() API function to remove EOL characters from the end of each line.

The following PHP code prints the first line of the data.txt file but does not include the EOL character sequence at the end of each value in the array:

$a = file ( 'data.txt' , FILE_IGNORE_NEW_LINES );

print $a [ 0 ];

The Node.js conversion for the PHP file() API function is somewhat more compli‐ cated than the Node.js conversion for the PHP file_get_contents() API function:

var fs = require ( 'fs' );

var FILE_IGNORE_NEW_LINES = 0x2 ;

var a = false ; var flags = FILE_IGNORE_NEW_LINES ; fs . readFile ( __dirname + '/' + 'data.txt' , 'utf8' , function ( err , data ) { if ( ! err ) { a = data . replace ( /\r\n?/g , '\n' ); a = a . split ( '\n' );

a . neol = a . length - 1 ; if (( a . length > 0 ) && ( a [ a . length - 1 ] === '' )) { a . splice ( a . length - 1 , 1 );

if (( flags & FILE_IGNORE_NEW_LINES ) === 0 ) { for ( var i = 0 ; i < a . neol ; ++ i ) {

a [ i ] += '\n' ; } }

PHP file() API Function | 183 PHP file() API Function | 183

The if statement with the !err condition is where things get complicated. The first Node.js statement converts EOL characters for Windows, Mac, and Linux text

files into the \n end-of-line character for the operating system that the Node.js server is running on:

a = data . replace ( /\r\n?/g , '\n' );

The second Node.js statement converts the string to an array of lines that conforms to the PHP file() API function specification:

a = a . split ( '\n' );

The following Node.js statements handle the last line of the file. The PHP implemen‐ tation has quirky handling for the last line of a file:

a . neol = a . length - 1 ; if (( a . length > 0 ) && ( a [ a . length - 1 ] === '' )) { a . splice ( a . length - 1 , 1 );

Finally, if the FILE_IGNORE_NEW_LINES is not specified, EOL characters are added to the end of the lines. To conform to the PHP implementation, the last line may or may not have an EOL character appended to it:

if (( flags & FILE_IGNORE_NEW_LINES ) === 0 ) { for ( var i = 0 ; i < a . neol ; ++ i ) {

a [ i ] += '\n' ; } }

Due to the length of the converted Node.js code, it is recommended that the PHP file() API function be implemented using the quick-and-dirty technique of creating a Node.js file() function to match the specification of the PHP file() API function as close as possible.

The following Node.js file() function demonstrates how to implement a Node.js file() function with similar parameters to the PHP file() API function, plus an ad‐ ditional callback function parameter:

var fs = require ( 'fs' );

var FILE_IGNORE_NEW_LINES = 0x2 ; function file ( filename , flags , callback ) {

if ( ! callback ) { callback = flags ; flags = 0 ; }

184 | Chapter 9: File Access 184 | Chapter 9: File Access

if ( err ) { data = false ;

} else { data = data . replace ( /\r\n?/g , '\n' ); data = data . split ( '\n' );

data . neol = data . length - 1 ;

if (( data . length > 0 ) && ( data [ data . length - 1 ] === '' )) {

data . splice ( data . length - 1 , 1 );

if (( flags & FILE_IGNORE_NEW_LINES ) === 0 ) { for ( var i = 0 ; i < data . neol ; ++ i ) { data [ i ] += '\n' ;

} } delete data . neol ; } callback ( data ); }); }

The Node.js file() function would be called using the following code:

file ( __dirname + '/' + 'data.txt' , FILE_IGNORE_NEW_LINES , function ( data ) { var a = data ; // for clarity console . log ( a [ 0 ]); });

Similar to the PHP file() API function, the second argument, flags, is optional. The FILE_IGNORE_NEW_LINES flag could be omitted. The callback function would be passed as the second argument instead of the third:

file ( __dirname + '/' + 'data.txt' , function ( data ) {

var a = data ; // for clarity console . log ( a [ 0 ]); });

The following find-and-replace action will convert the PHP file() API function to the Node.js file() function. But, before executing the action, copy the Node.js file() function implementation into the .njs file:

Operation: "Find/Replace" in Eclipse PDT Find: file( Replace: Options: None Action: Find, then Replace/Find

At each occurrence, apply the linearity concepts from previous chapters to correctly implement the Node.js callback function that replaces the PHP return value. Also, insert the __dirname constant before the first Node.js argument, if required.

PHP file() API Function | 185

Beneath the commonly used PHP file_get_contents() API function and the older PHP file() API function, PHP has a core set of file handling APIs. These APIs are used to implement the more convenient higher level APIs. Node.js also has a core set of file handling API functions.