سؤال

هذه لقطة من الكود الخاص بي:

$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);

انا حصلت

لديك خطأ في بناء جملة SQL الخاص بك ؛ تحقق من الدليل الذي يتوافق مع إصدار خادم MySQL الخاص بك لاستخدام بناء الجملة الأيمن بالقرب من "15" ، 15 "في السطر 1

يبدو أن PDO يضيف عروض أسعار واحدة إلى متغيراتي في الجزء الحد من رمز SQL. نظرت إلى الأمر ، لقد وجدت هذا الخطأ الذي أعتقد أنه مرتبط:http://bugs.php.net/bug.php؟id=44639

هل هذا ما أبحث عنه؟ تم افتتاح هذا الخطأ منذ أبريل 2008! ما الذي من المفترض أن نفعله في هذه الأثناء؟

أحتاج إلى بناء بعض ترقيم الصفحات ، وأحتاج إلى التأكد من أن البيانات نظيفة ، SQL Aft ، قبل إرسال عبارة SQL.

هل كانت مفيدة؟

المحلول

أتذكر أنني أواجه هذه المشكلة من قبل. قم بإلقاء القيمة إلى عدد صحيح قبل تمريرها إلى وظيفة الربط. أعتقد أن هذا يحلها.

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

نصائح أخرى

أبسط حل هو قم بإيقاف تشغيل وضع المحاكاة. يمكنك القيام بذلك إما كخيار اتصال أو ببساطة عن طريق إضافة السطر التالي

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

لن يحل مشكلتك فقط مع Bind Param ، ولكن أيضًا يتيح لك إرسال القيم في Execute () ، مما سيجعل الكود الخاص بك كثيرًا

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

بالنظر إلى تقرير الأخطاء ، قد ينجح ما يلي:

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

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

لكن هل أنت متأكد من أن بياناتك الواردة صحيحة؟ لأنه في رسالة الخطأ ، يبدو أن هناك فقط واحد اقتبس بعد الرقم (على عكس العدد الكامل المرفق في اقتباسات). يمكن أن يكون هذا أيضًا خطأ في بياناتك الواردة. هل يمكنك القيام print_r($_GET); تجده في الخارج؟

هذا مجرد ملخص.
هناك أربعة خيارات لتعليم قيم الحد/الإزاحة:

  1. إبطال PDO::ATTR_EMULATE_PREPARES كما ذكر في الاعلى.

    الذي يمنع القيم التي تم تمريرها لكل ->execute([...]) لتظهر دائما كقواسل.

  2. التبديل إلى يدوي ->bindValue(..., ..., PDO::PARAM_INT) السكان المعلمة.

    ومع ذلك ، فإنه أقل ملاءمة من قائمة التنفيذ [].

  3. ما عليك سوى جعل استثناءً هنا وقم فقط بتمثيل الأعداد الصحيحة العادية عند إعداد استعلام SQL.

     $limit = intval($limit);
     $s = $pdo->prepare("SELECT * FROM tbl LIMIT {$limit}");
    

    الصب مهم. أكثر شيوعا ترى ->prepare(sprintf("SELECT ... LIMIT %d", $num)) تستخدم لمثل هذه الأغراض.

  4. إذا كنت لا تستخدم MySQL ، ولكن على سبيل المثال sqlite ، أو postgres ؛ يمكنك أيضًا إلقاء معلمات ملزمة مباشرة في SQL.

     SELECT * FROM tbl LIMIT (1 * :limit)
    

    مرة أخرى ، لا يدعم MySQL/MariaDB التعبيرات في جملة الحد. ليس بعد.

ل LIMIT :init, :end

تحتاج إلى ربط بهذه الطريقة. إذا كان لديك شيء مثل $req->execute(Array()); لن يعمل كما سوف يلقي PDO::PARAM_STR إلى جميع Vars في الصفيف ولل LIMIT أنت بحاجة بالتأكيد إلى عدد صحيح. bindvalue أو bindparam كما تريد.

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

نظرًا لأن أحداً لم يشرح سبب حدوث ذلك ، فأنا أضيف إجابة. السبب الذي يجعل هذا هو التصرف هو أنك تستخدم trim(). إذا نظرت إلى دليل PHP لـ trim, نوع العودة هو string. أنت تحاول بعد ذلك تمرير هذا PDO::PARAM_INT. بعض الطرق للالتفاف حول هذا:

  1. يستخدم filter_var($integer, FILTER_VALIDATE_NUMBER_INT) للتأكد من أنك تمر عدد صحيح.
  2. كما قال آخرون ، باستخدام intval()
  3. صب مع (int)
  4. التحقق مما إذا كان عدد صحيح مع is_int()

هناك الكثير من الطرق ، ولكن هذا هو السبب الجذري في الأساس.

إزاحة BINDVALUE وحدها باستخدام PDO :: param_int وستعمل

// قبل (الخطأ الحالي) $ query = ".... limit: p1 ، 30 ؛" ؛ ... $ stmt-> bindParam (': p1' ، $ limiteinferior) ؛

// بعد (خطأ تصحيح) $ query = ".... الحد: p1 ، 30 ؛" ؛ ... $ limiteInferior = (int) $ limiteInferior ؛ $ stmt-> bindParam (': p1' ، $ limiteinferior ، pdo :: param_int) ؛

PDO::ATTR_EMULATE_PREPARES أعطاني

لا يدعم برنامج التشغيل هذه الوظيفة: لا يدعم برنامج التشغيل هذا الخطأ في إعداد السمات.

كان الحل الخاص بي هو تعيين أ $limit متغير كسلسلة ، ثم ادمجها في عبارة إعداد كما في المثال التالي:

$limit = ' LIMIT ' . $from . ', ' . $max_results;
$stmt = $pdo->prepare( 'SELECT * FROM users WHERE company_id = :cid ORDER BY name ASC' . $limit . ';' );
try {
    $stmt->execute( array( ':cid' => $company_id ) );
    ...
}
catch ( Exception $e ) {
    ...
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top