Path manipulation — realpath, basename, dirname, pathinfo
Concept
Temporary files and directories are essential for safe file processing — use them as staging areas before atomically moving results to their final location, or as scratch space for data that shouldn't be persisted.
tmpfile(): Creates a temporary file and returns its file handle. The file is automatically deleted when the handle is closed or the script ends. The file is created in the system temp directory. There's no way to get the filename easily (use stream_get_meta_data($handle)['uri']). Useful for scratch space that must be cleaned up.
tempnam(string $dir, string $prefix): Creates a temporary file in $dir with a unique name starting with $prefix. Returns the path. Does NOT auto-delete — you must unlink() it yourself. Useful when you need to know the path (e.g., to pass it to an external command).
sys_get_temp_dir(): Returns the system temp directory path (/tmp on Linux, C:\Windows\Temp on Windows, or the value of sys_temp_dir php.ini setting). Always use this instead of hardcoding /tmp.
Temporary directories: PHP has no built-in mkdtemp() equivalent. Create one manually: $dir = sys_get_temp_dir() . '/' . uniqid('app_', true); mkdir($dir, 0700). Ensure cleanup via a finally block or a destructor.
Security: Temporary files created in a world-writable /tmp can be a security risk (TOCTOU attacks, symlink attacks). Use 0600 permissions, unique names, and process them quickly. On Linux, tmpfs means /tmp is in RAM — fast but bounded.
Code Example
<?php
declare(strict_types=1);
// tmpfile — auto-deleted when closed
$tmp = tmpfile();
fwrite($tmp, "temporary data");
rewind($tmp);
$content = stream_get_contents($tmp);
$tmpPath = stream_get_meta_data($tmp)['uri']; // e.g., /tmp/phpXXXXX
echo "Temp file path: $tmpPath\n";
fclose($tmp); // file deleted here automatically
// tempnam — manually managed
$tempFile = tempnam(sys_get_temp_dir(), 'upload_');
try {
// Process uploaded file to temp location
file_put_contents($tempFile, $uploadedContent);
processFile($tempFile);
// Move to permanent location
rename($tempFile, '/var/www/storage/processed/' . basename($originalName));
$tempFile = null; // don't delete in finally — we moved it
} finally {
if ($tempFile !== null && file_exists($tempFile)) {
unlink($tempFile);
}
}
// Temporary directory for multi-file operations
function withTempDirectory(callable $work): mixed
{
$tempDir = sys_get_temp_dir() . '/' . uniqid('tmp_', true);
mkdir($tempDir, 0700);
try {
return $work($tempDir);
} finally {
// Clean up temp directory
$iter = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($tempDir, \FilesystemIterator::SKIP_DOTS),
\RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($iter as $file) {
$file->isDir() ? rmdir($file->getPathname()) : unlink($file->getPathname());
}
rmdir($tempDir);
}
}
withTempDirectory(function(string $dir) {
file_put_contents("$dir/part1.txt", "chunk 1");
file_put_contents("$dir/part2.txt", "chunk 2");
// combine, process, then move to permanent location
$combined = file_get_contents("$dir/part1.txt") . file_get_contents("$dir/part2.txt");
file_put_contents('/var/www/storage/result.txt', $combined);
});