错误 - 它们属于逻辑层还是表示层?

时间:2012-09-03 12:46:16

标签: php error-handling separation-of-concerns

关于函数调用,最好让调用者负责检查函数是否有效,或者函数本身是否应该宣布错误?

我问的原因是因为我不喜欢将演示文稿与逻辑混合,但是如果调用者必须进行错误检查,那么它可能是不准确和繁琐的,例如。

if(!login($username, $password)
{
    echo 'Login failed. Please try again.';
}

调用者不知道失败的原因。用户名/密码组合错误,还是数据库连接失败?还是其他一些意外的原因?

如果我们可以在函数内部错误检查/抛出异常,这不会是一个问题,因为那时我们会在特定的代码点遇到特定错误,例如数据库连接失败......但这会混合表示和逻辑。这里的最佳做法是什么?

谢谢。

3 个答案:

答案 0 :(得分:2)

我个人会通过在业务逻辑(模型)层中抛出异常来给调用者一个责任。然后,异常可以在控制器中捕获(并且错误在视图中分配了变量)。有些人甚至喜欢直接在表示层中捕获异常,但这在Web开发的情况下并不适用。只要该异常仅用于视图中的演示目的,我不认为这是一个很大的问题。

因此,我不会像您在简单示例中那样做,因为调用者可能并不总是希望显示错误。通过处理呼叫者的责任,他或她可以选择。另外,我不喜欢在业务逻辑中回显内容(我更喜欢抛出异常并保持模型不干净,但是你的代码很可能只是一个过于简单的例子。

修改:您可以执行以下操作:

型号:

function login($username, $password) {
    if (login failed) {
        throw new Login_Exception();
    }

    else {
        // Set session
        return true;
    }
}

控制器:

try {
    $model->login($username, $password);
}

catch (Login_Exception $e) {
    $view->loginError = 'There was an error logging in.';
}

然后,您可以抛出不同的异常来准确指出出错的地方(例如Wrong_Username_Exception)并相应地处理它。或者你甚至可以在异常的构造函数中提供一个用户友好的原因,但在我看来,这会将表示和逻辑耦合得太多。

答案 1 :(得分:1)

示例代码的问题:

if(!login($username, $password)
{
    echo 'Login failed. Please try again.';
}

...是login()函数没有返回足够的信息供调用者使用。无论调用者是Web表示层还是其他内容,这都是一个问题。

更好的login()函数可能会返回一个Object,以便调用者可以执行:

$response = login($username, $password);
if(! $response->isLoggedIn()) {
    echo "Login failed. " +  $response->getErrorMessage();
}

现在您的登录方法没有与用户界面紧密耦合,但您可以将登录失败的原因传递给用户。

现在,在login()方法中仍然存在“presentation”是有效的,因为它返回的文本是逐字引用给用户的。如果您想要更松散地耦合,您可以定义错误代码列表,并让您的表示层将这些代码转换为消息。或者您可以返回指向消息表的值。阅读国际化;它是相同的基本领域。

答案 2 :(得分:0)

第一个。调用者应该负责错误检查。 如果你想知道什么样的错误,你可以重写登录功能并添加第三个参数来保存对错误的引用,如下所示:

<?php
function login($user, $pass, &$error) {
    // if user or pass wrong
    $error = 'Username / pass wrong';

    // if db failed
    $error = 'unable to connect to db'
};

if(!login($user, $pass, $error)) {
    // do whatever you want with the error
}

更好的是,您可以将常量用于错误类型

<强>更新

如果在调用函数后设置会话或cookie,则不希望显示该函数的错误。它会破坏你的通知,你会收到如下通知:“标题已经发送......”

相关问题