PHP : touch()関数の戻り値について

こんにちは、さるまりんです。

とてもシンプルな話。PHPのtouch()関数についてです。

公式のドキュメントはこちら

touch()関数はドキュメントにあるようにファイルの最終アクセス時刻および最終更新日をセットします。UnixやLinuxのコマンドのtouchコマンドと同じですね。

そのマニュアルにもこう説明されています。

touch — change file access and modification times

(BSD General Commands Manualより)

その戻り値について知りたかったのでちょっとだけ実験してみました。

戻り値については以下のようにあります。

成功した場合に true を、失敗した場合に false を返します。

(PHPのドキュメントより)

file_exists()でファイルの存在をチェックし、その後touch()を試みるプログラムで実験してみました。

以下がそのプログラムです。

touch.php

<?php
$file = "a.txt";
echo "file $file exists? " . (file_exists($file) ? "true" : "false") . "\n";
$result = touch($file);
echo "result of touch is " . ($result ? "true" : "false") . "\n";

実行環境はOSがmacOS Big Sur、PHP versionは7.3.24です。

php -v
WARNING: PHP is not recommended
PHP is included in macOS for compatibility with legacy software.
Future versions of macOS will not include PHP.
PHP 7.3.24-(to be removed in future macOS) (cli) (built: Nov 23 2020 06:45:16) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.24, Copyright (c) 1998-2018 Zend Technologies

(おや?PHPがmacOSから無くなる・・・)

1回目の実行です。

file a.txt exists? false
result of touch is true

ファイルa.txtは存在せず、そのファイルのtouchに成功です。

これでファイルa.txtが作成されています。

2回目の実行です。

file a.txt exists? true
result of touch is true

ファイルが存在し、touchにも成功です。

次はファイルを読み込み専用にして試してみます。

まずはchmodで読み込み権限のみにします。

chmod 444 a.txt
ls -l a.txt
-r--r--r--  1 salumarine  staff  0  1 10 17:22 a.txt

で、3回目の実行です。

file a.txt exists? true
result of touch is true

こちらも成功しましたね。

次はchownで所有者を変更してみます。

chown root a.txt
ls -l a.txt          
-r--r--r--  1 root  staff  0  1 10 17:48 a.txt

で、4回目の実行です。

file a.txt exists? true
Warning: touch(): Utime failed: Permission denied in /Users/salumarine/........./touch.php on line 4
result of touch is false

今度はファイルの存在チェックの後、touch()が失敗していますね。警告も表示されています。Utime failedとあるので、最終アクセス時刻および最終更新日の設定に失敗したのが原因の警告です。所有者が違うのでファイルの操作に失敗しているのですね。

地味な実験ですが分かったことが一つ。3回目の読み込み権限のみにしてもtouch()は成功するようです。少なくともこの実験した環境においてはですが。

試してみないと分からないことがありますね。Linuxではどうなるんだろう。条件分岐に使っているのであれば実験、試験はとても重要ですね。

読んでくださってありがとうございます。

それではまた!