mysqli_fetch_assoc () คาดว่าจะมีข้อผิดพลาดพารามิเตอร์ / เรียกไปยังฟังก์ชันสมาชิก bind_param () จะรับข้อผิดพลาด mysql จริงและแก้ไขได้อย่างไร?


111

ในสภาพแวดล้อมโลคัล / การพัฒนาของฉันคิวรี MySQLi ทำงานได้ดี อย่างไรก็ตามเมื่อฉันอัปโหลดในสภาพแวดล้อมการโฮสต์เว็บฉันได้รับข้อผิดพลาดนี้:

ข้อผิดพลาดร้ายแรง: เรียกใช้ฟังก์ชันสมาชิก bind_param () บนวัตถุที่ไม่ใช่ใน ...

นี่คือรหัส:

global $mysqli;
$stmt = $mysqli->prepare("SELECT id, description FROM tbl_page_answer_category WHERE cur_own_id = ?");
$stmt->bind_param('i', $cur_id);
$stmt->execute();
$stmt->bind_result($uid, $desc);

ในการตรวจสอบคำถามของฉันฉันพยายามดำเนินการค้นหาผ่านแผงควบคุม phpMyAdmin และผลลัพธ์ก็โอเค


เราสามารถดูว่าคุณเริ่มต้น$mysqliตัวแปรได้ที่ไหน?
Rikesh

อาจเป็นไปได้ว่าผู้ใช้ MySQL ของคุณไม่มีสิทธิ์ในการSELECTสืบค้น คุณตรวจสอบแล้วหรือยัง?
Amal Murali

สิ่งที่ควรคำนึงถึงคือไม่มี mysqli ให้ใช้งานหรือคุณให้ข้อมูลรับรองไม่ถูกต้องเพื่อเชื่อมต่อกับ MySQL
NB

ฉันรู้ว่าโพสต์นี้เก่าจริงๆ แค่คิดว่าฉันจะเพิ่มความคิดเห็น ฉันมีข้อผิดพลาดเดียวกันทุกประการและปัญหาคือการสะกดชื่อฟิลด์ในฐานข้อมูลผิดพลาดเพียงครั้งเดียว เมื่อฉันแก้ไขแล้วทุกอย่างก็ใช้ได้ โง่เล็กน้อย แต่อย่างไรก็ตาม
Brian

คำตอบ:


123

บางครั้งรหัส MySQLi ของคุณสร้างข้อผิดพลาดเช่นmysqli_fetch_assoc() expects parameter..., Call to a member function bind_param()...หรือคล้ายกัน หรือแม้กระทั่งไม่มีข้อผิดพลาดใด ๆ แต่แบบสอบถามไม่ได้ทำงานเหมือนกันทั้งหมด หมายความว่าการสืบค้นของคุณล้มเหลวในการดำเนินการ

เวลาแบบสอบถามล้มเหลวทุก MySQL มีข้อผิดพลาดที่อธิบายเหตุผล น่าเสียดายที่โดยค่าเริ่มต้นข้อผิดพลาดดังกล่าวจะไม่ถูกถ่ายโอนไปยัง PHP และสิ่งที่คุณมีคือข้อความแสดงข้อผิดพลาดที่เป็นความลับที่กล่าวถึงข้างต้น ดังนั้นการกำหนดค่า PHP และ MySQLi จึงเป็นเรื่องสำคัญมากเพื่อรายงานข้อผิดพลาด MySQL ให้คุณทราบ และเมื่อคุณได้รับข้อความแสดงข้อผิดพลาดการแก้ไขจะกลายเป็นเค้ก

จะรับข้อความแสดงข้อผิดพลาดใน MySQLi ได้อย่างไร

ก่อนอื่นต้องมีบรรทัดนี้เสมอก่อนที่ MySQLi จะเชื่อมต่อในทุกสภาพแวดล้อมของคุณ:

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

หลังจากนั้นข้อผิดพลาด MySQL ทั้งหมดจะถูกโอนไปยังข้อยกเว้นของ PHP ในทางกลับกันข้อยกเว้นที่ไม่ถูกจับทำให้ PHP เกิดข้อผิดพลาดร้ายแรง ดังนั้นในกรณีที่เกิดข้อผิดพลาด MySQL คุณจะได้รับข้อผิดพลาด PHP ทั่วไป นั่นจะทำให้คุณทราบสาเหตุของข้อผิดพลาดได้ทันที และการติดตามสแต็กจะนำคุณไปยังจุดที่เกิดข้อผิดพลาด

