LoginSignup
22
21

More than 5 years have passed since last update.

PHPのディレクトリ権限変更系を3ケタの数字で設定すると陥る罠と理由

Last updated at Posted at 2016-10-25

事象

PHP経由で複数階層にわたるディレクトリを作りたくて以下のようなコマンドを実行する

php
mkdir('./hoge/huga', 777, true);

しかしこれはエラーになり
以下のように1階層目のディレクトリだけができて終わってしまう。

lsの結果
drwxrwxrwx 3 user group 4096 Oct 10 09:19 .
drwxr-xr-x 7 user group 4096 Oct 10 04:00 ..
dr----x--t 2 user group 4096 Oct 15 08:00 hoge

解決法

(解決法って話でもないんですが)
ディレクトリ権限を指定する場合は4ケタの数字を指定する。

mkdir('./hoge/huga', 0777, true);

解説

777 ではなく 0777 ではないと
権限が 411 になってしまい
しかもユーザー権限が x ではなく t というものができるのか
順を追って説明します。

ディレクトリ権限の t とは

まず t とは何を表現するのか
これはスティッキービットと呼ばれるものだ。

スティッキービット(Sticky Bit)とは、ディレクトリに設定される特殊なアクセス権の事です。
スティッキービット(Sticky Bit)が設定されたディレクトリでは、すべてのユーザーがファイル・ディレクトリを書き込めますが、所有者だけ(rootは除く)しか削除できなくなります。
スティッキービット(Sticky Bit) - 特殊なアクセス権

上記のような特殊なアクセス権のことを指す。
そしてこのスティッキービットを設定する場合は
以下のように chmod を実行する

chmodする場合のコマンド
$ chmod 1777 dir

従来の権限設定に加えて、4ケタ目に1を指定することで
スティッキービットが設定される

PHPの権限変更の設定

PHPの chmodmkdir の権限設定の引数はint型だが
0777 とか 0755 など、必ず0を指定するように書かれている。

理由としては chmod のリファレンスページに書かれている

自動的には 8 進数と見なされないので注意してください。 意図した操作を行うには、mode の前にゼロ(0)を付ける必要があります
PHP: chmod - Manual

そのため、従来のシェルスクリプトの $ chmod 777 を実現したいような場合は 0777 を指定しないと実現しない。

そのため 777 を指定すると、10進数を指定されたことが想定される、そのため8進数に置き換えた 1411 を指定したことになる。

結果、 1411 の権限を指定したことになるので
スティッキービットが適用された 411 が適応されて
ディレクトリが作られることになる。

余談:mkdirの権限

PHP の mkdirumask の制限を受ける。

モードを八進数で指定したくなることもあるかもしれません。 その場合は先頭にゼロをつける必要があります。 また、モードは、現在設定されている umask の影響も受けます。 umask を変更するには umask() を使用します。
PHP: mkdir - Manual

umaskとmkdirの関係に関して以下のページがまとまっているので参照のこと。
【PHP】mkdirのパーミッション(属性)の指定が機能しない原因 – ysklog

大概は umask は 0022 が指定されているため
今回は影響なかったが、 1777 等を指定していたら
1755 とかになっていたハズ。

参考

参考URL

検証環境

Ubuntu
PHP 7.0.8

22
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
21