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) {
    if (! (isset($postfix) && is_string($postfix))) {
        return false;
    }
    if (! (isset($prefix) && is_string($prefix))) {
        return false;
    }
    if (! isset($dir)) {
        $dir = getcwd();
    }
    $tries = 1;
    do {
        $sysFileName = tempnam($dir, $prefix);
        if ($sysFileName === false) {
            return false;
        }
        $newFileName = $sysFileName . $postfix;
        if ($sysFileName == $newFileName) {
            return $sysFileName;
        }
        $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.