chgrp()
In this article, we will discuss the chgrp() function in PHP. The chgrp() function is used to change the group ownership of a file or directory. We will cover
Introduction
On Unix-like systems every file belongs to a user (the owner) and a group. The group lets several accounts share access to the same file through the file's group permission bits. The chgrp() function in PHP changes which group a file or directory belongs to — the same job the chgrp shell command does, but callable from your code.
This is most often needed when a script creates files that a web server, a deployment user, or a background worker must also read or write: you set the group so all of those accounts (which belong to that shared group) can reach the file.
This article covers the syntax, parameters, return value, common gotchas, and runnable examples, including how to change a whole directory tree.
chgrp()only does something on Unix-like systems (Linux, macOS, BSD). On Windows it does nothing and returnstrue. It is a sibling ofchown()(changes the owner) andchmod()(changes the permission bits).
Syntax
chgrp(string $filename, string|int $group): bool$filename— the path to the file or directory whose group will be changed.$group— the new group, given either as a group name (e.g."www-data") or as a numeric group ID / GID (e.g.33).
Parameters
| Parameter | Required | Description |
|---|---|---|
$filename | Yes | Path to the file or directory to modify. |
$group | Yes | The target group. A string is treated as a group name; an int is treated as a numeric GID. |
Passing a GID is handy when the group name might not resolve on the current host but you know the numeric ID is stable.
Return Values
chgrp() returns a boolean:
true— the group was changed successfully (or the platform is Windows, where the call is a no-op).false— the change failed, usually because the process lacks permission or the group/file does not exist. A warning is also emitted.
Because the return value alone does not tell you why it failed, always check it explicitly rather than ignoring it.
Examples
Change the group of a single file
<?php
$filename = "/path/to/file.txt";
$group = "www-data";
if (chgrp($filename, $group)) {
echo "Group ownership changed to {$group}.";
} else {
echo "Failed to change group ownership.";
}Read the group back after changing it
To confirm the change, look the group up with filegroup(), which returns the file's GID. The cache that the stat functions share can be stale right after a change, so clear it first with clearstatcache():
<?php
$filename = "/path/to/file.txt";
chgrp($filename, "www-data");
clearstatcache(); // forget any cached stat info for the file
$gid = filegroup($filename); // numeric group ID
// On systems with the POSIX extension you can turn the GID into a name:
if (function_exists("posix_getgrgid")) {
$info = posix_getgrgid($gid);
echo "File now belongs to group: " . $info["name"];
} else {
echo "File now belongs to GID: " . $gid;
}Change the group of a whole directory tree (recursive)
chgrp() does not recurse, so to change every file under a directory you iterate yourself. A RecursiveDirectoryIterator makes this concise:
<?php
function chgrpRecursive(string $path, string|int $group): bool
{
$ok = chgrp($path, $group);
if (is_dir($path)) {
$items = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS),
RecursiveIteratorIterator::SELF_FIRST
);
foreach ($items as $item) {
$ok = chgrp($item->getPathname(), $group) && $ok;
}
}
return $ok;
}
if (chgrpRecursive("/var/www/uploads", "www-data")) {
echo "Whole tree updated.";
} else {
echo "At least one path could not be changed.";
}Common Gotchas
- Permissions. Only the file owner (when they are a member of the target group) or the superuser can change a file's group. A typical web request running as
www-datacannot reassign files to arbitrary groups, so this often fails silently in shared hosting — always check the return value. - Symbolic links.
chgrp()follows symlinks and changes the group of the target file. To change the group of the link itself, uselchown()family behaviour (lchgrpis not available in PHP, so operate on the link path with the underlying OS tools when needed). - Stale stat cache. PHP caches file metadata; after
chgrp()callclearstatcache()before re-reading the group, or you may see the old value. - No glob expansion.
chgrp("uploads/*", ...)does not work — pass a real path, and loop over matches fromglob()yourself.
Related Functions
chown()— change the file owner.chmod()— change the permission bits.filegroup()— read a file's current group (GID).clearstatcache()— reset cached file metadata.
Conclusion
chgrp() gives PHP a direct way to manage which group owns a file or directory — the key to letting multiple Unix accounts share access. Remember that it needs sufficient privileges, does not recurse on its own, and that you should clear the stat cache before reading the result back. Pair it with chown() and chmod() when you need full control over ownership and permissions.