Documentation on tempnam
tempnam = Create file with unique file name
Creates a file with a unique filename, with access permission set to 0600, in the specified directory. If the directory does not exist or is not writable, tempnam() may generate a file in the system's temporary directory, and return the full path to that file, including its name.
dir The directory where the temporary filename will be created. prefix The prefix of the generated temporary filename. Note: Windows uses only the first three characters of prefix.
Usage, params, and more on tempnam
string tempnam ( string $dir
, string $prefix
)
dir
The directory where the temporary filename will be created. prefix
The prefix of the generated temporary filename. Note: Windows uses only the first three characters of prefix.
Returns the new temporary filename (with path), or FALSE
on failure.
Notes and warnings on tempnam
Basic example of how to use: tempnam
Example #1 tempnam() example
<?php
$tmpfname = tempnam("/tmp", "FOO");
$handle = fopen($tmpfname, "w");
fwrite($handle, "writing to tempfile");
fclose($handle);
// do here something
unlink($tmpfname);
?>
Other code examples of tempnam being used
Watch out using a blank $dir as a "trick" to create temporary files in the system temporary directory.
<?php
$tmpfname = tempnam('', 'FOO'); // not good
?>
If an open_basedir restriction is in effect, the trick will not work. You will get a warning message like
Warning: tempnam() [function.tempnam]: open_basedir restriction in effect.
File() is not within the allowed path(s): (/var/www/vhosts/example.com/httpdocs:/tmp)
What works is this:
<?php
$tmpfname = tempnam(sys_get_temp_dir(), 'FOO'); // good
?>
tempnam() function does not support custom stream wrappers registered by stream_register_wrapper().
For example if you'll try to use tempnam() on Windows platform, PHP will try to generate unique filename in %TMP% folder (usually: C:\WINDOWS\Temp) without any warning or notice.
<?php
// << ...custom stream wrapper goes somewhere here...>>
echo '<pre>';
error_reporting(E_ALL);
ini_set('display_errors', true);
clearstatcache();
stream_register_wrapper('test', 'MemoryStream');
mkdir('test://aaa');
mkdir('test://aaa/cc');
mkdir('test://aaa/dd');
echo 'PHP '.PHP_VERSION;
echo '<br />node exists: '.file_exists('test://aaa/cc');
echo '<br />node is writable: '.is_writable('test://aaa/cc');
echo '<br />node is dir: '.is_dir('test://aaa/cc');
echo '<br />tempnam in dir: '.tempnam('test://aaa/cc', 'tmp');
echo "<br /></pre>";
?>
ouputs:
--------------------
PHP 5.2.13
node exists: 1
node is writable: 1
node is dir: 1
tempnam in dir: C:\Windows\Temp\tmp1D03.tmp
If you want to create temporary file, you have to create your own function (which will probably use opendir() and fopen($filename, "x") functions)
>Under UNIX (where you can rename onto an extant file and so I used link), you will have to remove both the link and the link's target.
Couldn't you do
<?php
if ($newFileCreated) {
unlink ($sysFileName);
return $newFileName;
}
?>
and get the same semantics as the windows version?
Beware: functions are not atomic. If many processes call the same function at the same time, you may end up with unwanted behavior.
If you need your own variant of tempnam, use something like this:
<?php
function tempnam_sfx($path, $suffix)
{
do
{
$file = $path."/".mt_rand().$suffix;
$fp = @fopen($file, 'x');
}
while(!$fp);
fclose($fp);
return $file;
}
// call it like this:
$file = tempnam_sfx("/tmp", ".jpg");
?>
You may replace mt_rand() by some other random name generator, if needed.
Guillaume Paramelle's comments below are worth underlining: tempnam() will not accept a relative path for its first directory. If you pass it one, it will (on Windows XP at least) create the temporary file in the system temp directory.
The easiest way to convert a relative path to an absolute path is to prepend getcwd():
<?php
$file = tempnam('files/temp', 'tmp'); // Wrong!
$file = tempnam(getcwd() . 'files/tmp', 'tmp') // Right.
?>
This function creates a temporary directory. The previous example given could bug if between the unlink() and mkdir() some process creates the same directory or file. This implementation is faster too.
<?php
function tempdir($dir, $prefix='', $mode=0700)
{
if (substr($dir, -1) != '/') $dir .= '/';
do
{
$path = $dir.$prefix.mt_rand(0, 9999999);
} while (!mkdir($path, $mode));
return $path;
}
?>
The file created by tempnam() will have file permissions that reflect the current umask applied to the default (e.g., 0600 or -rw-------). This is the case whether the umask is set before starting the web server process, or set by an earlier call to PHP's umask() function.
For example, if the current umask is 0022, the temporary file is created with permissions 0600 (read/write by owner).
Also, if the current umask is 0222, the temporary file is created with permissions 0400 (read-only by owner). (This is problematic if your code then tries to open the temporary file for writing.)
It's important to remember that the umask revokes permissions. In neither of the above examples are the group, other, or execute permissions set.
See: umask(), chmod().
<?php
function tempdir($dir=false,$prefix='php') {
$tempfile=tempnam('','');
if (file_exists($tempfile)) { unlink($tempfile); }
mkdir($tempfile);
if (is_dir($tempfile)) { return $tempfile; }
}
/*example*/
echo tempdir();
// returns: /tmp/8e9MLi
?>
Notice that tempnam will return NULL (not false) if the second parameter <prefix> isn't transferred:
<?php
var_dump(tempnam(sys_get_temp_dir())); // NULL
?>
also the warning will be generated:
Warning: tempnam() expects exactly 2 parameters, 1 given in php shell code ...