Search code examples
phpzend-frameworkzend-framework2zend-framework3

How to implement prepared statement in Zend Framework Database Query Functions


I am learning the Zend Framework. Now I need to attach a prepared statement to prevent SQL injection in the Zend Framework. So I am sharing some functions here which I am using so if you can tell me how I can attach a prepared statement in these Zend Database Query Functions it will be helpful.

public function getRowByID($id) {
        $row = $this->fetchRow("id =  '$id'");
        if (!$row) {
            return false;
        }
        return $row;
    }

public function getbyProjectID($projectid) {
        $query = "SELECT * FROM auth where projectid = '$projectid'";

        $result = $this->getAdapter()->query($query);
        return $result->fetchAll();
    }

public function updateRowByUserProject($username, $projectid) {

        $query = "UPDATE auth SET iscurrent=0 WHERE username = '$username'";

        $result = $this->getAdapter()->query($query);

        $query1 = "UPDATE auth SET iscurrent=1 WHERE username = '$username' AND projectid = '$projectid'";

        $result1 = $this->getAdapter()->query($query1);
        $affectedRow = $result1->rowCount();
        if($affectedRow == 1){
            return true;
        }else{
            return false;
        }
    }

Solution

  • For fetching you could use Zend_Db_Select Class methods for preparing a query and executing it, passing variables in questionmark places (placeholders which will be escaped from special characters) after comma (possible multiple questionmarks, passing variables from left to right):

    public function getRowByID($id) {
            $table = $this->getTable();
            $select = $table->select();
    
            $select->where('id = ?', $id);
    
            $row = $table->fetchRow($select);
    
            if (!$row) {
                return false;
            }
            return $row;
        }
    

    For your second method getByProjectId() it depends if you are in proper model (like Auth_Model_Auth) or you want to access data from another table

    public function getbyProjectID($projectid) {
        $table = $this->getTable();
        $select = $table->select();
    
        $select->where('projectid = ?', $projectid);
    
        $result = $table->fetchAll($select);
        return $result;
    }
    

    And for updating you can pass an array to 'update' method in same style like for fetching data. Key of an array must be a column name of your table.

    public function updateRowByUserProject($username, $projectid) {
        $table = $this->getTable();
    
        // Data you want to insert/update
        $data = [
            'iscurrent' => 0
        ];
    
        // Where you want to update it
        $where = [
            'username = ?' => $username
        ]
    
        $result = $table->update($data, $where);
    
        $data1 = [
            'iscurrent' => 1
        ]
    
        $where1 = [
            'username = ?' => $username,
            'projectid = ?' => $projectid
        ]
    
        $result1 = $table->update($data1, $where1);
    }
    

    EDIT:

    For both questions from comments you could achieve this by using quoteInto method, which also escapes data from special chars.

    In first case you prepare a $where variable, which contains what record you want to delete:

    $table = $this->getTable();
    $where = $table->getAdapter()->quoteInto('projectid = ?', $projectid); 
    
    $isDeleted = $table->delete($where);
    

    In second case you can do exactly the same:

    $query = "SELECT COUNT(*) AS total FROM applications WHERE projectid IN (SELECT projectid FROM auth WHERE projectid = ?)";
    $query = $this->getAdapter()->quoteInto(?, $projectid):
    ...
    

    But you should try to avoid writing big queries in one variable and then executing them. I would suggest you to get to know with this: https://framework.zend.com/manual/1.11/en/zend.db.select.html

    Really well explained how to use Zend methods for this purpose.