#事象
以下のようにメソッドを呼び出したときに発生します。
class Item extends Model
{
public function getItems()
{
// 取得処理
class ItemController extends Controller
{
public function index(Request $request)
{
$items = Item::getItems();
// Error
> Non-static method App\Models\Item::getItems() should not be called statically
#原因
エラーメッセージを訳すと***「非静的メソッドApp\Models\Item::getItems()
は静的に呼び出されるべきではありません」***になります。
原因はそのままでgetItems
は非静的メソッドなので、静的な呼び出しを行なってはならない、ということになります。
###「静的」とは?
クラスのメソッドを静的として宣言すると、クラスのインスタンス化を必要とせずにそれらにアクセスできるようになります。
###「静的な呼び出し」とは?
クラス名::メソッド名()
のような書き方です。
静的呼び出しではItemクラスのインスタンスを作成せずにgetItems
メソッドを呼び出しています。
上記の例ではgetItems
は静的なメソッドとして定義されていないので、呼び出すにはインスタンスを生成する必要があります。それを静的呼び出し(インスタンスを生成せず呼び出す方法)で呼び出そうとしているので警告されているわけですね。
#解決方法
###1.インスタンスを生成し、インスタンスメソッドとして呼び出す
getItems
は非静的メソッドなので静的な呼び出しを行ってはならない、ということだったのでインスタンスを作成して、インスタンスメソッドとして呼び出すようにします。
class ItemController extends Controller
{
public function index(Request $request)
{
$i = new Item(); // Itemクラスのインスタンスを生成
$items = $i->getItems(); //生成したItemインスタンスのgetItemsメソッドを呼び出す
###2.静的メソッドに変更する
getItems
は非静的メソッドなので静的な呼び出しを行ってはならない、ということだったのでgetItems
を静的メソッドに変更してあげます。
class Item extends Model
{
public static function getItems() // メソッド名にstaticキーワードを付けると静的メソッドになる
{
#どちらを使えばいいのか?
###インスタンスメソッド
- インスタンスごとに異なる動作を期待する場合
###静的メソッド
- いろんな場所で繰り返し同じ処理を呼びたい場合
- 呼び出す場所によって期待する動作が異ならない(常に同じものを返してほしい)場合
#参考
Why I'm getting 'Non-static method should not be called statically' when invoking a method in a Eloquent model?
PHPでなくC#ですが、静的メンバ―の説明がわかりやすかったので。