วิธีกำหนดค่า PHP ในสภาพแวดล้อมต่างๆ

นี่คือส่วนสำคัญของบทความของฉันเกี่ยวกับการรายงานข้อผิดพลาด PHP : การ
รายงานข้อผิดพลาดในการพัฒนาและเซิร์ฟเวอร์ที่ใช้งานจริงต้องแตกต่างกัน บนเซิร์ฟเวอร์การพัฒนาจะสะดวกที่จะมีข้อผิดพลาดปรากฏบนหน้าจอ แต่ในข้อความแสดงข้อผิดพลาดของเซิร์ฟเวอร์จริงจะต้องถูกบันทึกแทนดังนั้นคุณจะพบข้อผิดพลาดในบันทึกข้อผิดพลาดในภายหลัง

ดังนั้นคุณต้องตั้งค่าตัวเลือกการกำหนดค่าที่เกี่ยวข้องเป็นค่าต่อไปนี้:

  • บนเซิร์ฟเวอร์การพัฒนา

    • error_reportingควรตั้งค่าเป็นE_ALLมูลค่า
    • log_errors ควรตั้งค่าเป็น 1 (สะดวกในการบันทึกบนพีซีสำหรับการพัฒนาด้วย)
    • display_errors ควรตั้งค่าเป็น 1
  • บนเซิร์ฟเวอร์ที่ใช้งานจริง

    • error_reportingควรตั้งค่าเป็นE_ALLมูลค่า
    • log_errors ควรตั้งค่าเป็น 1
    • display_errors ควรตั้งค่าเป็น 0

ใช้งานจริงได้อย่างไร?

เพียง แต่เอารหัสใด ๆ ที่ตรวจสอบข้อผิดพลาดด้วยตนเองทุกคนor die(), if ($result)และเช่น เพียงเขียนรหัสโต้ตอบฐานข้อมูลของคุณทันที:

$stmt = $this->con->prepare("INSERT INTO table(name, quantity) VALUES (?,?)");
$stmt->bind_param("si", $name, $quantity);
$stmt->execute();

อีกครั้งโดยไม่มีเงื่อนไขใด ๆ รอบ ๆ หากข้อผิดพลาดเกิดขึ้นจะถือว่าเป็นข้อผิดพลาดอื่น ๆ ในโค้ดของคุณ ตัวอย่างเช่นบนพีซีสำหรับการพัฒนาจะปรากฏบนหน้าจอในขณะที่อยู่บนไซต์ที่ใช้งานจริงจะถูกบันทึกไว้สำหรับโปรแกรมเมอร์ในขณะที่เพื่อความสะดวกของผู้ใช้คุณสามารถใช้ตัวจัดการข้อผิดพลาด (แต่นั่นเป็นเรื่องที่แตกต่างออกไปซึ่งไม่อยู่ในหัวข้อสำหรับ MySQLi แต่คุณสามารถอ่านได้ในบทความที่เชื่อมโยงด้านบน)

จะทำอย่างไรกับข้อความแสดงข้อผิดพลาดที่คุณได้รับ

ก่อนอื่นคุณต้องค้นหาแบบสอบถามปัญหา ข้อความแสดงข้อผิดพลาดประกอบด้วยชื่อไฟล์และหมายเลขบรรทัดของจุดที่เกิดข้อผิดพลาด สำหรับโค้ดง่ายๆนั้นเพียงพอ แต่ถ้าโค้ดของคุณใช้ฟังก์ชันหรือคลาสคุณอาจต้องทำตามstack traceเพื่อค้นหาปัญหา

หลังจากได้รับข้อความแสดงข้อผิดพลาดคุณต้องอ่านและทำความเข้าใจ เสียงมันชัดเจนเกินไปหากไม่ได้วางตัว แต่ผู้เรียนมักจะมองข้ามความจริงที่ว่าเกิดข้อผิดพลาดไม่ได้เป็นเพียงสัญญาณเตือน แต่จริง ๆ แล้วมันมีคำอธิบายรายละเอียดของปัญหา และสิ่งที่คุณต้องมีคืออ่านข้อความแสดงข้อผิดพลาดและแก้ไขปัญหา

  • สมมติว่าถ้ามันบอกว่าไม่มีตารางใดตารางหนึ่งคุณต้องตรวจสอบตัวสะกดพิมพ์ผิดตัวพิมพ์เล็ก นอกจากนี้คุณต้องตรวจสอบให้แน่ใจว่าสคริปต์ PHP ของคุณเชื่อมต่อกับฐานข้อมูลที่ถูกต้อง
  • หรือหากระบุว่ามีข้อผิดพลาดในไวยากรณ์ SQL คุณต้องตรวจสอบ SQL ของคุณ และจุดปัญหาอยู่ก่อนส่วนของแบบสอบถามที่อ้างถึงในข้อความแสดงข้อผิดพลาด

