link()
The link() function is a built-in PHP function that creates a hard link from the target file to the destination file. A hard link is a file system object that
The PHP link() function creates a hard link — a second filesystem entry that points to the exact same data on disk as an existing file. This page covers what a hard link actually is, the function's syntax and return value, a complete runnable example, how it differs from a symbolic link, and the gotchas that cause it to fail.
What is the link() Function?
link() creates a hard link from an existing file (the target) to a new name (the link). A hard link is not a copy and it is not a shortcut: it is a second directory entry that references the same inode — the underlying on-disk object that stores a file's data and metadata. Because both names point to the same inode, they are completely interchangeable: editing through one name changes what you see through the other, and the file's data is only deleted once every hard link to it is removed.
Two consequences follow directly from that:
- Hard links must live on the same filesystem (partition) as the target. Inodes are local to a filesystem, so you cannot hard-link across drives or mount points. If you need to link across filesystems, use a symbolic link instead — see
symlink(). - You usually cannot hard-link a directory. Most operating systems forbid hard links to directories to prevent reference cycles in the filesystem tree.
Syntax
link(string $target, string $link): bool| Parameter | Description |
|---|---|
$target | Path to the existing file you want to link to. |
$link | Path of the new hard link to create (must not already exist). |
The function returns true on success and false on failure, emitting an E_WARNING when it fails.
A Complete, Runnable Example
This example creates a file, hard-links it, and then proves both names share one inode:
<?php
$target = __DIR__ . '/target.txt';
$link = __DIR__ . '/hardlink.txt';
file_put_contents($target, "Hello hard links\n");
if (link($target, $link)) {
echo "Created hard link\n";
}
echo "Same inode? " . (fileinode($target) === fileinode($link) ? "yes" : "no") . "\n";
echo "Link count: " . stat($target)['nlink'] . "\n";
echo "Read via link: " . file_get_contents($link);
unlink($link); // remove only the new name
echo "After unlink, target still exists? " . (file_exists($target) ? "yes" : "no") . "\n";Output:
Created hard link
Same inode? yes
Link count: 2
Read via link: Hello hard links
After unlink, target still exists? yesNotice that after link() the link count (nlink) is 2 — the inode now has two names. Removing one name with unlink() just decrements that count; the data survives until the count reaches zero. This is exactly why deleting a hard-linked file does not free its disk space if other hard links remain.
Handling Failure Gracefully
Because link() emits a warning on failure, in production code you typically suppress the warning with @ and act on the return value, or check the destination first:
<?php
$target = __DIR__ . '/target.txt';
$link = __DIR__ . '/hardlink.txt';
if (file_exists($link)) {
echo "A file already exists at the link path.\n";
} elseif (@link($target, $link)) {
echo "Hard link created.\n";
} else {
echo "Could not create hard link.\n";
}Common reasons link() returns false:
- The target file does not exist, or you lack read access to it.
- You lack write permission on the directory where the link will be created.
- The link path already exists.
- The target and link are on different filesystems.
- The target is a directory (not permitted on most systems).
Hard Link vs. Symbolic Link
Hard link (link()) | Symbolic link (symlink()) | |
|---|---|---|
| Points to | The same inode (data) | A path (another filename) |
| Survives deleting the original | Yes — data stays until all links removed | No — becomes a dangling link |
| Can cross filesystems | No | Yes |
| Can link a directory | Usually no | Yes |
| Detect with | stat()['nlink'] > 1 | is_link() |
If you need to know whether a path is a symbolic link, or read where it points, see is_link() and readlink(). To inspect a link's metadata, use linkinfo().
When Would I Use This?
Hard links are handy for deduplication and atomic file swaps. Backup tools use them so that unchanged files across snapshots share one copy on disk. Deployment scripts hard-link a new build into place and then rename over the old name so readers never see a half-written file. For everyday "shortcut" needs that cross drives or point at directories, reach for symlink() instead.
Conclusion
link() creates a hard link — a second name for the same inode on the same filesystem. The data lives until the last hard link is removed, links cannot cross filesystems, and directories generally cannot be hard-linked. Use the runnable example above to see the shared-inode behaviour for yourself, and pair link() with unlink(), symlink(), and is_link() for full control over filesystem links. For a broader tour of file functions, see the PHP Filesystem chapter.