lchown()
PHP lchown() changes the owner of a symbolic link without following it to the target. Covers syntax, return value, chown() differences, and permission rules.
The PHP lchown() function changes the owner of a symbolic link itself, without following the link to its target. This page explains what it does, how it differs from chown(), the exact signature and return value, when you actually need it, and the permission rules that make it succeed or fail.
What is the lchown() function?
lchown() is a built-in PHP function that sets the user (owner) of a symbolic link. The "l" prefix means it operates on the link, not on the file the link points to — the same convention used by the underlying C library calls (lchown vs chown).
This distinction only matters for symbolic links. A symlink is a small file that stores a path to another file. Most filesystem calls dereference a symlink automatically: if you call chown() on a symlink, you change the owner of the target file. lchown() is the variant that stops at the link and changes the link's own ownership instead.
lchown() is the user-ownership counterpart of lchgrp(), which changes a symlink's group.
Syntax
lchown(string $filename, string|int $user): bool| Parameter | Description |
|---|---|
$filename | Path to the symbolic link whose owner you want to change. |
$user | The new owner — either a username (string) such as 'www-data' or a numeric user ID (int) such as 33. |
Return value. lchown() returns true on success and false on failure (and emits a warning, for example when you lack permission or the path does not exist).
Basic example
<?php
$link = '/path/to/link';
$user = 'myuser';
if (lchown($link, $user)) {
echo 'Ownership of symbolic link updated successfully';
} else {
echo 'Failed to update ownership of symbolic link';
}Here the owner of the symbolic link /path/to/link is set to myuser. The if checks the boolean result so you can react to failure instead of silently ignoring it.
lchown() vs chown(): why it matters
The difference is easiest to see when a link and its target are owned differently. Suppose report.txt is a real file and latest is a symlink to it:
<?php
$target = '/var/data/report.txt';
$link = '/var/data/latest'; // symlink -> report.txt
// Changes the OWNER OF report.txt (chown follows the link):
chown($link, 'alice');
// Changes the OWNER OF the symlink "latest" only; report.txt is untouched:
lchown($link, 'bob');Use lchown() whenever you specifically want the link's metadata to change without touching — or accidentally re-owning — the file it points to. Using chown() here would be a bug if your intent was to re-own the link itself.
Demonstrating it end to end
This script creates a real file and a symlink to it, then changes the link's owner to the current user and confirms the result. Because changing ownership normally requires elevated privileges, re-owning to the current user is the one case an ordinary user is allowed to do.
<?php
$target = sys_get_temp_dir() . '/lchown_target.txt';
$link = sys_get_temp_dir() . '/lchown_link';
file_put_contents($target, "hello\n");
@unlink($link); // remove any leftover link from a previous run
symlink($target, $link); // create the symbolic link
$me = posix_getpwuid(posix_geteuid())['name']; // current process user
if (lchown($link, $me)) {
echo "Link owner set to: " . posix_getpwuid(lstat($link)['uid'])['name'] . "\n";
} else {
echo "lchown() failed\n";
}lstat() (rather than stat()) is used to read the link's own metadata, mirroring the way lchown() writes it.
Permissions and gotchas
- Privilege required. Changing an item's owner to another user typically requires root. As a non-root user you can usually only "change" the owner to yourself, which is effectively a no-op. Expect
falseplus a warning otherwise. - Windows.
lchown()is a POSIX-style operation and is not available on Windows. It is meant for Unix-like filesystems. - The path must be a symlink. Pointing
lchown()at a regular file still works through the OS, but the entire point of the function is symlinks — usechown()for ordinary files. - Suppress, don't ignore. Failures raise an
E_WARNING. Prefer checking the return value (as above) over silencing the warning with@and hoping for the best.
Related functions
chown()— change the owner of a file (follows symlinks).lchgrp()— change the group of a symbolic link.chgrp()— change the group of a file.fileowner()— read the user ID of a file's owner.symlink()— create a symbolic link.readlink()— return the target a symlink points to.
Conclusion
lchown() changes the owner of a symbolic link itself rather than the file it targets — the key reason to reach for it instead of chown(). Remember that it needs appropriate privileges, is Unix-only, and returns a boolean you should always check.