Help us understand the problem. What is going on with this article?

DateTime::formatメソッドに指定するフォーマットを無意味に長くすると,不具合を引き起こしやすい.

TL;DR

  • index.htmlという文字列をフォーマットとして \DateTime::format() メソッドに引き渡したところ,i801Asia/Tokyox.013108Saturday という出力が生成された.
  • format() メソッドに指定するフォーマットは,必要最低限とする.変換されない文字列と誤認して、n, eなどを指定してしまうと面倒なことになる.
  • 自分の想定通りに動くか,細かい単位で動作確認・テストを行う.

環境

  • PHP7.2
  • Ubuntu18.04 LTS

経緯

今日の日付情報を保持した \DateTime クラスからディレクトリパス(文字列)を format() メソッドを用いて生成し,それをキーとして指定してS3にファイルをアップロードするという処理にて,予期せぬ挙動が発生しました.
DateTime
具体的には,

  • 2020/08/index.html

というパスにファイルを自動でアップロードしたかったものが

  • 2020/08/i801Asia/Tokyox.013108Saturday

というパスにファイルがアップロードされてしまい,自動生成されるはずの目的のページが生成されないという意図せぬ挙動となりました.

CLIで実行して確認

\DateTime 型のインスタンスを取得し, format() 関数にフォーマットを引き渡して呼び出してやれば,渡したフォーマットに応じた文字列が返ります.

php > $date = new \DateTime();
php > echo $date->format('Y')
php > ;
2020
php > echo $date->format('m');
08

今回の問題箇所についても実行してみます.

php > echo $date->format('Y/m/index.html');
2020/08/33801Asia/Tokyox.013108Saturday

ああ...

下記のように変更を行い,正常に動作するようになりました.

php > echo $date->format('Y/m/').'index.html';
2020/08/index.html

教訓

  • format() メソッドに指定するフォーマットは,必要最低限とする.変換されない文字列だからといってむやみに詰め込まない.
  • 自分の想定通りに動くか,細かい単位でチェックを行う.
  • var_dump() さんありがとう.
x-trans
AWS、GCP、Azureの導入設計、環境構築、運用・保守までサポートするエンジニア軍団
https://x-trans.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away