使用 PhpActiveRecord 检查 NULL 值

Check NULL value using PhpActiveRecord

根据此处的文档 (http://www.phpactiverecord.org/projects/main/wiki/Finders)

有一种方法可以在数据库中查找记录,如下所示。

 # fetch all lousy romance novels which are cheap
   Book::all(array('conditions' => array('genre = ? AND price < ?', 'Romance', 15.00)));
 # sql => SELECT * FROM `books` WHERE genre = 'Romance' AND price < 15.00

但是,如果任何值为 NULL,这将不起作用。这仅仅是因为 NULL 不是任何值,所以它没有任何可比较的东西。我明白这一点,但我在文档中无法弄清楚的是如何实际检查使用该格式的值是否为空。

在 SQL 中,您可以简单地说 WHERE 值为 null,或不为 null,但是对于 PHPActiveRecord 条件数组字符串,我不确定...

我想用条件字符串和数组来做的原因是我有自动创建这些条件的代码设置,我将 post 下面的代码。

    function create_find_options($fields,$operators,$values,$sortfields,$sortdirections,$limit,$offset,$logic){
        $conditionstring = '';
        $fieldcount = count($fields);
        $i=0;

        for($k=0;$k<count($logic)-1;$k++){
            $conditionstring.="(";//add starting parenthesis for every known logic.
        }

        for($i=0;$i<$fieldcount;$i++){
            $conditionstring.=$fields[$i];
            switch($operators[$i]){
                case "equals":
                    $conditionstring.=" = ?";
                    break;
                case "greaterthan":
                    $conditionstring.=" > ?";
                    break;
                case "lessthan":
                    $conditionstring.=" < ?";
                    break;
                case "notequals":
                    $conditionstring.=" != ?";
                    break;
                case "contains":
                    $conditionstring.=" LIKE ?";
                    break;
            }

            if($i!=$fieldcount-1 && $fieldcount>=2){
                if($i>0){
                    $conditionstring.=")";//first condition does not get ending parenthesis.
                }
                $conditionstring.=" ".$logic[$i]." ";//AND or OR
            }
        }

        //$conditionstring = substr($conditionstring,0,strlen($conditionstring)-5);
        //die($conditionstring);

        $options = array('conditions' => array($conditionstring));

        $i=0;
        for($i=0;$i<$fieldcount;$i++){
            if($operators[$i]=="contains"){ //exception for contains because it needs the percentage symbols around the value.
                $options['conditions'][] = "%".$values[$i]."%";
            }else{
                $options['conditions'][] = $values[$i];
            }
        }

        //Add any sorts now.
        $i=0;
        $sortcount = count($sortfields);
        $orderstring = '';
        for($i=0;$i<$sortcount;$i++){
            $orderstring.= $sortfields[$i]." ".$sortdirections[$i].",";
        }
        $orderstring = rtrim($orderstring,",");//remove trailing comma

        $options['order'] = $orderstring;//sets order rules.

        //Add any limits now.
        if(isset($limit)){
            $options['limit']   = $limit;
        }
        if(isset($offset)){
            $options['offset']  = $offset;
        }

        return $options;
    }

所以我的函数将自动创建所需的条件字符串,但由于我上面描述的原因,它在 NULL 上失败。我想我需要在这里添加一些额外的条件,如果我检测到 NULL 如何更好地处理它,但我不确定该怎么做或者 [=13 是否可行=]?

好吧,花了……一整天,我找到了解决办法。我想这可能是常识,但文档中没有,所以我不得不猜测。

显然你可以像常规 SQL 一样在条件字符串中简单地说 'is null' 并且它会起作用...

也就是说,我将我的函数更新为以下内容,这会生成一个完整的选项数组,其条件已准备就绪,即使使用空值也能正常工作。

希望这对某人有用!在我的情况下,我希望 0 与 null 相同,因此您可以根据自己的情况进行相应调整。

function create_find_options($fields,$operators,$values,$sortfields,$sortdirections,$limit,$offset,$logic){
    $conditionstring = '';
    $fieldcount = count($fields);
    $i=0;

    for($k=0;$k<count($logic)-1;$k++){
        $conditionstring.="(";//add starting parenthesis for every known logic.
    }

    for($i=0;$i<$fieldcount;$i++){
        $conditionstring.=$fields[$i];
        $nullFound = false;
        if($values[$i]=='0'){
            $nullFound = true;
        }
        switch($operators[$i]){
            case "equals":
                if($nullFound==true){
                    $conditionstring.=" is null OR ".$fields[$i].' = 0';
                }else{
                    $conditionstring.=" = ?";
                }
                break;
            case "greaterthan":
                $conditionstring.=" > ?";
                break;
            case "lessthan":
                $conditionstring.=" < ?";
                break;
            case "notequals":
                if($nullFound==true){
                    $conditionstring.=" is not null OR ".$fields[$i].' != 0';
                }else{
                    $conditionstring.=" != ? OR ".$fields[$i].' is null';
                }
                break;
            case "contains":
                $conditionstring.=" LIKE ?";
                break;
        }

        if($i!=$fieldcount-1 && $fieldcount>=2){
            if($i>0){
                $conditionstring.=")";//first condition does not get ending parenthesis.
            }
            $conditionstring.=" ".$logic[$i]." ";//AND or OR
        }
    }

    //$conditionstring = substr($conditionstring,0,strlen($conditionstring)-5);
    //die($conditionstring);

    $options = array('conditions' => array($conditionstring));

    $i=0;
    for($i=0;$i<$fieldcount;$i++){
        if($values[$i]!="0"){
            if($operators[$i]=="contains"){ //exception for contains because it needs the percentage symbols around the value.
                $options['conditions'][] = "%".$values[$i]."%";
            }else{
                $options['conditions'][] = $values[$i];
            }
        }
    }

    //Add any sorts now.
    $i=0;
    $sortcount = count($sortfields);
    $orderstring = '';
    for($i=0;$i<$sortcount;$i++){
        $orderstring.= $sortfields[$i]." ".$sortdirections[$i].",";
    }
    $orderstring = rtrim($orderstring,",");//remove trailing comma

    $options['order'] = $orderstring;//sets order rules.

    //Add any limits now.
    if(isset($limit)){
        $options['limit']   = $limit;
    }
    if(isset($offset)){
        $options['offset']  = $offset;
    }
    //die(print_r($options));
    return $options;
}