Проверьте, не является ли свойство класса нулевым, перед вызовом любого открытого метода класса - PullRequest
0 голосов
/ 02 октября 2018

Что у меня есть : Game класс (как часть Laravel 5.5 framework)

class Game implements GameInterface
{
    private $currentGame;

    public function __construct()
    {
        $this->currentGame = Game::where('status', true)->first();
    }

    public function getPlayersAmount()
    {
        if ($this->currentGame)
            //fetch data & return it
        else
            return 0;
    }

    public function getPlayers()
    {
        if ($this->currentGame)
            //fetch data & return it
        else
            return null;
    }

    public function getAllStats()
    {
        if ($this->currentGame)
            //fetch data & return it
        else
            return null;
    }

    public function getTopScore()
    {
        if ($this->currentGame)
            //fetch data & return it
        else
            return 0;
    }
}

Моя проблема - if ($this->currentGame).Я должен разместить его внутри каждого метода, чтобы избежать исключений, связанных с Eloquent.

Как я могу выполнить эту проверку if ($this->currentGame) перед каждым вызовом метода, чтобы избежать дублирования кода?

__call() не делает 't работают для открытых методов.

Мое текущее использование класса:

$game = new Game();
$game->getPlayers();
//and so on

Ответы [ 3 ]

0 голосов
/ 03 октября 2018

Вы можете использовать __call с этим, вам просто нужно сделать ваши публичные функции частными, а затем добавить в них префикс с чем-то уникальным, чтобы убедиться, что они являются единственными частными функциями, которые можно публично вызывать.

Вот пример.

class Game implements GameInterface
{
    private $currentGame;

    public function __construct()
    {
        $this->currentGame = Game::where('status', true)->first();
    }

    public function __call($method, $args)
    {
        if ($this->currentGame) 
            return call_user_func_array(array($this, 'public'.ucfirst($method)), $args);
        else 
            return 0;
    }

    private function publicGetPlayersAmount()
    {
        //fetch data & return it
    }

    private function publicGetPlayers()
    {
        //fetch data & return it
    }

    private function publicGetAllStats()
    {
        //fetch data & return it
    }

    private function publicGetTopScore()
    {
        //fetch data & return it
    }
}
0 голосов
/ 03 октября 2018

Ваш подход не имеет большого смысла, на мой взгляд.

Если ваш Game экземпляр будет зависеть от наличия currentGame, то не будет возможности создать экземпляр, если currentGame is falsey.

Просто поместите проверку в конструктор и сгенерируйте исключение, если не может быть создан экземпляр.

public function __construct()
  {
    $this->currentGame = Game::where('status', true)->first();

    if (! $this->currentGame) {
        throw new \Exception('Current game not available');
        // probably better if you define your own exception class
    }
  }

Затем вы просто проверяете, работает ли это при создании экземпляра, и если этопродолжает нормально:

try { 
    $game = new Game();
    $game->getPlayers();
}
catch (\Exception $e) {
    // $game is not safe to use, do something about it.
}
0 голосов
/ 03 октября 2018

Я думаю, что это может быть достигнуто с __call и call_user_func_array

class Game implements GameInterface
{
    private $currentGame;

    public function __construct()
    {
        $this->currentGame = Game::where('status', true)->first();
    }

    public function __call($name, $arguments) {
        $name = '_'.$name;
        if ($this->currentGame && method_exists($this,$name)) return call_user_func_array(array($this, $name), $arguments);
        return null;
    }

    private function _getPlayersAmount()
    {
        return "sthg";
    }

    private function _getPlayers()
    {
        return "sthg else";
    }

    private function _getAllStats()
    {
        return "also sthg else";
    }

    private function _getTopScore()
    {
        return "different one";
    }
}

, просто мы реализуем наши функции как частные с немного другим именем и позволяем им вызываться через __call через call_user_func_array.Мы могли бы также использовать switch-case, однако таким образом он более динамичен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...