简体   繁体   中英

If statement with PDO SQL query

Could someone please assist / advise on how I could use if statements inside a sql query? I am trying to create a search form where the query would only consider the "category" and the "type" fields if they are not empty?

I have tried the code below, but are receiving an error:

    public static function findBySearch($data)
    {
        $location = $data['location'];
        $category = $data['category'];
        $type = $data['type'];
           
            $sql = 'SELECT * FROM posts
            WHERE location = :location';

            if ($category != '') {
            $sql .= ', category = :category';
            }

            if ($type != '') {
                $sql .= ', type = :type';
                }
       
            $db = static::getDB();
            $stmt = $db->prepare($sql);

            $stmt->bindValue(':location', $location, PDO::PARAM_STR);
           
            if ($category !='') {       
                $stmt->bindValue(':category', $category, PDO::PARAM_STR);
                }

            if ($type !='') {       
                $stmt->bindValue(':type', $type, PDO::PARAM_STR);
                } 

            return $stmt->execute();
        }

Error:

Uncaught exception: 'PDOException'

Message: 'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ' category = 'To Rent', type = 'House'' at line 2'

Stack trace:

#0 C:\xampp\htdocs\findingproperty\App\Models\Post.php(269): PDOStatement->execute()
#1 C:\xampp\htdocs\findingproperty\App\Controllers\Posts.php(106): App\Models\Post::findBySearch(Array)
#2 [internal function]: App\Controllers\Posts->searchAction()
#3 C:\xampp\htdocs\findingproperty\Core\Controller.php(51): call_user_func_array(Array, Array)
#4 C:\xampp\htdocs\findingproperty\Core\Router.php(121): Core\Controller->__call('search', Array)
#5 C:\xampp\htdocs\findingproperty\public\index.php(63): Core\Router->dispatch('posts/search')
#6 {main}

Any assistance would be appreciated.

In a WHERE statement you have to concatinate conditions with AND or OR as already pointed out in the comments.

What about this:

public static function findBySearch($data)
    {
        $location = $data['location'];
        $category = $data['category'];
        $type = $data['type'];
           
            $sql = 'SELECT * FROM posts
            WHERE location = :location';

            if ($category != '') {
                $sql .= 'AND category = :category';
            }

            if ($type != '') {
                $sql .= 'AND type = :type';
            }
       
            $db = static::getDB();
            $stmt = $db->prepare($sql);

            $stmt->bindValue(':location', $location, PDO::PARAM_STR);
           
            if ($category !='') {       
                $stmt->bindValue(':category', $category, PDO::PARAM_STR);
                }

            if ($type !='') {       
                $stmt->bindValue(':type', $type, PDO::PARAM_STR);
                } 

            return $stmt->execute();
        }

Or you can do:

public static function findBySearch($data)
    {
        $location = $data['location'];
        $category = $data['category'];
        $type = $data['type'];
           
            $sql = 'SELECT * FROM posts';
            $where = [
                [ 'column' => 'location', 'value' => $location ]
            ];

            if ($category != '') {
                $where[] = [ 'column' => 'category', 'value' => $category ];
            }

            if ($type != '') {
                $where[] = [ 'column' => 'type', 'value' => $type ];
            }
            
            if (count($where) {
                $sql .= ' WHERE '.join(' AND ', array_map(function($item) {
                    return $item['column'].' = :'.$item['value'];
                }));                
            }
       
            $db = static::getDB();
            $stmt = $db->prepare($sql);
            
            if (count($where) {
                foreach($where as $column => $value) {
                    $stmt->bindValue(':'.$column, $value, PDO::PARAM_STR);
                }
            }

            return $stmt->execute();
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM