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.
1 |
echo sys_get_temp_dir(); |
Will output on Windows
1 |
C:\Windows\Temp\ |
and on Linux
1 |
/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
1 |
explode(DIRECTORY_SEPARATOR, $path); |
will look and perform better than doing
1 |
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.
1 2 3 4 5 6 7 8 9 |
# 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
1 |
.:/usr/share/pear:/usr/share/php .:/usr/share/pear:/usr/share/php:/tmp/somefolder |
And on Windows
1 |
.;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.
1 2 3 4 5 6 7 8 9 10 11 12 |
# 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
1 2 3 4 5 6 |
array(1) { [0]=> string(14) "/tmp/phpJeGEGm" } Closing temporary file resource ... array(0) { } |
And on Windows
1 2 3 4 5 6 |
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.