2011年4月12日 星期二

Write file manipulation cross-platform PHP code

As we use Windows computers to develop our PHP scripts and Linux servers in production, we must be careful about what we use in our PHP script, especially when manipulating files.
A lot of PHP function work well in cross-platform, rename(), unlink(), copy(), realpath(), glob() ... all of them will do the job, whether they are called in Linux, or Windows, but when playing with temporary directory (That can be at different places, even on same platform), parsing file paths or include_path, we need some tools.
One thing to avoid is doing specific part of code for Windows, and specific for Linux.
So I will focus in this post on some functions and constants around file manipulation that are helpful when writing cross-platform code.

Temporary directory with sys_get_temp_dir()
sys_get_temp_dir() function is useful to find the path of the directory PHP stores temporary files by default.
echo sys_get_temp_dir();
Will output on Windows
C:\Windows\Temp\
and on Linux
/tmp
If you want to put some files in temporary directory, and don't want to check what is the temporary directory path, sys_get_temp_dir() is the function made for that.

DIRECTORY_SEPARATOR
Even if some people tell you that / will do the job in both Windows and Linux, using DIRECTORY_SEPARATOR is the good way to go.
Nothing tell us that next PHP Version or next OS you will deploy your PHP on will not change this, it's not about if it works or not with /, but if you really want to do cross-platform PHP at 100%, not just when you find it useful.
So DIRECTORY_SEPARATOR will produce / on Linux, and \ on Windows.
Where it's again useful, is for exploding or applying regular expression on paths
explode(DIRECTORY_SEPARATOR, $path);
will look and perform better than doing
preg_split('/\\|\//', $path);

PATH_SEPARATOR
When playing with include_path, one difference between Windows and Linux, is the path separator between each include path, : for Linux and ; for Windows.
PATH_SEPARATOR will contain the right path separator for the actual platform.
# Printing base include_path
echo get_include_path() . PHP_EOL;

#Adding temporary directory to include_path
set_include_path(get_include_path() . PATH_SEPARATOR .
sys_get_temp_var() . DIRECTORY_SEPARATOR . 'somefolder');

# Printing modified include_path
echo get_include_path();
Will output in Linux
.:/usr/share/pear:/usr/share/php
.:/usr/share/pear:/usr/share/php:/tmp/somefolder
And on Windows
.;C:\Program Files\Zend\ZendServer\bin\pear;
.;C:\Program Files\Zend\ZendServer\bin\pear;C:\Windows\Temp\somefolder

Creating and managing temporary files with tmpfile()
tmpfile() function is useful as it will create a temporary file with a unique name in read-write mode and will returns a file handle to use with fwrite(), fread(), ...
The file is then removed by PHP when closed (fclose()), or when the script ends, you don't have to worry about cleaning or doing platform dependent code.
# Creating temporary file
$handle = tmpfile();

# Listing what is under temporary directory
var_dump(glob(sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'php*'));

# Closing resource link
echo 'Closing temporary file resource ...' . PHP_EOL;
fclose($handle);

# Listing what is under temporary directory
var_dump(glob(sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'php*'));
Will output on Linux
array(1) {
[0]=>
string(14) "/tmp/phpJeGEGm"
}
Closing temporary file resource ...
array(0) {
}
And on Windows
array(1) {
[0]=>
string(26) "C:\Windows\Temp\php82.tmp"
}
Closing temporary file resource ...
array(0) {
}
As you see, temporary file is created by PHP, and then removed without any action.

Conclusion
As you see, writing cross-platform PHP code is quick and simple, and can save you a lot of time, simply check PHP documentation if you have any doubt in a function.

reference : http://blog.elijaa.org/index.php?post/2010/10/14/Write-file-manipulation-cross-platform-PHP-code

沒有留言:

wibiya widget