SINIR PHP PDO bindValue

6 Cevap php

İşte benim kod görüntüsüdür:

$fetchPictures = $PDO->prepare("SELECT * FROM pictures WHERE album = :albumId ORDER BY id ASC LIMIT :skip, :max");
$fetchPictures->bindValue(':albumId', $_GET['albumid'], PDO::PARAM_INT);
if(isset($_GET['skip'])){
    $fetchPictures->bindValue(':skip', trim($_GET['skip']), PDO::PARAM_INT);    
}
else{
    $fetchPictures->bindValue(':skip', 0, PDO::PARAM_INT);  
}
$fetchPictures->bindValue(':max', $max, PDO::PARAM_INT);
$fetchPictures->execute() or die(print_r($fetchPictures->errorInfo()));
$pictures = $fetchPictures->fetchAll(PDO::FETCH_ASSOC);

Ben olsun

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''15', 15' at line 1

It seems that PDO is adding single quotes to my variables in the LIMIT part of the SQL code. I looked it up I found this bug which I think is related: http://bugs.php.net/bug.php?id=44639

Is that what I'm looking at? This bug has been opened since April 2008! What are we supposed to do in the meantime?

i bazı sayfalandırma oluşturmak gerekiyor ve veri temiz olduğundan emin olmak gerekir, sql enjeksiyon güvenli, sql deyimi göndermeden önce.

6 Cevap

Ben daha önce bu sorunu yaşıyorsanız hatırlıyorum. Bağlama işlevine geçirmeden önce bir tamsayı değeri döküm. Ben bu bunu çözer düşünüyorum.

$fetchPictures->bindValue(':skip', (int) trim($_GET['skip']), PDO::PARAM_INT);

Hata raporu baktığımızda, şu işe yarayabilir:

$fetchPictures->bindValue(':albumId', (int)$_GET['albumid'], PDO::PARAM_INT);

$fetchPictures->bindValue(':skip', (int)trim($_GET['skip']), PDO::PARAM_INT);  

ama eminiz gelen verileri doğru? Hata iletisinde, sayıdan sonra sadece one alıntı (tırnak içinde olan tam sayıya aksine) gibi görünüyor çünkü. Bu da, gelen veri ile bir hata olabilir. Öğrenmek için bir print_r($_GET); yapabilir miyim?

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

tüm ihtiyacınız

Ayrıca, daha kısa kullanılabilir. PHP kullanıcıları uzun ve rüzgarlı koduna kadar eğimli neden ben anlamıyorum.

$skip = (isset($_GET['skip'])):$_GET['skip']:0;
$sql  = "SELECT * FROM pictures WHERE album = ? ORDER BY id ASC LIMIT ?, ?";
$stm  = $PDO->prepare($sql);
$stm->execute(array($_GET['albumid'],$skip,$max));
$pictures = $stm->fetchAll(PDO::FETCH_ASSOC);

LIMIT :init, :end için

You need to bind that way. if you had something like $req->execute(Array()); it wont work as it will cast PDO::PARAM_STR to all vars in the array and for the LIMIT you absolutely need an Integer. bindValue or BindParam as you want.

$fetchPictures->bindValue(':albumId', (int)$_GET['albumid'], PDO::PARAM_INT);

Ben aynı sorunla karşı karşıya duyuyorum, ama ne yazık ki kullanan bir çerçeve üreten sorgu parçası olmak $statement->execute($query, $params) ben yukarıda önerilen çözüm kullanamadı.

Ancak, sınır şartının bağlı params yerine genel bir düzenli ifade kontrol uygulanmaktadır.

Ile $sQuery, örneğin olur:

SELECT `name` FROM `students` 
WHERE `school` LIKE :PARAM1 
LIMIT :PARAM2, :PARAM3

$sParamVal değeri her türlü sahip sen, bir argüman olarak bekliyoruz

Argüman listesine uygulanan aşağıdaki komut çalışması gerekir. Benim durumumda jenerik ve params sayısı sorgunun bağlıdır, bu yüzden bir döngü bu pasajı da dahil olmak üzere, işlenir Unutmayın:

    if (preg_match("/LIMIT :PARAM" . $i . "\\b/", $sQuery) === 1) {
        $sQuery = preg_replace("/LIMIT :PARAM" . $i . "\\b/", "LIMIT " . intval($sParamVal), $sQuery);
    } else if (preg_match("/LIMIT :PARAM[\d]+,[ ]*:PARAM" . $i . "\\b/", $sQuery) === 1) {
        $sQuery = preg_replace("/(LIMIT :PARAM[\d]+,[ ]*)(:PARAM" . $i . ")\\b/", "\\1 " . intval($sParamVal), $sQuery);
    } else if (preg_match("/LIMIT [\d]+,[ ]*:PARAM" . $i . "\\b/", $sQuery) === 1) {
        $sQuery = preg_replace("/(LIMIT [\d]+,[ ]*)(:PARAM" . $i . ")\\b/", "\\1 " . intval($sParamVal), $sQuery);
    } else {
        $arr[":PARAM" . $i] = $sParamVal;
    }

... etc

$statement = $cn->prepare($sQuery);
$statement->execute($arr);

Bu idare edecek:

  • SINIR X
  • SINIR X, Y

X veya Y tamsayı (sql enjeksiyon, parametrelerinde hata) değilse, intval will most likely return 0 although this depends on the leftmost characters of the string.

Ben insanların olduğunu yolu sıkışmış için başka bir alternatif verecek umuyoruz.

Şerefe!

$ Bilgi benim bağlı parametreleri tutarak benim dizidir nerede mayın şu ki:

    preg_match( '/LIMIT :(?P<limit>[0-9a-zA-Z]*)/', $sql, $matches );
    if (count($matches)) {
        //print_r($matches);
        $sql = str_replace( $matches[0], 'LIMIT ' . intval( $info[':' . $matches['limit']] ), $sql );
    }       
    // LIMIT #, :limit#
    preg_match( '/LIMIT (?P<limit1>[0-9]*),\s?:(?P<limit2>[0-9a-zA-Z]*)/', $sql, $matches );
    if (count($matches)) {
        //print_r($matches);
        $sql = str_replace( $matches[0], 'LIMIT ' . $matches['limit1'] . ',' . intval( $info[':' . $matches['limit2']] ), $sql );
    }

Bu Sebas kodunun kısmen dayanmaktadır.