PHP异常和用户消息

时间:2011-10-15 15:57:43

标签: php exception

我有一个项目对象。 用户可以为其分配工作对象。

99%的情况下,项目对象都设置了所有正确的字段。 在某些情况下,该项目缺少一个字段。

为了将工作人员分配给项目,项目必须设置所有必需的字段。

要解决这个问题,我会抛出这样的异常:(不要试图在这里找到一个模式,真正的例子更复杂)


if ($project->startDate == false ) {
  throw new Exception("Missing startDate attribute for project id: $id");
}


if ($project->finishDate == false ) {
  throw new Exception("Missing finishDate attribute for project id: $id");
}

if ($project->startDate > $project->finishDate ) {
  throw new Exception("Invalid start date for project id: $id");
}

这个问题是我每次都需要向用户显示一条自定义消息。例如,如果抛出第一个错误,用户应该看到:'请设置项目开始日期',依此类推。

我该怎么做?

3 个答案:

答案 0 :(得分:5)

只需在try .. catch中定义您自己的异常类和整个代码:

class FormException extends Exception {
   private var $userMessage;
   public function __construct($message, $userMessage) {
     parent::__construct($message);
     $this->userMessage = $userMessage;
   }
   public function getUserMessage() {return $this->userMessage;}
}

try {
  // Whole code goes here, probably a function call
  throw new FormException("Missing startDate attribute for project id: $id",
                          'Please setup the project start date');
} catch (FormException $e) {
  echo $e->getUserMessage();
  error_log($e->getMessage());
}

顺便说一下,如果要在字符串中包含变量内容,可以使用双引号("id: $id")或连接('id: ' . $id)。

答案 1 :(得分:1)

试试这个:

try
{
  $Message = '';
  if ($project->startDate == false ) {
    $Message = "Please setup the project start date\n";
    throw new Exception("Missing startDate attribute for project id: $id");
   }


   if ($project->finishDate == false ) {
     $Message = "Please setup the project finish date\n";
     throw new Exception("Missing finishDate attribute for project id: $id");
   }

   if ($project->approved == false ) {
     $Message = "Please setup the project approved field\n";
     throw new Exception("Missing approved attribute for project id: $id");
   }
}
catch(Exception $Ex)
{
   // Log in some way you like the $Ex-getMessage();
   echo nl2br($Message);
}

答案 2 :(得分:0)

在项目类中,创建一个新方法,可能称为getErrorMessage

该函数应该进行检查(不需要在项目之外具有具体的验证方法或为项目创建验证对象)。然后:

if ($message = $project->getErrorMessage())
{
    throw new Exception(sprintf('%s (project id: %d)', $message, $id));
}

如果您决定不因设计原因而抛出异常,这仍然有用。

使用验证器对象可以获得更大的灵活性,自然可以提供比单个方法更详细的信息。所以这可能是更好的事情:

class ProjectValidator
{
    private $project;
    private $errors;
    public function __construct($project)
    {
        $this->project = $project;
    }
    public function isValid()
    {
        // run your checks, add errors to the array as appropriate.

        $errors = array();

        if (!$this->project->startDate)
        {
            $errors[] = 'Missing startDate attribute';
        }

        if (!$this->project->finishDate)
        {
           $errors[] = 'Missing finishDate attribute';
        }

        if (!$this->project->approved)
        {
            $errors[] = 'Missing approved attribute';
        }

        $this->errors = $errors;

        return (bool) count($this->errors);
    }
    public function getErrors()
    {
        return $this->errors;
    }
}

$validator = new ProjectValidator($project);
if (!$validator->isValid())
{
    // throw an exception or do whatever you want in case it's not valid

    $errors = $validator->getMessages();
    $message = sprintf("Project id: %d has the following %d error(s):\n", $id, count($errors));        
    foreach($errors as $index => $error)
    {
        $message .= sprintf("%d. %s\n", $index+1, $error);
    }

    throw new Exception($message);
}