事象
PHP経由で複数階層にわたるディレクトリを作りたくて以下のようなコマンドを実行する
mkdir('./hoge/huga', 777, true);
しかしこれはエラーになり
以下のように1階層目のディレクトリだけができて終わってしまう。
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 1777 dir
従来の権限設定に加えて、4ケタ目に1を指定することで
スティッキービットが設定される
PHPの権限変更の設定
PHPの chmod
や mkdir
の権限設定の引数はint型だが
0777
とか 0755
など、必ず0を指定するように書かれている。
理由としては chmod
のリファレンスページに書かれている
自動的には 8 進数と見なされないので注意してください。 意図した操作を行うには、mode の前にゼロ(0)を付ける必要があります
PHP: chmod - Manual
そのため、従来のシェルスクリプトの $ chmod 777
を実現したいような場合は 0777
を指定しないと実現しない。
そのため 777
を指定すると、10進数を指定されたことが想定される、そのため8進数に置き換えた 1411
を指定したことになる。
結果、 1411
の権限を指定したことになるので
スティッキービットが適用された 411
が適応されて
ディレクトリが作られることになる。
余談:mkdirの権限
PHP の mkdir
は umask
の制限を受ける。
モードを八進数で指定したくなることもあるかもしれません。 その場合は先頭にゼロをつける必要があります。 また、モードは、現在設定されている umask の影響も受けます。 umask を変更するには umask() を使用します。
PHP: mkdir - Manual
umaskとmkdirの関係に関して以下のページがまとまっているので参照のこと。
【PHP】mkdirのパーミッション(属性)の指定が機能しない原因 – ysklog
大概は umask は 0022
が指定されているため
今回は影響なかったが、 1777
等を指定していたら
1755
とかになっていたハズ。
参考
参考URL
- 今さら聞きづらい「ファイルパーミッション」について (フェンリル | デベロッパーズブログ)
- chmod :SUID、GUID、スティッキービットまとめ - Qiita
- データ型
- ファイルの属性情報を探る 権限編 - ザリガニが見ていた...。
検証環境
Ubuntu
PHP 7.0.8