tempnam

(PHP 4, PHP 5)

tempnamCreate file with unique file name

Description

string tempnam ( string $dir , string $prefix )

Creates a file with a unique filename, with access permission set to 0600, in the specified directory. If the directory does not exist, tempnam() may generate a file in the system's temporary directory, and return the full path to that file, including its name.

Parameters

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.

Return Values

Returns the new temporary filename (with path), or FALSE on failure.

Changelog

Version Description
4.0.6 Prior to PHP 4.0.6, the behaviour of the tempnam() function was system dependent. On Windows the TMP environment variable will override the dir parameter, on Linux the TMPDIR environment variable has precedence, while SVR4 will always use your dir parameter if the directory it points to exists. Consult your system documentation on the tempnam(3) function if in doubt.
4.0.3 This function's behavior changed in 4.0.3. The temporary file is also created to avoid a race condition where the file might appear in the filesystem between the time the string was generated and before the script gets around to creating the file. Note, that you need to remove the file in case you need it no more, it is not done automatically.

Examples

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);
?>

Notes

Note: If PHP cannot create a file in the specified dir parameter, it falls back on the system default. On NTFS this also happens if the specified dir contains more than 65534 files.

See Also

Коментарии

Be careful with you forward and back slashes. Innocent looking code like this...

$uploaddir = "C:/Program Files/Apache Group/Apache2/htdocs/sasdap/uploads/";
$tempFile = tempnam ($uploaddir, "TMPANAL");
$fp = fopen($tmpfname, "w");
fwrite($fp, $iqdata);
//fclose($fp);

... may show something odd when echoing $tempFile";

i.e. /Program Files/Apache Group/Apache2/htdocs/sasdap/uploads/\TMP3D.tmp
                                                       
Must... remember... to... use... backslashes...

 - Lee P. Reilly
2002-08-28 20:54:51
http://php5.kiev.ua/manual/ru/function.tempnam.html
The "newtempnam" recipe provided below (posted by "tempnam" on " 23-Jul-2003 08:56") has at least one race condition.  The while loop checks to make sure that the file in question doesn't exist, and then goes and creates the file.  In between the existence test and the fopen() call there is an opportunity for an attacker to create the file in question.

This is a classic race-condition, and while it seems difficult to exploit there are a number of well-known attacks against this kind of sloppy file creation.

The atomic primitives necessary to implement secure file creation are not available at the language level in PHP.  This further underscores the need for PHP-language developers to rely on the language's security primitives (including tempnam() and tempfile()) instead of rolling their own.
2003-11-25 17:54:28
http://php5.kiev.ua/manual/ru/function.tempnam.html
Автор:
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.
2004-04-30 23:03:58
http://php5.kiev.ua/manual/ru/function.tempnam.html
>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?
2004-07-04 11:20:55
http://php5.kiev.ua/manual/ru/function.tempnam.html
Автор:
It is worth noting that if the 'dir' that you supply doesn't exist, then it is silently ignored and the system /tmp directory used. At least under Linux, PHP v4.1.2.

I had a script that appeared to work fine with safe mode switched off, but I didn't realise that my 'dir' parameter had a typo (so the files were going in /tmp), and once safe mode was switched on I started getting errors because the rest of the script couldn't read files from the system /tmp folder.
2005-01-20 13:35:20
http://php5.kiev.ua/manual/ru/function.tempnam.html
Автор:
If you go to the linux man page for the C function tempnam(3), you will see at the end "Never use this function. Use mkstemp(3) instead." But php's tempnam() function doesn't actually use tmpnam(3), so there's no problem (under Linux, it will use mkstemp(3) if it's available).
2005-01-21 15:03:04
http://php5.kiev.ua/manual/ru/function.tempnam.html
Note that tempnam returns the full path to the temporary file, not just the filename.
2005-03-06 00:10:41
http://php5.kiev.ua/manual/ru/function.tempnam.html
This Example makes a File called "user.txt"
in the dir www.XXXXX.XX/restricted/
<?php
$tmpfname 
tempnam($_ENV["DOCUMENT_ROOT"]."/restricted""FOO");
$handle fopen($tmpfname"w");
fwrite($handle"writing to tempfile");
fclose($handle);

// do here something
//echo($_ENV["DOCUMENT_ROOT"]);
copy($tmpfname,'user.txt');
 
?>
2005-09-18 16:51:48
http://php5.kiev.ua/manual/ru/function.tempnam.html
Автор:
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(09999999);
    } while (!
mkdir($path$mode));

    return 
$path;
  }