หากคุณไม่เข้าใจข้อความแสดงข้อผิดพลาดให้ลองใช้ Google และเมื่อเรียกดูผลลัพธ์ให้ยึดตามคำตอบที่อธิบายข้อผิดพลาดแทนที่จะให้คำตอบอย่างตรงไปตรงมา วิธีแก้ปัญหาอาจใช้ไม่ได้ในกรณีของคุณ แต่คำอธิบายจะช่วยให้คุณเข้าใจปัญหาและทำให้คุณสามารถแก้ไขปัญหาได้ด้วยตัวเอง

คุณต้องเชื่อถือข้อความแสดงข้อผิดพลาดด้วย หากระบุว่าจำนวนโทเค็นไม่ตรงกับจำนวนตัวแปรที่ถูกผูกไว้แสดงว่าเป็นเช่นนั้น เช่นเดียวกับตารางหรือคอลัมน์ที่ขาดไป ให้ทางเลือกไม่ว่าจะเป็นความผิดพลาดของคุณเองหรือข้อความแสดงข้อผิดพลาดผิดให้ยึดติดกับอดีตเสมอ อีกครั้งดูเหมือนว่าจะน้อยไปมาก แต่คำถามหลายร้อยคำถามในเว็บไซต์นี้พิสูจน์ได้ว่าคำแนะนำนี้มีประโยชน์อย่างยิ่ง

รายการสิ่งที่คุณไม่ควรทำในเรื่องการรายงานข้อผิดพลาด

  • อย่าใช้ตัวดำเนินการปราบปรามข้อผิดพลาด ( @)! ทำให้โปรแกรมเมอร์ไม่สามารถอ่านข้อความแสดงข้อผิดพลาดและไม่สามารถแก้ไขข้อผิดพลาดได้
  • ห้ามใช้die()หรือechoหรือฟังก์ชันอื่นใดเพื่อพิมพ์ข้อความแสดงข้อผิดพลาดบนหน้าจอโดยไม่มีเงื่อนไข PHP สามารถรายงานข้อผิดพลาดได้ด้วยตัวเองและทำได้อย่างถูกต้องขึ้นอยู่กับสภาพแวดล้อมดังนั้นเพียงแค่ปล่อยให้ PHP
  • อย่าเพิ่มเงื่อนไขเพื่อทดสอบผลการสืบค้นด้วยตนเอง (เช่นif($result)) เมื่อเปิดใช้งานข้อผิดพลาดเงื่อนไขดังกล่าวจะไร้ประโยชน์
  • อย่าใช้try..catchตัวดำเนินการเพื่อสะท้อนข้อความแสดงข้อผิดพลาด ควรใช้โอเปอเรเตอร์นี้เพื่อจัดการข้อผิดพลาดบางอย่างเช่นการย้อนกลับธุรกรรม แต่อย่าใช้เพียงเพื่อรายงานข้อผิดพลาด - ดังที่เราได้เรียนรู้ไว้ข้างต้น PHP สามารถทำได้แล้วเป็นวิธีที่ถูกต้อง

ปล.
บางครั้งก็ไม่มี error แต่ก็ไม่มีผลลัพธ์เช่นกัน จากนั้นก็หมายความว่ามีข้อมูลในฐานข้อมูลเพื่อให้ตรงกับเกณฑ์ของคุณไม่มี ในกรณีนี้คุณต้องยอมรับความจริงนี้แม้ว่าคุณจะสามารถสาบานข้อมูลได้และเกณฑ์ก็ถูกต้องทั้งหมด พวกเขาจะไม่. คุณต้องตรวจสอบอีกครั้ง ฉันมีบทความที่สามารถช่วยในเรื่องนี้วิธีการปฏิสัมพันธ์ฐานข้อมูลการแก้ปัญหา แม้ว่าจะเขียนขึ้นสำหรับ PDO แต่หลักการก็เหมือนกัน เพียงทำตามคำแนะนำนี้ทีละขั้นตอนและแก้ไขปัญหาของคุณหรือมีคำถามที่ตอบได้สำหรับ Stack Overflow


