こんにちは。新卒2年目エンジニアの遠藤です。
今回は、PHP/Laravelで子クラスで設定した値を親クラスで使おうとした時につまずいたので解決方法とともに紹介させていただきます。
実際に発生したうまく引き継げなかった例
以下のように、親クラスに$nameという変数を用意し、子クラスで「$this->name = ‘遠藤’」として値を代入したのですが、その後、親クラスで「$this->name」を出力しようとするとnullとなってしいました。子クラスで代入した「$this->name = ‘遠藤’」は子クラス内でのみの使用に限られるようです。これは子クラスの「$this」が子クラスのオブジェクトを指しており、親クラスの「$this」が前者とは別の親クラスのオブジェクトを指しているためです。
親クラスで値を定義
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?php namespace App\Http\Controllers; class Controller extends BaseController { protected $name; protected function outputName() { echo $this->name; } } |
子クラスで値を代入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php namespace App\Http\Controllers; class childController extends Controller { protected function name() { $this->name = '遠藤'; $this->outputName(); // nullが出力された。 } } |
staticを使用したらうまく引き継げた
static変数を使用したところうまく引き継ぐことができました。static変数はオブジェクト毎に生成されるのではなく、全体で引き継がれます。そのため、子クラスで「親クラス::name」の形で値を代入すると親クラスで$nameにアクセスした場合も代入された値を取得できます。
親クラスで値をstaticで定義
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?php namespace App\Http\Controllers; class Controller extends BaseController { protected static $name; protected function outputName() { echo $self::name; } } |
子クラスで値を代入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php namespace App\Http\Controllers; class childController extends Controller { protected function name() { Controller::name = '遠藤'; $this->outputName(); // 遠藤が出力された。 } } |
PHPで用意されている$GLOBALSの使用
PHPで用意されている$GLOBALSを使用することによってもデータを引き継ぐことができたが、コードが読みにくくなりそうでした。そのため、この方法は使用せずstaticで定義しました。
static変数を使用する場合はその変数が親クラスがインポートされているファイルで使われていることが想定できますが、$GLOBALSに入れるとどこからでも使用できてしまうため、ソースコードを読む際にどこを見ればいいかの当たりがつきにくくなってしまいます。
親クラスで値をstaticで定義
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?php namespace App\Http\Controllers; class Controller extends BaseController { protected function outputName() { echo $GLOBALS['name']; } } |
子クラスで値を代入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php namespace App\Http\Controllers; class childController extends Controller { protected function name() { $GLOBALS['name'] = '遠藤'; $this->outputName(); // 遠藤が出力された。 } } |