LIMIT子句的参数化PDO查询

时间:2018-01-11 11:33:52

标签: php sql pdo

我已经看到类似的问题已经回答,但我似乎无法将相同的解决方案应用到我的代码中。

$a=1;
$results = DB::query('SELECT posts.`postbody`, posts.`filepost`, posts.`likes`, posts.`posted_at`, users.`id`, posts.`id_of_post` FROM posts, users WHERE posts.`post_id` = users.`id` ORDER BY id_of_post DESC LIMIT :a', array(':a'=>$a));

class DB {
    private static function connect() {
        $pdo = new PDO('mysql:host=127.0.0.1;dbname=SocialNetwork;charset=utf8', 'root', '');
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        return $pdo;
    }
    public static function query($query, $params = array()) {
        $statement = self::connect()->prepare($query);
        $statement->execute($params);
        if (explode(' ', $query)[0] == 'SELECT') {
        $data = $statement->fetchAll();
        return $data;
        }
    }
}

对于记录,以下代码可以正常工作。

$results = DB::query('SELECT posts.`postbody`, posts.`filepost`, posts.`likes`, posts.`posted_at`, users.`id`, posts.`id_of_post` FROM posts, users WHERE posts.`post_id` = users.`id` ORDER BY id_of_post DESC LIMIT 1');

3 个答案:

答案 0 :(得分:0)

如前所述,如果您没有定义:

class Button
  def initialize link
    @link = link
  end

  def color(color)
    @color = color
    self
  end

  def shape(shape)
    @shape = shape
    self
  end

  def self.create(type, link)
    case type
    when 'RedButton'
        self.new(link).color('red')
    when 'RoundButton'
        self.new(link).shape('round')
    when 'RedRoundButton'
        self.new(link).color('red').shape('round')
    else
        raise 'Unknown type'
    end
  end
end

x = Button.create('RedButton', 4)
y = Button.create('RedRoundButton', 6)

您必须将要绑定的参数定义为整数:

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

这仍然不是一个完美的解决方案,但如果您信任键值对(即它们来自代码,而不是用户输入),它就足够了。

答案 1 :(得分:0)

不理想,但您可以取消PDO参数。

$a = 1;
$sql = "SELECT stuff FROM table LIMIT {$a};";

然后从$sql字符串运行您的查询。

答案 2 :(得分:0)

在MySQL的LIMIT子句中,执行此操作是错误的:

LIMIT '1'

因为LIMIT必须采用整数,而不是字符串。

如果PDO配置为模拟prepare()(通过将值插入到SQL字符串中),则可能会使插值成为带引号的字符串,这将导致错误。

为避免这种情况,您必须使用原生整数作为绑定变量,您只需指定PDO::PARAM_INT

    $statement = self::connect()->prepare($query);
    $statement->bindParam('a', $a, PDO::PARAM_INT);
    $statement->execute();

这将让驱动程序知道避免在插值值周围加上引号。

如果将PDO属性设置为禁用模拟准备,也可以避免错误。我总是这样做,因为我不相信“模拟准备。”

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

另见我在这里写的测试:Parametrized PDO query and `LIMIT` clause - not working