كيفية تطبيق طريقة BindValue في جملة الحد؟
سؤال
هذه لقطة من الكود الخاص بي:
$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);
تجده في الخارج؟
هذا مجرد ملخص.
هناك أربعة خيارات لتعليم قيم الحد/الإزاحة:
إبطال
PDO::ATTR_EMULATE_PREPARES
كما ذكر في الاعلى.الذي يمنع القيم التي تم تمريرها لكل
->execute([...])
لتظهر دائما كقواسل.التبديل إلى يدوي
->bindValue(..., ..., PDO::PARAM_INT)
السكان المعلمة.ومع ذلك ، فإنه أقل ملاءمة من قائمة التنفيذ [].
ما عليك سوى جعل استثناءً هنا وقم فقط بتمثيل الأعداد الصحيحة العادية عند إعداد استعلام SQL.
$limit = intval($limit); $s = $pdo->prepare("SELECT * FROM tbl LIMIT {$limit}");
الصب مهم. أكثر شيوعا ترى
->prepare(sprintf("SELECT ... LIMIT %d", $num))
تستخدم لمثل هذه الأغراض.إذا كنت لا تستخدم 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
. بعض الطرق للالتفاف حول هذا:
- يستخدم
filter_var($integer, FILTER_VALIDATE_NUMBER_INT)
للتأكد من أنك تمر عدد صحيح. - كما قال آخرون ، باستخدام
intval()
- صب مع
(int)
- التحقق مما إذا كان عدد صحيح مع
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 ) {
...
}