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).

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():

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.

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.

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)

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.

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.

// 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:

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.

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.

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 trueis_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...?>

Regarding Typo3 and Safe mode "Generally, everything in TYPO3 can work under safe_mode and open_basedir as long as the script permissions are correct. Notice, this is not something TYPO3 can do better or worse; for a working TYPO3 system there must be access to writing files and directories in the filesystem and this is done by plain PHP functions."

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.