decoct
Converts a decimal integer to its octal string representation.
decoct(int $num): string- Added in PHP 4.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$num | int | Decimal value to convert. |
Return value
stringA string containing the base-8 representation of $num, with no leading 0 prefix.
Errors
Throws a TypeError if $num is not an int or a value that can be coerced to int.
Changelog
- PHP 8.1Passing a float that loses precision in the implicit int conversion emits a deprecation notice; cast explicitly with (int).
decoct() converts a decimal integer to base 8 and returns it as a string. Its inverse is octdec(). On a 64-bit build the largest convertible value is PHP_INT_MAX, which comes out as 21 sevens.
When to reach for it
Unix file permissions are effectively the only common use. When fileperms() or stat() hands you a decimal mode, decoct() puts it back into the 755 or 644 form everybody recognises. It also occasionally turns up when reading legacy formats or hardware registers that group bits in threes.
What trips people up
An octal literal in PHP source needs a leading 0 (or the clearer 0o prefix added in PHP 8.1), but decoct() does not produce that prefix. So decoct(493) is "755", and if you concatenate it into a string that later gets read as a number, the leading zero must be added by hand.
Watch the extra bits in a real file mode. fileperms() returns the file type bits as well, so decoct(fileperms($f)) yields something like 100644. Mask it first with & 0777. And remember the string is decorative: chmod() expects the integer 0644, never the string "644", which would be read as decimal 644 and set the wrong bits.
Example
When to use it
- Display a file's permission bits in the familiar 755 or 644 notation.
- Log the mode returned by fileperms() or stat() in a form an admin can read.
- Convert a three-bit-grouped hardware register value into readable octal.
Frequently asked questions
Why does decoct not include a leading zero?
decoct() returns only the digits, so decoct(420) is "644". Prepend the 0 yourself for display, or use printf('%04o', $mode) which pads to four characters including the leading zero.
Can I pass decoct output to chmod?
No. chmod() takes an integer, and chmod($file, "644") converts the string to decimal 644, which is the wrong bit pattern. Pass an octal literal such as 0644, or use octdec() to convert a string back to the right integer.
Why does decoct(fileperms($f)) return 100644 instead of 644?
fileperms() returns the file-type bits along with the permission bits. Mask them off with fileperms($f) & 0777 before converting.
More examples
Reading a real file's permission bits
The raw value prints as something like 100644 because fileperms() includes the file-type bits at the top. Masking with 0777 strips them and leaves just the permission triplet, which is what people mean when they say a file is 644.
<?php
file_put_contents('demo.txt', "hello\n");
$perms = fileperms('demo.txt');
echo "raw: ", decoct($perms), "\n"; // includes file-type bits
echo "masked: ", decoct($perms & 0777), "\n"; // permissions only
printf("pretty: %04o\n", $perms & 0777);
unlink('demo.txt');Octal literals versus octal strings
0755 and 0o755 are the same integer, 493. Writing 755 without the prefix gives a completely different number, and decoct(755) shows that 755 in decimal is 1363 in octal — this is exactly the mistake behind mysteriously wrong file permissions.
<?php
var_dump(0755); // int(493) - octal literal
var_dump(0o755); // int(493) - PHP 8.1+ prefix
var_dump(755); // int(755) - plain decimal
var_dump(decoct(755)); // string(4) "1363"
var_dump(octdec("755")); // int(493)A permission table
Each mode is split into its three octal digits by shifting and masking with 7. This makes it obvious why octal is used for permissions: each digit maps to exactly three bits, so 0755 reads directly as owner 7, group 5, other 5.
<?php
$modes = [0400, 0600, 0644, 0664, 0755, 0777];
foreach ($modes as $m) {
printf("%-6s decimal %-5d owner=%d group=%d other=%d\n",
'0' . decoct($m), $m, ($m >> 6) & 7, ($m >> 3) & 7, $m & 7);
}
Discussion