EclipseのPDT/PHPでクラスが警告になったり定義に移動できなくなったり

バージョン2019-12の頃から気になり始め、致命的に困ることでもないので「まぁいいか」としてきていたのですが、2020-06バージョンになって決定的になったので重い腰をあげて調査してみました。

このページの現象は、2020-12 バージョンで解消されています。

【追記】F3キーが効かないのはこちらもご覧ください

現象

PHPエディタで次のような警告が大量に出ます。

ExampleClass を型に解決できません

次のようなエラーもたくさんでています。

The declared namespace "" does not match the expected namespace "example\aaa"
この行で見つかった複数の注釈:
	- The declared class "ExampleClass1" must be named to 
	 "example_class1"
	- 'ExampleClass1' の出現箇所

警告やエラーだけだったら最悪そのままでも開発は進められるのですが、2020-06から困ったことが起こるようになりました。

F3キーが効きません。クラス名や関数名をクリックして右クリックからの「宣言を開く」。ショートカットキー F3 が使えなくなりました。

使えなくなったのは、赤の波線が出ている警告の個所だけです。
警告(赤波線)のないクラス・関数もあります。

解決方法

それでは解決方法です。
先にスクリーンショットを載せます。
こちらはプロジェクトごとの設定です。

  1. 上部メニュー > ウィンドウ > 設定
  2. 左メニュー > PHP > 検証 > エラー/警告
  3. 右側 > プロジェクト固有の設定の構成
  4. 対象のプロジェクトを選択 > OK
  5. 既に選択済みだと思いますが確認として
  6. 左メニュー > PHP > 検証 > エラー/警告
  7. 「プロジェクト固有の設定を可能にする」
  8. 次の項目を「情報」または「無視」に変更
    1. インスタンス化できない型
    2. Duplicate type declaration
    3. Unexpected namespace name
    4. First class in file doesn't match filename
  9. 「適用して閉じる」
  10. 「適用して閉じる」

注意

こちらの設定はプロジェクトごとでなくグローバルでやっても良いかな、と思うところですが、プロジェクトごとに設定することにします。

2020-06バージョンで新たに加わったこれらの警告とエラー。
Eclipseのデフォルトとして入れてくるってことは、将来的にこの形に馴染んでいたほうが得かと思います。

とはいえ、今抱えている案件をこれに従った形にする余裕なんてないと思います。
なので既存のシステムは、「情報」もしくは「無視」で良いと思います。

じゃ、新規案件からはこれに従うのか?っていうと、それもケースバイケースだと思います。
例えば、Wordpress案件でこのやり方に合わせるって難しい以前の問題で無理じゃないかなって思いますし。スグに変えれるものじゃないですね。

原因

なんでこんなことになったのか。

はじめは「おい、PDTさん、もしかして退化した?」なんてことも頭をよぎった今回の事件。

いつもの F3キー が全然効かない。
プロジェクトを削除して、新規でPHPプロジェクトを作っても変わらない。
警告の赤波線と効かないF3キー。

分かってみればなるほど、なんですが、原因にたどり着くのに時間が掛かってしまいました。

こちらの画面なんですが、肝は解決方法で書いた4つの項目です。

そのうちの一番下2つが大きく関係しています。

  • Unexpected namespace name
  • First class in file doesn't match filename

英語になっているだけあって翻訳が追い付いてないんですね。
2020-06 で増えた項目です。

日本語で書くと次のような感じかな

予期しない名前空間

どうやらPHPファイルの配置している場所が、正しい場所にないとダメなようです。

namespace abc; とするなら、そのPHPファイルは 「abc」というフォルダ直下に置かないと警告になります。
namespace abc\def; だったら、「abc\def」に置くことになります。

しかもなんですが、基点を決めていないデフォルト状態だったら、プロジェクト直下に▲でいう「abc」を置かないとダメっぽいです。

ファイルの最初のクラスがファイル名と一致しない

こっちも似た感じなんですが、「クラス名に拡張子を付けたのがファイル名」でなければダメっぽいです。

class SampleClass {} ってするなら、SampleClass.php ですね。

で、「ファイルの最初のクラスが」とありますが、PSRに従ってたら1ファイル1クラスなので、単純に「ファイル名とクラス名は同じ」と考えて良いと思います。

あ、あと、これもPSRから、クラス名はアッパーキャメルケースですね。

いつから発生したか

ってことで古いバージョンを起動して確認してみました。

複数バージョンを同居してるとこんな時にも役立ちます。

2019-19 バージョン

2019-09 バージョン。
このときまでは特に気になることもなく、順調にバージョンアップを行っていました。

2019-12、2020-03バージョン

2019-12 と 2020-03 の項目は同じでした。

2019-12で、一番上に「インスタンス化できない型」「Duplicate type declaration」の項目が増えています。

このあたりから、「ん?警告?」みたいな感じでちょっと気になるようになってきました。
でも、エディタに波線がつくくらいで特別困るようなこともなかったので放置でした。

2020-06バージョン

そして今回、本記事を書いているときの最新版2020-06です。

一番下に2つ「Unexpected namespace name」と「First class in file doesn't match filename」が加わりました。

ということで、つい最近のアップデートで、このあたりの制約をエラーとして扱うか仕様が追加されたようです。

ということで、調査完了です。