Jump to content

PHP oop coding, please comment.


Supervan
Go to solution Solved by Supervan,

Recommended Posts

Hi,

I'm trying to improve my coding and would appreciate if someone could comment and alter my code.
I dont know what would work best, named placeholders or question mark placeholders. Place the variables in a array first and then do the binding.

Im looking also for solutions regarding record update using place holders.

Thanks

    $idnrr = 1;
    $users = DB::getInstance()->query("SELECT * FROM users WHERE id = :id1", array(':id1' => $idnrr));
    if ($users->count()) {
        foreach ($users->results() as $result) {
            echo $result->name . "<br />";
        }
    }
public function query($sql, $params) {
        $this->_error = false;
        if ($this->_query = $this->_pdo->prepare($sql)) {
            $x = 1;
           

            if ($this->_query->execute($params)) {
                $this->_results = $this->_query->fetchAll(PDO::FETCH_OBJ);
                $this->_count = $this->_query->rowCount();
            } else {
                $this->_error = true;
            }
        }

        return $this;
    }
Link to comment
Share on other sites

imo, it doesn't matter if you use named place holders or ? place holders. you have to keep track of how many, what they are used for, and supply an input parameter for each one.

 

btw - your existing code will work for either type of place holder. for a ? place holder, your query calling statement would become - $users = DB::getInstance()->query("SELECT * FROM users WHERE id = ?", array($idnrr));

 

however, your current method of supplying the parameters in the ->execute($params) method won't work for things like LIMIT x,y clauses (i.e. you are dynamically getting the y value from the user), because using ->execute($params) treats all the parameters as strings, which produces a sql syntax error when used in a LIMIT clause.

 

a general purpose solution would need a way of (optionally) supplying the input type (in each element in your $params array) and would specifically bind each input by looping over the elements of the $params array. see the following example -

    public function query($query,$data_in=array()){
        if($data_in){
            // prepared query
            $stmt = parent::prepare($query); // this example extends the pdo class
            foreach($data_in as $arr){
                if(isset($arr[2])){
                    // type supplied
                    $stmt->bindValue($arr[0],$arr[1],$arr[2]);
                } else {
                    // no type supplied
                    $stmt->bindValue($arr[0],$arr[1]); // defaults to string type
                }
            }
            $stmt->execute();
        } else {
            // non-prepared query
            $stmt = parent::query($query);
        }

        // code to retrieve the result from the query....

    }

to specifically supply an integer data type, the $params array entry, corresponding to your supplied example, would look like - array(':id',$idnrr,PDO::PARAM_INT). to use a ? place holder, this would become - array(1,$idnrr,PDO::PARAM_INT)

Link to comment
Share on other sites

imo, it doesn't matter if you use named place holders or ? place holders. you have to keep track of how many, what they are used for, and supply an input parameter for each one.

 

btw - your existing code will work for either type of place holder. for a ? place holder, your query calling statement would become - $users = DB::getInstance()->query("SELECT * FROM users WHERE id = ?", array($idnrr));

 

however, your current method of supplying the parameters in the ->execute($params) method won't work for things like LIMIT x,y clauses (i.e. you are dynamically getting the y value from the user), because using ->execute($params) treats all the parameters as strings, which produces a sql syntax error when used in a LIMIT clause.

 

a general purpose solution would need a way of (optionally) supplying the input type (in each element in your $params array) and would specifically bind each input by looping over the elements of the $params array. see the following example -

    public function query($query,$data_in=array()){
        if($data_in){
            // prepared query
            $stmt = parent::prepare($query); // this example extends the pdo class
            foreach($data_in as $arr){
                if(isset($arr[2])){
                    // type supplied
                    $stmt->bindValue($arr[0],$arr[1],$arr[2]);
                } else {
                    // no type supplied
                    $stmt->bindValue($arr[0],$arr[1]); // defaults to string type
                }
            }
            $stmt->execute();
        } else {
            // non-prepared query
            $stmt = parent::query($query);
        }

        // code to retrieve the result from the query....

    }

to specifically supply an integer data type, the $params array entry, corresponding to your supplied example, would look like - array(':id',$idnrr,PDO::PARAM_INT). to use a ? place holder, this would become - array(1,$idnrr,PDO::PARAM_INT)

 

Thanks for your help..

Link to comment
Share on other sites

I really appreciated your help. I tried, but missing something.

 

Error... Warning: PDOStatement::bindValue() expects parameter 3 to be long

$idnrr = 1;
$name1 = "tom12345";

$users = DB::getInstance()->query("SELECT * FROM users WHERE id = :id AND name = :name",
                                   array(':id'=>$idnrr,PDO::PARAM_INT,':name'=>$name1,PDO::PARAM_STR));

if ($users->count()) {
    foreach ($users->results() as $result) {
        echo $result->name . "<br />";
    }
}
class DB {

    private static $_instance = null; // use $_ notation for private
    private $_pdo,
            $_query,
            $_error = false,
            $_results,
            $_count = 0;

  
    public function query($sql, $data_in = array()) {
        $this->_error = false;
        if ($data_in) {// prepared query
            $this->_query = $this->_pdo->prepare($sql); // this example extends the pdo class
            foreach ($data_in as $arr) {
                if (isset($arr[2])) {// type supplied
                    $this->_query->bindValue($arr[0], $arr[1], $arr[2]);
                } else {// no type supplied
                    $this->_query->bindValue($arr[0], $arr[1]); // defaults to string type
                }
            }
            if ($this->_query->execute()) {
                $this->_results = $this->_query->fetchAll(PDO::FETCH_OBJ);
                $this->_count = $this->_query->rowCount();
            } else {
                $this->_error = true;
            }
        } else {// non-prepared query
            $this->_query = $this->_pdo->prepare($sql);
            if ($this->_query->execute()) {
                $this->_results = $this->_query->fetchAll(PDO::FETCH_OBJ);
                $this->_count = $this->_query->rowCount();
            } else {
                $this->_error = true;
            }
        }// code to retrieve the result from the query....
        return $this;
    }


  

    public function results() {
        return $this->_results;
    }

    public function first() {
        return $this->_results[0];
    }

    public function error() {
        return $this->_error;
    }

    public function count() {
        return $this->_count;
    }

}

 

Link to comment
Share on other sites

the array structure would be - array(array(':id',$idnrr,PDO::PARAM_INT),array(':name',$name1,PDO::PARAM_STR))

 

or more clearly -

$parms = array();
$parms[] = array(':id',$idnrr,PDO::PARAM_INT);
$parms[] = array(':name',$name1,PDO::PARAM_STR);

// then use the $parms array as the second parameter in your query calling statement -
 $users = DB::getInstance()->query("SELECT * FROM users WHERE id = :id AND name = :name",$parms);
Link to comment
Share on other sites

  • Solution

 

the array structure would be - array(array(':id',$idnrr,PDO::PARAM_INT),array(':name',$name1,PDO::PARAM_STR))

 

or more clearly -

$parms = array();
$parms[] = array(':id',$idnrr,PDO::PARAM_INT);
$parms[] = array(':name',$name1,PDO::PARAM_STR);

// then use the $parms array as the second parameter in your query calling statement -
 $users = DB::getInstance()->query("SELECT * FROM users WHERE id = :id AND name = :name",$parms);

 

This worked like a charm... Thank you so much.

Now I need to try and solve the rest. Update/ Insert and delete..

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.