PHP:如果...其他...查询

时间:2010-03-16 21:07:25

标签: php

我正在while (($data=fgetcsv($this->fin,5000,";"))!==FALSE)

下执行此声明

现在我想要的else循环只是为不满足if条件的数据值抛出异常。现在我正在显示完整的行,因为我不知道如何仅针对不满足该值的数据抛出异常。

代码

if ((strtotime($data[11]) &&strtotime($data[12])&&strtotime($data[16]))!==FALSE 
&& ctype_digit($data[0]) && ctype_alnum($data[1]) && ctype_digit($data[2]) 
&& ctype_alnum($data[3]) && ctype_alnum($data[4]) && ctype_alnum($data[5]) 
&& ctype_alnum($data[6]) && ctype_alnum($data[7]) && ctype_alnum($data[8]) 
&& $this->_is_valid($data[9]) && ctype_digit($data[10]) && ctype_digit($data[13]) 
&& $this->_is_valid($data[14]))
{
     //Some Logic
}
else
{
    throw new Exception ("Data {$data[0], $data[1], $data[2], $data[3],
    $data[4], $data[5], $data[6], $data[7],
    $data[8], $data[9], $data[10], $data[11], $data[12],
    $data[13], $data[14], $data[16]} is not in valid format");
}

我将高度赞赏指导如何仅针对不满足if值的数据抛出异常。

3 个答案:

答案 0 :(得分:4)

为什么不分开测试?即逐个进行每个测试,如果特定测试失败则抛出异常?


从您的代码复制粘贴,它可能看起来像这样:

if (!strtotime($data[11])) {
    throw new Exception("field 11 : {$data[11]} is not a valid date");
}
if (!strtotime($data[12])) {
    throw new Exception("field 12 : {$data[12]} is not a valid date");
}
// Some more...
if (!ctype_alnum($data[8])) {
    throw new Exception("field 8 : {$data[8]} is not a valid alnum");
}
// And so on...

// And when all is tested, you know the items 
// in $data are all OK


这样:

  • 您可以知道哪个字段导致验证失败
  • 如果您在同一个字段上有多个不同的测试,则可以知道哪个特定测试失败

并且,作为一种可能性,您可以(如果需要)抛出不同类型的异常,具体取决于失败的测试(即日期的一种异常,整数的异常, ......) - 在某些情况下,这可能有用。



评论后修改:更多完整示例

是的,您可以逐个字段进行验证,并且仍然可以逐行工作。

你只需要将你的测试代码包装在try / catch块中,这是在逐行循环的内部;有点像:

$validData = array();
$errors = array();

while ($data = fgetcsv($f)) {
    try {
        // Validate the data of the current line
        // And, if valid, insert it into the database

        if (!strtotime($data[11])) {
            throw new Exception("field 11 : {$data[11]} is not a valid date");
        }
        if (!strtotime($data[12])) {
            throw new Exception("field 12 : {$data[12]} is not a valid date");
        }
        // Some more...
        if (!ctype_alnum($data[8])) {
            throw new Exception("field 8 : {$data[8]} is not a valid alnum");
        }
        // And so on...

        // And when all is tested, you know the items 
        // in $data are all OK
        // => which means it can be inserted into the DB
        // Or you can just put the valid data into a "temporary" array, that will be used later :
        $validData[] = $data;

    } catch (Exception $e) {
        // An error has occurend on the current line
        // You can log it, if necessary :
        $errors[] = $e->getMessage();
    }
}

// Now that the whole file has been read, test if there's been an error :
if (empty($errors)) {
    // No error
    // => insert the data that's in $validData
} else {
    // There's been an error
    // => don't insert the data that's in $validData, if you don't want to insert anything
}


有了这个:

  • 如果一行(即验证失败)存在异常,您将跳转到catch块,以解决问题
  • 然后循环将重新开始,为下一行。

编辑 :(由Yacoby提供)
您可以只定义应由哪个函数检查哪些元素,然后在循环中处理它们,而不是拥有无限的if语句。这样就避免了16个if语句。

代码示例:

foreach ( array(11,12,16) as $index ){
    if ( !strtotime($data[$i]) ){
        throw new Exception("field {$i} : {$data[$i]} is not a date");
    }
}

foreach ( array(1,3,4,5,6,7,8) as $index ){
    if ( !ctype_alnum($data[$i]) ){
        throw new Exception("field {$i} : {$data[$i]} is not alphanumeric");
    }
}

foreach ( array(2, 10) as $i ){
    if ( !ctype_digit($data[$i]) ){
        throw new Exception("field {$i} : {$data[$i]} is not a valid digit");
    }
}

if ( !$this->_is_valid($data[14]) ){
    throw new Exception("field {14} : {$data[14]} is not valid");
}

答案 1 :(得分:1)

您需要将大量if语句拆分为每个值一个。

答案 2 :(得分:1)

我认为你最好把它分解成许多if语句,如

if(!strtotime($data[11])
{
    throw new Exception("...");
}

if(!strtotime($data[12]))
{
    throw new Exception("...");
}


//after all of your if statements now do business logic
//remember that all of your if conditions have to be met to get this far
//because throwing the exception will leave this stack
//so it functions sort of like the else clause would.