对如何改善这个功能感到困惑..?

时间:2014-07-16 17:38:53

标签: php laravel laravel-4

我的控制器中有以下功能来处理准备和加载我的主页。

public function index()
    {
        // GetBalance
        $current_balance = $this->PayPal->getBalance();

        if(Session::has('errors'))
        {
            return Redirect::to('error');
        }

        // TransactionSearch
        $params = array(
            'number_of_days' => 1
        );
        $recent_history = $this->PayPal->transactionSearch($params);

        if(Session::has('errors'))
        {
            return Redirect::to('error');
        }

        // Make View
        $data = array('current_balance' => $current_balance, 'recent_history' => $recent_history);
        return View::make('index')->with('data', $data);
    }

正如您所看到的,我正在通过我的模型对PayPal API进行两次不同的调用,并且在每次调用之后我都在检查错误。发生错误时,我会刷新错误消息并相应地重定向到错误页面。

我想改进一下,所以当我在加载视图之前进行一堆调用时,我不必一遍又一遍地使用相同的代码片段。

if(Session::has('errors'))
        {
            return Redirect::to('error');
        }

我试着把它移到自己的功能......

public function errorCheck()
    {
        if(Session::has('errors'))
        {
            return Redirect::to('error');
        }
    }

然后,我想我可以在索引函数中执行此操作...

// GetBalance
        $current_balance = $this->PayPal->getBalance();
        $this->errorCheck();

但这不起作用,我想因为errorCheck()只是返回一个值而不是实际触发重定向,所以我最终在我的主页上出现错误,因为它没有预期存在的数据(因为API调用失败了。)

有关我需要做什么的任何信息,以便我的errorCheck()函数只是在应该非常感激时触发重定向。

谢谢!

3 个答案:

答案 0 :(得分:1)

我能想到避免这种情况的唯一方法是使用例外。

使用errorCheck()方法,您可以尝试:

// GetBalance
$current_balance = $this->PayPal->getBalance();
return $this->errorCheck();

但这不是你想要的......它会在第一次通话后退出你的方法。你真正需要的是一种在任何地方捕获错误并处理它的方法 - 以及那些例外情况。

我将假设您的PayPal课程是第三方课程,您无法重写它以引发异常。鉴于这种假设,你可以做的是:

重写您的errorCheck()方法,如下所示:

public function errorCheck()
{
    if(Session::has('errors'))
    {
        throw new Exception("Problem with Paypal!");
    }
}

然后将所有Paypal访问代码包装在try / catch块中:

public function index()
{
    try {
        // GetBalance
        $current_balance = $this->PayPal->getBalance();

        $this->errorCheck();

        // TransactionSearch
        $params = array(
            'number_of_days' => 1
        );
        $recent_history = $this->PayPal->transactionSearch($params);

        $this->errorCheck();

        // Make View
        $data = array('current_balance' => $current_balance, 'recent_history' => $recent_history);
        return View::make('index')->with('data', $data);
    } catch(Exception $e) {
        return Redirect::to('error');
    }
}

每次调用errorCheck()时,都会检查错误并抛出异常。在这种情况下,执行将立即跳转到catch块并重定向到错误页面。

更好的解决方案是将异常更接近错误的来源,即。发生错误时Paypal类中的某个位置。这里的想法是异常包含许多有用的信息,告诉你发生了什么,比如堆栈跟踪。在我给出的代码中,堆栈跟踪将显示在errorCheck()方法中抛出了异常,虽然这是真的,但实际上并没有用。如果可以在Paypal类的某个地方抛出异常,它会更好地指示出现了什么问题。

答案 1 :(得分:1)

虽然抛出错误肯定是要走的路,但我还是说你更进一步,推广重定向。而不是每次调用PayPal API时尝试捕获阻止,您可以使用App::error全局重定向。

在适当的地方创建一个异常类:

class PayPalApiException extends Exception {}

然后在start/global.php添加此内容(在另一个App::error之前):

App::error(function(PayPalApiException $exception)
{
    return Redirect::to('error');
});

然后,您在控制器中的代码可以变得更加简单:

public function index()
{
    $current_balance = $this->PayPal->getBalance();

    $this->errorCheck();

    $recent_history = $this->PayPal->transactionSearch([
        'number_of_days' => 1
    ]);

    $this->errorCheck();

    $data = compact('current_balance', 'recent_history');

    return View::make('index')->with('data', $data);
}

protected function errorCheck()
{
    if (Session::has('errors'))
    {
        throw new PayPalApiException("Problem with Paypal!");
    }
}

答案 2 :(得分:0)

为什么你甚至需要检查两次错误?它似乎与每次通话无关?即如果余额调用失败似乎无关紧要,因为你不在事务搜索中使用结果。

我只是这样做

public function index()
{
        // GetBalance
        $current_balance = $this->PayPal->getBalance();

        // TransactionSearch
        $recent_history = $this->PayPal->transactionSearch(array('number_of_days' => 1));

        if(Session::has('errors'))
        {
            return Redirect::to('error');
        }
        else
        {
            return View::make('index')->with('current_balance', $current_balance)
                                      ->with('recent_history', $recent_history);
        }
}