PHP7.4にアップグレードしたらTwigのエラーが大量発生!その原因と対処方法について
弊社では、PHPフレームワーク「CodeIgniter」とテンプレートエンジン「Twig」を活用し、アプリケーション開発を行うことが多々あります。
過去にCodeIgniterとTwigの連携方法を紹介しています。
今回、PHP 7.2で作成したアプリケーションをPHP 7.4に移行した際に多数のエラーが発生しました。
本記事では、その原因調査の結果と対応策を備忘録としてまとめています。
※ Codeigniterの設置とTwigのインストールは上記の「CodeIgniter3にTwigを連携して使う」を参考にしています。
今回衝突した事象
カレンダーを使う社内アプリケーションをPHP7.2からPHP7.4に移行テストを行った際、大量のエラーが出てしまいました。
※ PHP7.2では表示できていたカレンダーアプリケーション(当該コード部分のみ抜粋)
Controller
<?php
class Slot extends CI_Controller
{
public function __construct()
{
$this->load->library(['twig', 'slot_calendar']);
}
public function index()
{
// 省略
// カレンダーデータの作成
$this->view_data['data'] = $this->slot_calendar->get_calendar(date('Y-m'));
// 省略
$this->twig->display('slot.html.twig', $this->view_data);
}
}
Library
<?php
class Slot_calendar
{
public function get_calendar(string $month): array
{
$d = new DateTimeImmutable($month);
return array_chunk(
iterator_to_array(
new DatePeriod(
$d->modify('first day of')->modify('+1 day')->modify('Sunday last week'),
new DateInterval('P1D'),
$d->modify('last day of')->modify('+1 day')->modify('Saturday this week')->modify('+1 day')
)
),
7
);
}
}
問題点の調査
エラー文言を見てみると
Undefined property: DateTimeImmutable::$date
DateTimeImmutableクラスのdateプロパティがないよとなっています。
しかも自前のクラスではなく、Twigのコアクラスのようです…。
/calendar/application/vendor/twig/twig/src/Extension/CoreExtension.php
Line: 1487
エラー文言で調べていると下記のような記述がありました。
For some reason, you're not supposed to be able to access the property but var_dump shows it anyways. If you really want to get the date in that format, use the DateTime::format() function.
echo $mydate->format('Y-m-d H:i:s');
どうも、PHP7.4以降はDateTimeの$dateプロパティを直接読むことは出来なくなっているようです。
TwigのコアではDateTimeの$dateを参照しようとしてエラーになっているみたいです!
※ PHP7.4の変更点を確認したところ、表示もされなくなっているようです。
DateTime や DateTimeImmutable のインスタンスに対して var_dump() 類似の関数を呼び出しても、オブジェクトでアクセス可能なプロパティのみを表示するようになりました。
問題点への対応
Twigのバージョンアップ
最初にTwigライブラリのバージョンアップで解決しようと、各バージョンの要件を確認しました。
PHP7.4の成約があったため、下限バージョンが7.4以下である最新バージョンをインストールしました。
PHP:7.2.5
残念ながらこのバージョンアップでは解決しませんでした…。
要件を無視し、無理矢理最新バージョンをインストールしてみましたがこちらも動作しないので、他のアプローチで攻めてみることにします。
Twigのdate関数を使用せず、CodeIgniter側でフォーマットする
Twigのdate関数でフォーマットしている箇所をController側でフォーマットして渡すように改修します。
Controller
<?php
class Slot extends CI_Controller
{
public function __construct()
{
$this->load->library(['twig', 'slot_calendar']);
}
public function index()
{
// 省略
// カレンダーデータの作成
$calendar = $this->slot_calendar->get_calendar(date('Y-m'));
// コンバータを通す
$this->view_data['data'] = $this->calendar_convert($calendar);
// 省略
$this->twig->display('slot.html.twig', $this->view_data);
}
// カレンダーデータを回してフォーマットしたstringの配列の配列に作り直す
private function calendar_convert(array $calendar): array
{
$convertedCalendar = [];
foreach($calendar as $week) {
$convertedWeek = [];
foreach($week as $day) {
$convertedWeek[] = $this->date_convert($day);
}
$convertedCalendar[] = $convertedWeek;
}
return $convertedCalendar;
}
// フォーマットしたstringの配列にする
private function date_convert(DateTimeImmutable $date): array
{
return [
'year' => $date->format('Y'),
'month' => $date->format('m'),
'day' => $date->format('d'),
'dayNo0' => $date->format('j'),
'week' => $date->format('w'),
];
}
}
diffだと以下のようになります。
- $this->view_data['data'] = $this->slot_calendar->get_calendar(date('Y-m'));
+ $calendar = $this->slot_calendar->get_calendar(date('Y-m'));
// コンバータを通す
+ $this->view_data['data'] = $this->calendar_convert($calendar);
$this->twig->display('slot.html.twig', $this->view_data);
}
+ private function calendar_convert(array $calendar): array
+ {
+ $convertedCalendar = [];
+ foreach($calendar as $week) {
+ $convertedWeek = [];
+ foreach($week as $day) {
+ $convertedWeek[] = $this->date_convert($day);
+ }
+ $convertedCalendar[] = $convertedWeek;
+ }
+ return $convertedCalendar;
+ }
+
+ private function date_convert(DateTimeImmutable $date): array
+ {
+ return [
+ 'year' => $date->format('Y'),
+ 'month' => $date->format('m'),
+ 'day' => $date->format('d'),
+ 'dayNo0' => $date->format('j'),
+ 'week' => $date->format('w'),
+ ];
+ }
なんとか正常に表示されるようになりました!
まとめ
ライブラリはとても便利ではありますが、フレームワークや各ライブラリ間でもミドルウェア等のバージョン要件が異なるので注意が必要と改めて学びました。
この記事が、同じ壁に遭遇した方の参考になれば幸いです。
この記事を書いた人
-
東京で2年半エンジニアとしての経験を積み、浜松にUターンの後、アーティスへ入社。
ソリューション事業部のWebエンジニアとして、システムの設計・開発・保守・運用からインフラまで幅広く従事している。
フルスタックエンジニア目指して現在も勉強の日々。車が好き。
この執筆者の最新記事
最新記事
FOLLOW US
最新の情報をお届けします
- facebookでフォロー
- Twitterでフォロー
- Feedlyでフォロー