note 42052 added to function.tempnam
| From: | bishop at rn2 dot php dot net | Date: | Sat, 01 May 2004 00:03:58 +0000 |
| Subject: | note 42052 added to function.tempnam | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-69055@lists.php.net to get a copy of this message | ||
Creating a temporary file with a specific extension is a common requirement on dynamic websites.
Largely this need arises from Microsoft browsers that identify a downloaded file's mimetype
based on the file's extension.
No single PHP function creates a temporary filename with a specific extension, and, as has been
shown, there are race conditions involved unless you use the PHP atomic primitives.
I use only primitives below and exploit OS dependent behaviour to securely create a file with a
specific postfix, prefix, and directory. Enjoy.
<?php
function secure_tmpname($postfix = '.tmp', $prefix = 'tmp', $dir = null) {
// validate arguments
if (! (isset($postfix) && is_string($postfix))) {
return false;
}
if (! (isset($prefix) && is_string($prefix))) {
return false;
}
if (! isset($dir)) {
$dir = getcwd();
}
// find a temporary name
$tries = 1;
do {
// get a known, unique temporary file name
$sysFileName = tempnam($dir, $prefix);
if ($sysFileName === false) {
return false;
}
// tack on the extension
$newFileName = $sysFileName . $postfix;
if ($sysFileName == $newFileName) {
return $sysFileName;
}
// move or point the created temporary file to the new filename
// NOTE: these fail if the new file name exist
$newFileCreated = (isWindows() ? @rename($sysFileName, $newFileName) : @link($sysFileName,
$newFileName));
if ($newFileCreated) {
return $newFileName;
}
unlink ($sysFileName);
$tries++;
} while ($tries <= 5);
return false;
}
?>
The isWindows function is mostly left as an exercise for the reader. A starting point is below:
<?php
function isWindows() {
return (DIRECTORY_SEPARATOR == '\\' ? true : false);
}
?>
Like tempnam(), this function requires you to cleanup your own files later. 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. Cleanup is left entirely to the reader.
----
Manual Page -- http://www.php.net/manual/en/function.tempnam.php
Edit -- http://master.php.net/manage/user-notes.php?action=edit+42052
Delete -- http://master.php.net/manage/user-notes.php?action=delete+42052&report=yes
Reject -- http://master.php.net/manage/user-notes.php?action=reject+42052&report=yes
Search -- http://master.php.net/manage/user-notes.php