touch
Sets a file's modification and access times, creating the file if it does not exist.
touch(string $filename, ?int $mtime = null, ?int $atime = null): bool- Added in PHP 4.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$filename | string | The name of the file being touched. It is created if it does not exist. |
$mtimeoptional | ?int= null | The modification time as a Unix timestamp. If null, the current system time() is used. |
$atimeoptional | ?int= null | The access time as a Unix timestamp. If null, the value of mtime is used; if both are null, the current system time is used. |
Return value
boolReturns true on success or false on failure.
Errors
Emits an E_WARNING and returns false when the file cannot be created or its times cannot be changed, typically a permissions problem.
Changelog
- PHP 8.0.0mtime and atime are now nullable.
touch() does two jobs. On a file that does not exist it creates an empty one. On a file that does exist it rewrites the modification and access timestamps, by default to now.
When to reach for it
- Creating a marker or sentinel file — a lock, a "migration ran" flag, an empty log the web server can later append to.
- Invalidating a time-based cache by pushing a source file's mtime forward, or expiring one by pushing it into the past.
- Keeping a session or heartbeat file fresh so a garbage collector that prunes by mtime leaves it alone.
What trips people up
The permission rules differ between the two jobs. Setting the times to now only needs write access to the file. Setting them to an explicit timestamp requires you to own the file — write access is not enough — so a script running as the web server user cannot backdate a file owned by someone else, and gets a warning instead.
The parameters are in the order mtime then atime, which is the reverse of what many people assume from ls -l habits. Passing only mtime sets the access time to the same value; you cannot change the modification time while leaving the access time alone.
Finally, filemtime() reads the stat cache, so check timestamps after a clearstatcache() or you will see the old value.
Example
When to use it
- Create an empty log file with the right ownership before a long-running process starts appending to it.
- Bump a template file's mtime so a cache layer that compares timestamps rebuilds the compiled version.
- Backdate a fixture file in a test to verify that cleanup code deletes anything older than 30 days.
Frequently asked questions
Does touch overwrite an existing file?
No. It creates the file only if it is missing; on an existing file it changes the timestamps and leaves the contents untouched. Use file_put_contents() or fopen() in 'w' mode to empty a file.
Why does touch fail with a permission warning when I can write to the file?
Setting an explicit mtime or atime requires ownership of the file, not just write permission. Calling touch($file) with no timestamps only needs write access and will succeed.
Which argument is the modification time?
The second one. touch($file, $mtime, $atime) sets modification time first, access time second; if you pass only $mtime, the access time is set to the same value.
More examples
Different modification and access times
The second argument is the modification time and the third the access time, in that order. Here they land on 2001-09-09 and 2017-07-14 respectively.
<?php
touch('demo.txt', 1000000000, 1500000000);
clearstatcache();
echo 'mtime: ', gmdate('Y-m-d', filemtime('demo.txt')), "\n";
echo 'atime: ', gmdate('Y-m-d', fileatime('demo.txt')), "\n";
unlink('demo.txt');Expire a cache file by backdating it
Pushing the mtime an hour into the past makes the freshness check treat the file as stale, which is the usual way to force a cache rebuild in a test.
<?php
file_put_contents('cache.dat', 'cached value');
touch('cache.dat', time() - 3600);
clearstatcache();
$age = time() - filemtime('cache.dat');
echo 'age in seconds: ', $age, "\n";
echo $age > 600 ? "stale, rebuild\n" : "fresh\n";
unlink('cache.dat');touch does not truncate an existing file
Unlike fopen($f, 'w'), touch() leaves existing content alone and only updates timestamps. The file still holds its 18 bytes afterwards.
<?php
file_put_contents('demo.txt', "important content\n");
touch('demo.txt');
clearstatcache();
echo 'size: ', filesize('demo.txt'), "\n";
echo file_get_contents('demo.txt');
unlink('demo.txt');
Discussion