在函数中返回真/假并附带一条消息以进一步解释返回假的原因


Returning true/false in functions with a message to further explain the reason why it returned false

我正在创建函数,我希望能够输出与函数内的if语句相关的true或false。一个这样的例子:

function pokeme($number){
    if($number > 10)
    {
        return true;
    }
    else
    {
        return false;
    }
}

然而,这种方法的一个问题是,如果函数返回false,您无法破译哪个false表示什么,特别是如果有多个if/else语句。

我的问题是,我如何输出false以及稍后识别该false是什么的方法?

我要做一个数组吗?

return array("false", "message pertaining to whatever");

然而,如果这样做了,你就不能真正这样做了,加上…:

if(pokeme()){ /*success*/ } else { /*there may be multiple falses for different situations... how do I distinguish what it is? */}

请注意,这里演示的方法可能不是最好的,但是一旦您掌握了其中的窍门,就会变得更容易。另外,请阅读结束语

如果你想这样使用(true是期望的,false是问题):

if(pokeme()){ /*success*/ } else { /* not needed */}

你可以这样做:

function pokeme($number){
    //let's say you want to return true if it's >10 and -9 to -1
    if($number > 10){
        // do something
        return true;
    }
    if($number < 0 && $number > -10){
        return true;
    }
    // handling multiple problems (just 2 ^^)
    if($number < -9){
        throw new Exception("Invalid input. Can't use negative smaller than -9.");
    }
    throw new Exception('Invalid input. Expected bigger than 10.');
}
两个测试:

try{
    echo "RESULT1 :".pokeme(-42).":"; // not shown (error in this line)
    echo "RESULT2 :".pokeme(11).":"; // not shown
}catch(Exception $e){
    echo "Error: '".$e->getMessage()."'"; // Just the message
}
echo "<br><br>";
try{
    echo "RESULT3 :".pokeme(11).":<br>"; // shown
    echo "RESULT4 :".pokeme(10).":"; // not shown (error in this line)
}catch(Exception $e){
    echo $e; // Full error
}

你可以这样使用:

try{
    if(pokeme(11)){
        echo "VALID INPUT<br>";
    }
    if(pokeme(5)){
        echo "I'm not seen :''";
    }
}catch(Exception $e){
    echo "Error: '".$e->getMessage()."'";
}

结束提示:想象一下你正在使用一个可能导致错误的内置php函数。这样你就必须用try..catch来处理它。

关于异常的更多信息。

对于完全自动化的输入验证,您可以使用Symfony表单组件及其Validation。你也可以添加非常简单的约束LessThan(10)完全像你的例子,组件自动写适当的错误信息回你的页面(和无效的形式,例如不执行DB插入)。它有很多准备好的约束可以使用,你也可以创建自己的约束。

或者如果你想自己写,我建议你先阅读OOP和异常处理。

编辑

如果你想"收集"您可以将此消息存储在超全局变量$_SESSION的临时数组中。我明确地说超全局变量。不要使用全局变量并注入global键,这将在长期内变得非常复杂的代码。

无论如何我的想法使用$_SESSION。下面的代码为我工作:

<?php
session_start();
// Resetting the tmp session array on every page reload. That previous error messages are resetted.
$_SESSION['errors'] = array();
function printSessionErrors()
{
    // Print errors stored in the session if some exists
    if (array_key_exists('errors', $_SESSION)) {
        foreach ($_SESSION['errors'] as $i => $error) {
            $success = true === $error['success'] ? 'true' : 'false'; // Only for print
            $message = $error['message'];
            echo "Success: $success. Message: $message <br>";
        }
    }
}
function pokeme($number)
{
    $expected = 10;
    $success = null;
    if ($number > $expected) {
        $success = true;
    } else {
        $_SESSION['errors'][] = array(
            'success' => $success,
            'message' => "Number $number is less than $expected"
        );
        $success = false;
    }
    return $success;
}
pokeme(1);
pokeme(7);
pokeme(99);
printSessionErrors();

现在取决于它是一个表单POST或过程验证你添加printCleanSessionErrors()在顶部(session_start()之后)或底部的代码。

我得到这样的输出:

Success: false. Message: Number 1 is less than 10 
Success: false. Message: Number 7 is less than 10 

您只需要将$_SESSION['errors'][] = array ....添加到您的其他错误情况

这是其中一个问题,由于措辞不当,导致完全错误的答案

在提出这样的问题之前,我们必须认识到有两种类型的函数:

  • 执行某些操作的函数
  • 函数不做任何事情,只是验证参数,告诉是否正确

如果pokeme()函数必须以某种方式使用$number参数,但由于某种原因不能这样做,则必须抛出异常。因为这正是异常的目的:处理异常行为。在这种情况下,该函数永远不会返回false,因此返回true也没有意义。因此,它要么是正确的结果,要么将抛出异常。但重要的是要明白,作为一项规则,不应该当场发现例外情况。至少必须使用异常来传递来自函数的某些消息。

只有当一个函数不能完成它的工作时,才应该使用异常:

function divide_by($number, $divisor)
{
    if (!is_numeric($number) || !is_numeric($divisor)) {
        throw new InvalidArgumentException("The arguments must be nubmers");
    }
    if ($divisor === 0) {
        throw new InvalidArgumentException("Cannot divide by zero");
    }
    return $number / $divisor;
}

如果pokeme()函数,如所提供的示例所示,必须以某种方式测试 $number,并判断它是否正常,则不需要使用异常。因为错误的值不是例外情况。

在这里,传达消息的最简单方法是反转函数的"极性"。让它在参数正确的情况下返回false,在参数错误的情况下返回真值。这将允许我们返回我们所需要的信息。

function check_number($number)
{
    if(!is_int($number))
    {
        return "The value provided is not numeric";
    }
    if($number < 10)
    {
        return "The number is less than 10";
    }
    return false;
}

然后可以这样使用

$error = check_number($number);
if(!$error) {
    /*success*/ 
} else {
    $errors[] = $error;
}

但是这种方法是相当愚蠢的。更健壮的解决方案是编写一个类,利用类变量这样方便的特性

class NumberValidator
{
    protected $error;
    public function validate()
    {
        if(!is_numeric($number))
        {
            $this->error = "The value provided is not numeric";
            return false;
        }
        if($number < 10)
        {
            $this->error = "The number is less than 10";
            return false;
        }
        return true;
    }
    public function getError()
    {
        return $this->error;
    }
} 

然后可以这样使用

$validator = new NumberValidator();
if($validator->validate($number)) {
    /*success*/ 
} else {
    $errors[] = $validator->getError();
}