?>
2006-02-03 02:32:51
http://php5.kiev.ua/manual/ru/function.tempnam.html
Beware that on Windows NT and other windows, if you have, for example, a variable $work_dir with a path to some dir on your document root(or any other dir). Note the following:
<?php
$work_dir 
'C:/some/path/to/document_root/dir';
file_exists($working_dir); // Returns true
is_writable($working_dir); // Returns true
$tempfile tempnam($working_dir,'img');
//$temfile now contains a system wide temp directory file, like 'C:/WINNT.SBS/img444.tmp' instead of the directory we pass it
//Thats because we need to give I_USR (IIS user) user write permission to $working_dir  although according to the aforementioned functions seemed it already had it...
//If you want to use just the system wide temp directory return by default by tempnam you will also need to give it write permission to I_USR user to be able to write to that file...
?>
2006-08-27 20:19:54
http://php5.kiev.ua/manual/ru/function.tempnam.html
Автор:
I want to guarantee that the file will be created in the specified directory or else the function should return FALSE, I have a simple function that works, but I am unsure if its a potential security issue.

function dir_tempnam($dir, $prefix)
{
    $real_dir_path = realpath($dir);
    if (substr($real_dir_path, -1) != '/')
        $real_dir_path .= '/';
   
    $tempfile = tempnam($real_dir_path, $prefix);
    $name = basename($tempfile);
   
    if(is_file($real_dir_path.$name))
        return $name;
    else
    {
        @unlink($name);
        return FALSE;
    }
}

This function returns just the name of the temporary file in the specified directory, or FALSE.

Obviously it could return the entire $tempfile, but in my case, I actually want the basename value seperate.
2007-01-12 06:47:47
http://php5.kiev.ua/manual/ru/function.tempnam.html
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.
?>
2007-09-03 06:51:56
http://php5.kiev.ua/manual/ru/function.tempnam.html
<?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

?>
2009-01-28 11:15:11
http://php5.kiev.ua/manual/ru/function.tempnam.html
Автор:
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
?>
2009-08-30 20:39:53
http://php5.kiev.ua/manual/ru/function.tempnam.html
Автор:
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)
2010-03-31 13:57:22
http://php5.kiev.ua/manual/ru/function.tempnam.html
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().
2010-04-06 19:20:20
http://php5.kiev.ua/manual/ru/function.tempnam.html
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.
2010-06-03 05:31:55
http://php5.kiev.ua/manual/ru/function.tempnam.html
Автор:
tempnam will not create file in unauthorized area.
Meaning you need access permissions to the temp dir ($dir) in order to create a file there.
2012-02-13 21:44:30
http://php5.kiev.ua/manual/ru/function.tempnam.html
if you don't want to take care of deleting the file yourself, and you don't need a custom prefix, you can use
$file_location=stream_get_meta_data(tmpfile())['uri'];
file will be created automatically, and deleted automatically on script close (thanks to tmpfile()) i found this useful for CURLOPT_COOKIEFILE (which wants a file location, not a handle)
2013-09-29 17:00:22
http://php5.kiev.ua/manual/ru/function.tempnam.html
Автор:
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 ...
2014-05-26 20:54:21
http://php5.kiev.ua/manual/ru/function.tempnam.html
Please note that this function might throw a notice in PHP 7.1.0 and above. This was a bugfix: https://bugs.php.net/bug.php?id=69489

You can place an address operator (@) to sillence the notice:

<?php

if ($tmp = @tempnam() !== false) {
 
// ...
}

?>

Or you could try to set the "upload_tmp_dir" setting in your php.ini to the temporary folder path of your system. Not sure, if the last one prevents the notices.
2017-01-11 15:55:25
http://php5.kiev.ua/manual/ru/function.tempnam.html
Debian 9 Stretch adds private temporary directories, so if you use this function when running as mod_php in Apache expecting that the file can be made available to a third party (e.g. in a shell command or a MariaDB load from temporary file command), it will no longer work: the file will not be visible to other processes, (though the same PHP will be able to read it back in).

Either you need to use the first parameter to put the temporary file somewhere specific (outside the HTML document tree) with permissions such that you can share it with the other party, or change the settings for private tmp, for example:

cp /lib/systemd/system/apache2.service /etc/systemd/system/
# edit /etc/systemd/system/ to change PrivateTmp=true to false
systemctl daemon-reload
service apache2 restart

Choosing a different location is better on a shared server - private tmp files were added for a reason.

This was something that puzzled me for ages when doing a recent OS upgrade.
2018-05-22 18:29:49
http://php5.kiev.ua/manual/ru/function.tempnam.html

    Поддержать сайт на родительском проекте КГБ