關於 Magic Methods 的介紹自行查閱官方文檔,這裏再也不贅述。
http://php.net/manual/en/lang...php
使用 phpstorm 的同窗注意了,若是在咱們的代碼中使用到了 php 中相關的魔術方法,須要在 php 文件中指明告訴 phpstorm 應該如何來跟蹤變量屬性。下面咱們來具體實踐分析。session
假設如今我有一個 php 的基類名爲 BaseController.phpphpstorm
<?php namespace Conduit\Controllers; use Psr\Container\ContainerInterface; /** * Class BaseController * @package Conduit\Controllers */ class BaseController { /** @var \Interop\Container\ContainerInterface */ protected $container; /** @var \Conduit\Services\Auth\Auth */ private $auth; /** @var \Conduit\Validation\Validator */ private $validator; /** @var \League\Fractal\Manager */ private $fractal; /** * BaseController constructor. * @param ContainerInterface $container */ public function __construct (ContainerInterface $container) { $this->container = $container; } /** * @param $name * @return mixed */ public function __isset ($name) { return $this->container->{$name}; } /** * @param $name * @param $value * @return mixed */ public function __set ($name, $value) { return $this->container->{$name} = $value; } /** * @param $name * @return mixed */ public function __get ($name) { return $this->container->{$name}; } }
同時還有一個 CompanyController.php 的類文件繼承的該 BaseController.phpoop
<?php namespace Conduit\Controllers\Company; class CompanyController extends BaseController { public function getSpecialSubs (Request $request, Response $response) { $couser = $this->auth->requestUser($request); } }
這裏咱們主要要關注的點就是 $this->auth 這個,由於這個纔是咱們今天要將的重點。這裏再說一點,列舉的代碼是基於 slim framework 中的一部分,有不瞭解 slim framework 的能夠先了解下。固然不瞭解也不影響咱們今天要說的這一點。下面是正題。ui
這裏我想實現的效果就是當我在 CompanyController.php 的方法中要訪問這個容器(container)中的 auth,能夠直接使用 $this->auth,而後就能夠操做auth中的方法和屬性等。
那上面我列舉的方式是使用 php 語言的 magic methods 這個特性,那有同窗就要說了,我直接指定豈不是也能夠,答案是確定的。this
<?php namespace Conduit\Controllers; use Interop\Container\ContainerInterface; class BaseController { /** @var \Interop\Container\ContainerInterface */ protected $container; /** @var \Conduit\Services\Auth\Auth */ protected $auth; /** @var \Conduit\Validation\Validator */ protected $validator; /** @var \Illuminate\Database\Capsule\Manager */ protected $db; /** @var \League\Fractal\Manager */ protected $fractal; /** @var \SlimSession\Helper */ protected $session; /** * BaseController constructor. * * @param \Interop\Container\ContainerInterface $container */ public function __construct(ContainerInterface $container) { $this->container = $container; $this->auth = $this->container->get('auth'); $this->validator = $this->container->get('validator'); $this->fractal = $this->container->get('fractal'); $this->session = $this->container->get('session'); $this->db = $this->container->get('db'); }
效果就是這個樣子。
確實這個樣子能夠實現,但沒有利用到 magic method 這一魔術方法的特性。spa
這裏着重說明的是這個咱們定義的這些個類內部屬性(這些成員屬性必須經過phpdoc 的 @var 來指明你將要調用的成員屬性是哪個否則 phpstorm 不會識別提示)和 __get() 方法,當咱們要訪問不可訪問的屬性時會調用該方法。
那因此說 $auth | $validator | $db | fractal 等屬性咱們要在外部自動調用 __get() 方法來訪問的話就必須將其訪問修飾符設置爲 private (php 中的三種修飾符 public protected private),這樣咱們在外部調用才能自動執行到 __get() 方法,達到一樣的目的來調用 $this->auth 等.net