@AdamWinter ที่ใช้ @ นั้นผิดเสมอและในกรณีนี้คือสิบเท่า ข้อความแสดงข้อผิดพลาดในโปรแกรมของคุณเหมือนกับความเจ็บปวดต่อร่างกายของคุณ เป็นการบอกคุณว่ามีบางอย่างผิดปกติเช่นขาของคุณหัก และคุณต้องแก้ไขขาไม่ใช่แค่กินยาแก้ปวดแล้วไปต่อ ที่นี่ PHP บอกคุณว่าไม่มีตัวแปรที่คุณคาดหวัง ดังนั้นคุณต้องแก้ไขฟอร์มหรืออะไรก็ตามเพื่อให้ตัวแปรนี้พร้อมใช้งาน ไม่ใช่แค่เขียนโค้ดเพื่อหลีกเลี่ยงข้อผิดพลาด
สามัญสำนึกของคุณ

ส่วนใหญ่ฉันเห็นด้วยอย่างไรก็ตาม 'สามัญสำนึกของคุณ' ฉันไม่เห็นด้วยกับ "ไม่ใช่แค่เขียนโค้ดเพื่อหลีกเลี่ยงข้อผิดพลาด" คุณคิดว่าการลอง ... จับทำอย่างไรมันจะหลีกเลี่ยงข้อผิดพลาดเพื่อป้องกันไม่ให้โค้ดเบสออก ในลักษณะที่ไม่มีการควบคุมข้อผิดพลาดบางอย่างที่คุณไม่สามารถแก้ไขได้ในเซิร์ฟเวอร์รหัส EG DB ได้หายไปแล้วคุณเพียงแค่ต้องจัดการข้อผิดพลาดและหลีกเลี่ยงข้อผิดพลาดเพื่อให้ได้ผลลัพธ์ที่ถูกต้อง
Barkermn01

@ Barkermn01 นั่นเป็นข้อกังวลที่เหมาะสมสำหรับคุณ แต่คุณกำลังสรุปข้อสรุปที่ไม่ถูกต้อง แน่นอนว่าแอปพลิเคชันของคุณควรให้ผลลัพธ์ที่ถูกต้อง (ซึ่งในกรณีของข้อผิดพลาด "Mysql หายไปแล้ว" ควรเป็นหน้าแสดงข้อผิดพลาดทั่วไป 500) แต่คุณต้องเข้าใจว่าเช่นผลที่ถูกต้องไม่กังวลของรหัสฐานข้อมูลของคุณ รหัสที่เกี่ยวข้องกับฐานข้อมูลของคุณควรทำงานร่วมกับฐานข้อมูล ในขณะที่การแสดงหน้าข้อผิดพลาดควรเป็นข้อกังวลเกี่ยวกับรหัสอื่น ดูที่นี่: phpdelusions.net/articles/error_reporting
สามัญสำนึกของคุณ

ฉันเข้าใจว่ามันเป็นเพียงสิ่งต่างๆเช่น 'แต่อย่าใช้เพียงเพื่อรายงานข้อผิดพลาด' มันประเภทของการกีดกันโค้ดเบสที่เป็นวัตถุประสงค์อย่างสมบูรณ์เช่น MVC ของฉันหากโมเดลของฉันพบข้อผิดพลาดที่ต้องจัดการกับข้อผิดพลาดจากนั้นให้ทำการสำรองข้อมูลดังนั้นคอนโทรลเลอร์ของฉัน โดยที่การใช้โมเดลถูกห่อไว้สามารถจัดการกับข้อผิดพลาดและนำเสนอข้อผิดพลาดได้ในกรณีนี้ฉันกำลังใช้มันเป็น API ดังนั้นข้อผิดพลาดและข้อมูลการติดตามทั้งหมดจะถูกส่งออกไปในการเรียก API หากมาจากระบบระยะไกลของเรา (Origin Verification ) เป็นเว็บจำนวนมากตอนนี้ PHP แบ็กเอนด์ REACT หรือ Angular Front end
Barkermn01

@ Barkermn01 โปรดอ่านบทความที่เชื่อมโยงอีกครั้ง ไม่ว่าจะด้วยวิธีใดฉันไม่รู้สึกว่านี่เป็นสถานที่ที่เหมาะสมสำหรับการสนทนาเช่นนี้ หากคุณมีคำถามเกี่ยวกับการรายงานข้อผิดพลาดโดยทั่วไปควรถามเป็นคำถามแยกต่างหาก ไชโย
สามัญสำนึกของคุณ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.