php magic method 的具體應用和 phpdoc 結合

關於 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

相關文章
相關標籤/搜索