0

I just want to make MySQL query with PDO and LIMIT. When PDO is making all numbers strings, I tried to turn PDO::ATTR_EMULATE_PREPARES false. When I've turned this false, my app didn't render the template, just the content. In some cases, it renders the first line of content view, then it goes to template and returns to content. Here are a few lines of the code. Without the line, where I'm setting PDO::ATTR_EMULATE_PREPARES false, everything is OK, but the query ofc.

There is my model, where the query is stored.

app\models
class ThingsAdmin{
    public function getLastThings($number){
        return $this->connection->allObjects('select ... limit ?', $typeofobject, array($param1);
    }
}

From this method of some controller, I'm calling the method from model.

app\controllers
$sz = new ThingsAdmin();

public function add($params = null) {
    $this->setTemplate('app/teplates/main');
    $content = new View('app/views/addsmth');
    $lastThings = $this->sz->getLastThings(10);
    $content->set('lastThings', $lastThings);
    $this->template->set('content', $content->render());
    echo $this->template->render();
}

Controller which extends anothers controllers.

libs\controller
public $template = null;

public $db = null;

protected function setConnection() {
    $options = array(
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ,
        PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING,
        PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"
    );
    $db_init = DB_TYPE . ':host=' . DB_HOST . ';dbname=' . DB_NAME;
    try {
        $this->db = new PDO($db_init, DB_USER, DB_PASS, $options);
    } catch (PDOException $e) {
        throw $e;
    }
}

protected function setTemplate($template) {
    $this->template = new View($template);
}

Library view with render method.

libs\View
public function render(){
    extract($this->_data);
    ob_start();
    try {
        require_once $this->_file;
    }
    catch (Exception $e) {
        ob_end_clean();
        throw $e;
    }
    return ob_get_clean();
}

Database connection wrapper.

libs\db
public function allObjects($query, $typeofobject, $params = array()) {
    $this->connection->setAttribute( PDO::ATTR_EMULATE_PREPARES, false );
    $stmt = $this->connection->prepare($query);
    $stmt->execute($params);
    // this instead of setAttribute does the same thing (yes, only one parameter)
    foreach ($parametry as $p) {
        $stmt->bindParam(1, $p, PDO::PARAM_INT);
    }
    $stmt->execute();
    // --------
    $stmt->setFetchMode(PDO::FETCH_CLASS, 'app\\models\\' . $typeofobject);
    return $stmt->fetchAll();
}

What am I missing?

Pang
  • 9,564
  • 146
  • 81
  • 122
Antonin
  • 1
  • 1
  • 4
  • `$parametry` is undefined. Also, you should presumably set emulate prepares only one time (i.e. in the connection options), not for every single query. – Mike Jul 05 '17 at 01:52
  • And on your line `$stmt->bindParam(1, $p, PDO::PARAM_INT);` you are hard-coding `1` in. Instead this should be the 1-indexed position of the parameter, which means it starts at 1 and increments by 1 for each parameter. Also, I believe you should use `bindValue()` instead of `bindParam()` because once you change the value of $p, you change the value bound to that parameter in the prepared statement. See: https://stackoverflow.com/questions/1179874/what-is-the-difference-between-bindparam-and-bindvalue – Mike Jul 05 '17 at 01:56
  • When in doubt check the log files. If anything's going wrong it should be there. – Mike Jul 05 '17 at 01:59

0 Answers0