คอมพิวเตอร์ หน้าต่าง อินเทอร์เน็ต

ทำไมคุณควรใช้ PDO เพื่อทำงานกับฐานข้อมูล วิธีการทำงานกับ PDO? คู่มือฉบับสมบูรณ์ ตัวอย่าง Php pdo mysql

ฉันคิดว่าถึงเวลาแล้วที่จะยกระดับประสบการณ์ของฉันและเปลี่ยนจากฟังก์ชัน mysql_ เป็น PDO เมื่อทำงานกับฐานข้อมูล ไลบรารีนี้เป็นส่วนเสริมที่มีประสิทธิภาพและรวดเร็วสำหรับ PHP ข้อดีอย่างหนึ่งคือการทำงานกับฐานข้อมูลจำนวนมาก (MS SQL, MySQL, PostgreSQL, Oracle เป็นต้น) นอกจากนี้ คุณสมบัติที่โดดเด่นของไลบรารีนี้คือการแสดงออกที่เตรียมไว้ ซึ่งเรียกว่าคำสั่งที่เตรียมไว้ ซึ่งควรเพิ่มความเร็วในการทำงานกับฐานข้อมูล และที่สำคัญที่สุดคือ ทำให้การแลกเปลี่ยนข้อมูลปลอดภัยและลืมช่องโหว่เช่น sql-injection นอกจากนี้ยังมีคุณสมบัติอื่น ๆ ที่มีประโยชน์มาก ในบทความนี้ ฉันพยายามรวบรวมตัวอย่างงานที่ใช้กันทั่วไป ซึ่งคุณสามารถเข้าใจสาระสำคัญของวิธีการทำงานของ PDO ได้ทันที

PHP มีสามนามสกุล MySQL: mysql, mysqli และ PDO PHP PDO (PHP Data Objects) รวมอยู่ใน PHP 5.1 ขึ้นไป ตามที่ฉันเข้าใจแล้ว ในขณะนี้ ฟังก์ชันสำหรับการทำงานกับฐานข้อมูล mysql_ ไม่แนะนำให้ใช้ เนื่องจากการพัฒนา php_mysql หยุดที่การสนับสนุนฟังก์ชันการทำงานของ MySQL 4.1.3 และยังไม่รองรับธุรกรรม อินเทอร์เฟซวัตถุ และอาจมีช่องโหว่เมื่อแทนที่ค่าในแบบสอบถาม หลังจาก mysql_ มาถึงส่วนขยาย mysqli (MySQL ที่ปรับปรุงแล้วในเวอร์ชัน 5) ซึ่งรองรับคุณสมบัติใหม่ของ MySQL และใช้ทั้งไวยากรณ์ OPP และการเขียนโปรแกรมตามขั้นตอน ไลบรารีเหล่านี้ทั้งหมดใช้ไลบรารีไคลเอนต์ MySQL มาตรฐาน (libmysql) ในบันทึกเดียวกัน เราจะใช้ตัวอย่างจริงเพื่อดูว่าการทำงานกับ mysql ดำเนินการอย่างไรโดยใช้ส่วนขยายล่าสุด - สพป.

การเชื่อมต่อฐานข้อมูล PDO

//ตัวอย่างการเชื่อมต่อกับ MySQL โดยใช้ PDO $db = new PDO("mysql:host=localhost;dbname=test", $user, $pass);

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

หากมีข้อผิดพลาดในการเชื่อมต่อกลไกข้อยกเว้นจะทำงาน - PDOException คุณควรรวมการดำเนินการ PDO ไว้ในบล็อก try/catch เสมอ คุณสามารถตรวจจับข้อยกเว้นได้หากต้องการจัดการข้อผิดพลาด หรือปล่อยให้เป็นหน้าที่ของตัวจัดการข้อยกเว้นส่วนกลางที่คุณสร้างขึ้นด้วย set_exception_handler() PDO มีฟังก์ชันพิเศษสำหรับข้อผิดพลาด: errorCode() จะส่งคืนหมายเลขข้อผิดพลาด errorInfo() จะส่งคืนอาร์เรย์พร้อมหมายเลขข้อผิดพลาดและคำอธิบาย จำเป็นเนื่องจากโหมดข้อผิดพลาดเริ่มต้นคือ ERRMODE_SILENT ในกรณีนี้ หากต้องการดูข้อผิดพลาด คุณจะต้องโทรหา:

เสียงสะท้อน $conn->errorCode(); เสียงสะท้อน $conn->errorInfo();

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

ลอง ( $db = new PDO("mysql:host=$host;dbname=$dbname", $user, $password); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $db->exec("set names utf8"); ) catch(PDOException $e) ( echo $e->getMessage(); )

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

//ปิดการเชื่อมต่อ $db = null;

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

// การเชื่อมต่อถาวร $dbh = PDO ใหม่ ("mysql:host=localhost;dbname=test", $user, $pass, array(PDO::ATTR_PERSISTENT => จริง));

ตอนนี้คุณได้เห็นวิธีการเปิดและปิดการเชื่อมต่อแล้ว มาดูตัวอย่าง PDO อื่นๆ กัน ในกรณีนี้ ฉันจะแสดงวิธีสอบถามฐานข้อมูลเฉพาะ สามารถสร้างคำขอได้โดยใช้ 3 ฟังก์ชัน: exec(), query() และ prepare+execute

ผู้บริหาร()

อย่างแรกคือ exec จะส่งคืนเฉพาะจำนวนแถวที่เกี่ยวข้อง หรือ FALSE เมื่อเกิดข้อผิดพลาด และใช้ในกรณีที่ไม่มีการส่งคืนข้อมูล เช่น เมื่อทำการลบ:

// ใช้เมธอด exec() try( $db = new PDO("mysql:host=localhost;dbname=test","user","password"); $delrows=$db->exec("DELETE FROM users WHERE id>20"); echo "จำนวนแถวที่ถูกลบ: ".$delrows; ) catch(PDOException $e)( echo "Error: ".$e->getMessage(); exit (); ) //เพิ่มเติม $db->exec("ลบจากคนที่ 1"); //หรือ $db->exec("SET time_zone = "-8:00""); //หรือ $db->exec("CREATE TABLE `test`(id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20) NOT NULL DEFAULT "", email VARCHAR(50) NOT NULL DEFAULT "")"); //หรือ $db->exec("ชุดอักขระ SET utf8");

ข้อความค้นหา()

ประการที่สอง แบบสอบถาม () จะส่งคืนผลลัพธ์ในวัตถุ PDOStatement ส่งคืนผลลัพธ์หรือ FALSE เมื่อเกิดข้อผิดพลาด สามารถเชื่อถือได้ด้วยคำของ่ายๆ คุณสามารถใช้ query() กับเงื่อนไข (ฉันไม่รู้จริงๆว่าทำไมใครๆ ถึงต้องการมัน) แต่คุณยังต้องหลีกเลี่ยงข้อมูลโดยใช้เมธอด PDO::quote

// แบบสอบถามอย่างง่าย $db->query("SET CHARACTER SET utf8"); $db->query("เลือก * จากผู้ใช้"); //คุณสามารถคำนวณจำนวนแถว $stmt = $db->query("SELECT * FROM table"); $row_count = $stmt->rowCount(); echo $row_count" เลือกแถวแล้ว"; // ตัวเลือกอื่นที่มีจำนวนเงิน $stmt = $db->query("SELECT * from users"); $rows = $stmt->fetchAll(); $count = นับ ($ แถว); foreach($rows as $row) ( print_r($row); ) // สืบค้นด้วยเงื่อนไขและหลีก $conn->query("SELECT * FROM table WHERE id = " . $conn->quote($id));

LastInsertId()ส่งคืน ID ของแถวฐานข้อมูลที่แทรกล่าสุด

//lastInsertId() วิธีการส่งกลับ id ของบันทึกล่าสุด $db->query("INSERT INTO users SET name="Vasya",address="Here",email=" [ป้องกันอีเมล]""); $insertId=$db->lastInsertId();

งบที่เตรียมไว้ - งบที่เตรียมไว้

วิธีที่สาม - เตรียม + ดำเนินการ - การแสดงออกที่เตรียมไว้เป็นคำแนะนำที่เตรียมไว้ และยังเป็นตัวยึดตำแหน่งอีกด้วย แถลงการณ์ที่เตรียมไว้หรือผูกตัวแปร ให้คุณกำหนดนิพจน์หนึ่งครั้งแล้วดำเนินการหลายครั้งด้วยพารามิเตอร์ที่แตกต่างกัน นอกจากนี้ยังอนุญาตให้แยกตัวแปรออกจากคิวรี ซึ่งทำให้โค้ดปลอดภัยยิ่งขึ้นและเพิ่มความเร็วในการดำเนินการ รหัสของคุณไม่จำเป็นต้องพยายามล้างข้อมูลที่ส่งอีกต่อไป เราจะทำเช่นนี้เพียงครั้งเดียวก่อนที่จะดำเนินการสืบค้นฐานข้อมูล สำหรับสิ่งนี้เราใช้ฟังก์ชัน เตรียมตัว(); ใช้การสืบค้น SQL เป็นพารามิเตอร์ แต่ในนั้นแทนที่จะใช้ตัวแปร จะใช้ป้ายกำกับในรูปแบบของเครื่องหมายคำถาม '?' หรือตัวเลข ':1' หรือตัวแปรที่มีชื่อขึ้นต้นด้วยเครื่องหมายทวิภาค ':' หากคุณหยุดที่เครื่องหมายคำถาม (: ตัวเลข) คุณต้องส่งอาร์เรย์ของค่าในลำดับที่เหมาะสมไปยังฟังก์ชันดำเนินการ หากตัวเลือกของคุณมีชื่อว่าตัวแปร คุณจะต้องกำหนดค่าให้กับตัวแปรแต่ละตัวผ่านหนึ่งในสองฟังก์ชัน: bindValue() ซึ่งจะกำหนดค่าให้กับตัวแปรเทียม หรือ bindParam() ซึ่งผูกตัวแปรหลอกกับตัวแปรจริง พารามิเตอร์ที่สามสามารถเป็นประเภทตัวแปรได้ เช่น $db->bindParam(':id',$id, PDO::PARAM_INT)

// ป้ายชื่อที่ไม่มีชื่อ try ( $stmt = $db->prepare("INSERT INTO test (label,color) VALUES (?,?)"); $stmt -> execute(array("perfect","green")); ) catch(PDOException $e)( echo "Error: ".$e->getMessage(); exit(); ) //stmt is a "state descriptor" // Named labels $stmt = $ db->prepare("INSERT INTO test (label,color) VALUES (:label,:color)"); $stmt -> execute(array("label"=>"perfect", "color"=>"green")); //ตัวเลือกอื่น $stmt = $db->prepare("INSERT INTO users (firstname, lastname, email) VALUES (:firstname, :lastname, :email)"); $stmt->bindParam(":ชื่อแรก", $ชื่อแรก); $stmt->bindParam(":lastname", $lastname); $stmt->bindParam(":email", $email); $ชื่อ = "จอห์น"; $lastname = "สมิธ"; $อีเมล = " [ป้องกันอีเมล]"; $stmt->ดำเนินการ ();

ฉันขอเตือนคุณอีกครั้งว่าหากคุณไม่ได้ใช้นิพจน์ที่เตรียมไว้ แต่ยังต้องการรักษาความปลอดภัยของข้อมูลที่ส่ง สามารถทำได้โดยใช้ฟังก์ชัน PDO:quote

PDO เลือกข้อมูล

เมธอด fetch() หรือ fetchAll() ใช้เพื่อดึงข้อมูล ก่อนเรียกใช้ฟังก์ชัน คุณต้องบอก PDO ว่าคุณจะได้รับข้อมูลจากฐานข้อมูลอย่างไร PDO::FETCH_ASSOC จะคืนค่าแถวเป็นอาร์เรย์เชื่อมโยงที่มีชื่อฟิลด์เป็นคีย์ PDO::FETCH_NUM จะคืนค่าสตริงเป็นอาร์เรย์ตัวเลข ตามค่าเริ่มต้น การดึงข้อมูลจะเกิดขึ้นกับ PDO::FETCH_BOTH ซึ่งจะทำซ้ำข้อมูลที่มีทั้งคีย์ตัวเลขและคีย์เชื่อมโยง ดังนั้นขอแนะนำให้ระบุวิธีเดียวเพื่อไม่ให้มีอาร์เรย์ซ้ำกัน:

$stmt = $db->query("เลือก * จากผู้ใช้"); //ตั้งค่าโหมดดึงข้อมูล $stmt->setFetchMode(PDO::FETCH_ASSOC); ในขณะที่ ($row = $stmt->ดึงข้อมูล ()) ( echo "

" . $row["firstname"] . " " . $row["lastname"] . "

";ก้อง"

" .$row["อีเมล"] "


"; }

หรือคุณสามารถระบุวิธีการดึงข้อมูลในวิธีการ ->fetch() เอง

$stmt = $db->query("เลือก * จากตาราง"); while($row = $stmt->fetch(PDO::FETCH_ASSOC)) ( echo $row["field1"]." ".$row["field2"]; //etc... ) //Attention ไม่ทำงานกับ LIKE! $stmt = $db->prepare("เลือกฟิลด์จากตารางที่ฟิลด์ LIKE %?%"); $stmt->bindParam(1, $ค้นหา, PDO::PARAM_STR); $stmt->ดำเนินการ (); // ต้องการดังนี้ $stmt = $db->prepare("SELECT field FROM table WHERE field LIKE ?"); $stmt->bindValue(1, "%$search%", PDO::PARAM_STR); $stmt->ดำเนินการ (); //อีกตัวอย่างหนึ่ง $stmt = $db->prepare("SELECT * FROM table WHERE id=? AND name=?"); $stmt->bindValue(1, $id, PDO::PARAM_INT); $stmt->bindValue(2, $ชื่อ, PDO::PARAM_STR); $stmt->ดำเนินการ (); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); // ตัวเลือกอื่น $stmt = $db->prepare("เลือก * จากผู้ใช้"); $stmt -> ดำเนินการ (); ในขณะที่($row = $stmt->ดึงข้อมูล()) ( print_r($row); )

ข้อมูลการปรับปรุง PDO

มันเกิดขึ้นในลักษณะเดียวกับ INSERT และ SELECT (ในกรณีนี้ เราจะใช้ตัวยึดตำแหน่งที่มีชื่ออีกครั้ง):

$stmt = $db->prepare("UPDATE users set email = :email where lastname=:lastname"); $stmt->bindParam(":lastname", $lastname); $stmt->bindParam(":email", $email); $lastname = "สมิธ"; $อีเมล = " [ป้องกันอีเมล]"; $stmt->ดำเนินการ ();

ลบการกำจัดทำได้ด้วยวิธีที่ง่ายที่สุด:

$db->exec("ลบผู้ใช้");

แน่นอน คุณยังสามารถใช้พารามิเตอร์ที่มีชื่อ (ตัวยึดตำแหน่ง) เมื่อทำการลบ

หากคุณมีช่องว่างที่ใช้บ่อยเมื่อทำงานกับส่วนขยาย PHP PDO ฉันจะขอบคุณถ้าคุณแบ่งปัน เชื่อมโยงไปยังคู่มือ

หากคุณมีข้อผิดพลาด Undefined variable: DBH ... คุณสามารถอ่านวิธีแก้ไขได้

Google ช่วยค้นหาข้อมูลสรุปเกี่ยวกับ PDO อาจมีประโยชน์สำหรับใครบางคน:

เมตาแท็ก (5)

บางครั้งฉันเห็นคำถามเกี่ยวกับการเชื่อมต่อกับฐานข้อมูล
คำตอบส่วนใหญ่ไม่ใช่วิธีที่ฉันทำ หรือฉันแค่ตอบไม่ถูก ถึงอย่างไร; ฉันไม่เคยคิดเกี่ยวกับเรื่องนี้เพราะวิธีที่ฉันทำมันได้ผลสำหรับฉัน

แต่นี่เป็นความคิดที่บ้า บางทีฉันอาจทำผิดทั้งหมด และถ้าใช่; ฉันต้องการทราบวิธีเชื่อมต่อกับฐานข้อมูล MySQL ด้วย PHP และ PDO อย่างถูกต้องและทำให้พร้อมใช้งาน

นี่คือวิธีที่ฉันทำ:

ก่อนอื่น นี่คือโครงสร้างไฟล์ของฉัน (ตัดลง) :

Public_html/ * index.php * initialize/ -- load.initialize.php -- configuration.php -- sessions.php

index.php
ที่ด้านบนสุดฉันต้องการ ("initialize/load.initialize.php"); ,

load.initialize.php

# ต้องมีการกำหนดค่าไซต์ ("configure.php"); # ต้องการเชื่อมต่อกับฐานข้อมูล ("root/somewhere/connect.php"); // ไฟล์นี้ถูกวางไว้นอก public_html เพื่อความปลอดภัยที่ดียิ่งขึ้น # รวมคลาส foreach (glob("assets/classes/*.class.php") เป็น $class_filename)( รวม($class_filename); ) # รวมฟังก์ชัน foreach (glob("assets/functions/*.func.php") เป็น $func_filename)( รวม($func_filename); ) # จัดการเซสชันต้องการ("sessions.php");

ฉันรู้ว่ามีวิธีที่ดีกว่าหรือถูกต้องกว่าในการรวมชั้นเรียน แต่ฉันจำไม่ได้ว่ามันคืออะไร ยังไม่มีเวลาตรวจสอบ แต่ฉันคิดว่ามันเป็นสิ่งที่มี autoload อะไรแบบนั้น...

configuration.php
ที่นี่ฉันแค่แทนที่บางส่วน php.iniคุณสมบัติและทำการตั้งค่าส่วนกลางอื่น ๆ สำหรับไซต์

connect.php
ฉันได้ตั้งค่าการเชื่อมต่อกับคลาสเพื่อให้คลาสอื่นสามารถ ขยายนี้...

คลาส connect_pdo ( ป้องกัน $dbh; ฟังก์ชันสาธารณะ __construct () ( ลอง ( $db_host = " "; // ชื่อโฮสต์ $db_name = " "; // ชื่อฐานข้อมูล $db_user = " "; // ชื่อผู้ใช้ $user_pw = " "; // รหัสผ่าน $con = new PDO("mysql:host=".$db_host."; dbname=".$db_name, $db_user, $user_pw); $con->set Attribu te(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $con->exec("SET CHARACTER SET utf8"); // ส่งคืนคำขอ sql ทั้งหมดเป็น UTF-8 ) catch (PDOException $err) ( echo "ข้อความแสดงข้อผิดพลาดที่ไม่เป็นอันตรายหากการเชื่อมต่อล้มเหลว"; $err->getMessage() "
"; file_put_contents("PDOErrors.txt",$err, FILE_APPEND); // เขียนรายละเอียดบางอย่างไปยังบันทึกข้อผิดพลาดนอก public_html die(); // ยุติการเชื่อมต่อ ) ) public function dbh() ( return $this->dbh; ) ) # ใส่ตัวจัดการฐานข้อมูลลงใน var เพื่อการเข้าถึงที่ง่ายขึ้น $con = new connect_pdo(); $con = $con->dbh(); //

นี่คือที่ที่ฉันเชื่อว่ามีที่ว่างสำหรับการปรับปรุงครั้งใหญ่ เพราะฉันเพิ่งเริ่มเรียนรู้ OOP และใช้ PDO แทน mysql
ดังนั้นฉันจึงทำตามบทช่วยสอนสำหรับผู้เริ่มต้นสองสามข้อและลองทำสิ่งต่าง ๆ...

sessions.php
นอกเหนือจากการจัดการเซสชันปกติแล้ว ฉันยังเริ่มต้นคลาสบางคลาสในเซสชันในลักษณะนี้:

ถ้า (!isset($_SESSION["sqlQuery"]))( session_start(); $_SESSION["sqlQuery"] = new sqlQuery(); )

ดังนั้นคลาสนี้จึงมีอยู่ทุกที่ มันอาจจะไม่ใช่แนวปฏิบัติที่ดี (?)...
อย่างไรก็ตาม นี่คือสิ่งที่วิธีนี้ช่วยให้ฉันทำได้ทุกที่:

Echo $_SESSION["sqlQuery"]->getAreaName("เขต",9); // เอาต์พุต: Aust-Agder (ชื่อเคาน์ตีที่มีรหัสนั้นในฐานข้อมูล)

ข้างในของฉัน ระดับ sqlQuery ซึ่งขยายของฉัน ระดับ connect_pdo ฉันมีฟังก์ชันสาธารณะ getAreaName ที่จัดการคำขอในฐานข้อมูลของฉัน
ฉันคิดว่าค่อนข้างเรียบร้อย

ทำงานเหมือนจับใจ
นั่นคือวิธีที่ฉันทำ
นอกจากนี้ เมื่อใดก็ตามที่ฉันต้องการดึงข้อมูลบางอย่างจากฐานข้อมูลจากคลาส ฉันแค่ทำสิ่งที่คล้ายกันนี้:

$id = 123; $sql = "เลือกอะไรก็ได้จาก MyTable โดยที่ id = :id"; $qry = $con->เตรียม($sql); $qry -> bindParam(":id", $id, PDO::PARAM_INT); $qry -> ดำเนินการ (); $get = $qry->ดึงข้อมูล (PDO::FETCH_ASSOC);

เนื่องจากฉันกำลังแทรกการเชื่อมต่อลงในตัวแปรภายใน connect_pdo.phpฉันแค่อ้างถึงมันและฉันก็พร้อมที่จะไป มันได้ผล. ฉันได้รับผลลัพธ์ที่คาดหวัง ...

แต่ไม่ว่า; ฉันจะขอบคุณมากถ้าพวกคุณช่วยบอกฉันว่าฉันออกไปจากที่นี่แล้ว แต่ฉันจะต้องเปลี่ยนด้านที่ฉันทำได้หรือควรเปลี่ยนเพื่อปรับปรุง ฯลฯ ...

อยากเรียนมากๆ...

คำตอบ

$dsn = "mysql:host=your_host_name;dbname=your_db_name_here"; // กำหนดชื่อโฮสต์และชื่อฐานข้อมูล $username = "คุณ"; // กำหนดชื่อผู้ใช้ $pwd="your_password"; // รหัสผ่านลอง ( $db = new PDO($dsn, $username, $pwd); ) catch (PDOException $e) ( $error_message = $e->getMessage(); echo "สิ่งนี้ปรากฏขึ้นเนื่องจากพบข้อผิดพลาด"; exit(); )

ฉันเพิ่งได้รับคำตอบ / คำถามที่คล้ายกันด้วยตัวเอง นี่คือสิ่งที่ฉันทำในกรณีที่ใครสนใจ:

หาเรื่อง = func_get_args (); ) ฟังก์ชันสาธารณะ __call($method, $args) ( if (empty($this->db)) ( $Ref = new \ReflectionClass("\PDO"); $this->db = $Ref->newInstanceArgs($this->args); ) return call_user_func_array(array($this->db, $method), $args); ) )

หากต้องการโทร คุณต้องเปลี่ยนบรรทัดนี้เท่านั้น:

$DB = new \Library\PDO(/* อาร์กิวเมนต์ปกติ */);

และพิมพ์คำใบ้หากคุณใช้ (\Library\PDO$DB)

สิ่งนี้คล้ายกับคำตอบที่ยอมรับและของคุณ อย่างไรก็ตามมันมีข้อได้เปรียบที่สำคัญ พิจารณารหัสนี้:

$DB = ใหม่ \Library\PDO(/* หาเรื่อง */); $STH = $DB->prepare("เลือก * จากผู้ใช้ โดยที่ผู้ใช้ = ?"); $STH->ดำเนินการ (อาร์เรย์ (25)); $User = $STH->ดึงข้อมูล ();

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

ฉันขอแนะนำไม่ให้ใช้ $_SESSION เพื่อเข้าถึงการเชื่อมต่อฐานข้อมูลของคุณทั่วโลก

คุณสามารถทำอย่างใดอย่างหนึ่งได้หลายอย่าง (ตามลำดับ แย่ที่สุดสำหรับสิ่งที่ดีที่สุดผู้ปฏิบัติงาน):

  • การเข้าถึง $dbh โดยใช้ global $dbh ภายในฟังก์ชันและคลาสของคุณ
  • ใช้ singleton Registry และเข้าถึงได้ทั่วโลก เช่น:

    $registry = MyRegistry::getInstance(); $dbh = $registry->getDbh();

    แนะนำตัวจัดการฐานข้อมูลในคลาสที่ต้องการ:

    คลาส MyClass ( ฟังก์ชันสาธารณะ __construct($dbh) ( /* ... */ ) )

อย่างไรก็ตาม เป็นขั้นสูงกว่าเล็กน้อยและต้องการ "การเดินสาย" มากขึ้นโดยไม่ต้องใช้กรอบ ดังนั้น หากการพึ่งพาอาศัยกันยากเกินไปสำหรับคุณ ให้ใช้ singleton Registry แทนการรวบรวมตัวแปรส่วนกลาง

เป้า

อย่างที่ฉันเห็น เป้าหมายของคุณในกรณีนี้มีสองเท่า:

  • สร้างและรักษาการเชื่อมต่อเดี่ยว/หลายต่อฐานข้อมูล
  • ตรวจสอบให้แน่ใจว่าได้ตั้งค่าการเชื่อมต่ออย่างถูกต้อง

สารละลาย

$provider = function() ( $instance = new PDO("mysql:......;charset=utf8", "username", "password"); $instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $instance->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); return $instance; ); $factory = โครงสร้างโรงงานใหม่ (ผู้ให้บริการ $);

จากนั้นในไฟล์อื่นหรือด้านล่างในไฟล์เดียวกัน:

$something = $factory->create("บางสิ่ง"); $foobar = $factory->create("ฟูบาร์");

โรงงานควรมีลักษณะดังนี้:

โครงสร้างคลาสโรงงาน ( ป้องกัน $provider = null; ป้องกัน $connection = null; ฟังก์ชันสาธารณะ __construct(เรียก $ผู้ให้บริการ) ( $this->provider = $provider; ) สร้างฟังก์ชันสาธารณะ ($name) ( ถ้า ($this->connection === null) ( $this->connection = call_user_func($this->provider); ) คืนค่าใหม่ $name($this->connection); ) )

วิธีนี้ทำให้คุณสามารถมีโครงสร้างแบบรวมศูนย์ที่รับรองว่าการเชื่อมต่อจะถูกสร้างขึ้นเมื่อจำเป็นเท่านั้น นอกจากนี้ยังทำให้ง่ายต่อการทดสอบหน่วยและบำรุงรักษา PHP และโค้ดนี้เพื่อเพิ่มแบ็กสแลชให้กับอักขระต่อไปนี้: \x00 , \n , \r , \ , " , " และ \x1a ส่งผ่านค่าอินพุตเป็นพารามิเตอร์เพื่อลดโอกาสในการฉีด SQL

  • วิธีที่ทันสมัยที่สุดคือการใช้ PDO
  • ฉันหวังว่านี่จะช่วยคุณได้

    พิจารณาแบบสอบถามต่อไปนี้:

    $iId = mysql_real_escape_string("1 หรือ 1=1"); $sql = "เลือก * จากตาราง WHERE id = $iId";

    mysql_real_escape_string() จะไม่ป้องกันที่นี่ หากคุณใช้เครื่องหมายอัญประกาศเดี่ยว ("") รอบตัวแปรของคุณภายในข้อความค้นหา นั่นคือสิ่งที่ป้องกันคุณจากตัวแปรนั้น นี่คือวิธีแก้ปัญหาด้านล่าง:

    $iId = (int) mysql_real_escape_string("1 หรือ 1=1"); $sql = "เลือก * จากตาราง WHERE id = $iId";

    คำถามนี้มีคำตอบที่ดี

    ฉันแนะนำว่าการใช้ PDO เป็นตัวเลือกที่ดีที่สุด

    แก้ไข:

    mysql_real_escape_string() เลิกใช้แล้วตั้งแต่ PHP 5.5.0 ใช้ mysqli หรือ PDO อย่างใดอย่างหนึ่ง

    อีกทางเลือกหนึ่งสำหรับ mysql_real_escape_string() คือ

    สตริง mysqli_real_escape_string (mysqli $link , สตริง $escapestr)

    ตัวอย่าง:

    $iId = $mysqli->real_escape_string("1 หรือ 1=1"); $mysqli->query("เลือก * จากตาราง WHERE id = $iId");

    • แปล

    นักพัฒนา PHP หลายคนคุ้นเคยกับการใช้ส่วนขยาย mysql และ mysqli เพื่อทำงานกับฐานข้อมูล แต่เนื่องจากเวอร์ชัน 5.1 ใน PHP มีวิธีที่สะดวกกว่า - PHP Data Objects คลาสนี้เรียกโดยย่อว่า PDO มีวิธีการทำงานกับออบเจกต์และคำสั่งที่เตรียมไว้ซึ่งจะช่วยเพิ่มประสิทธิภาพการทำงานของคุณอย่างมาก!

    ความรู้เบื้องต้นเกี่ยวกับ PDO

    "PDO - PHP Data Objects เป็นเลเยอร์ที่ให้วิธีที่หลากหลายในการทำงานกับฐานข้อมูลหลายฐานข้อมูล"

    มันทิ้งความกังวลเกี่ยวกับไวยากรณ์ของ DBMS ที่แตกต่างกันให้กับนักพัฒนา แต่ทำให้กระบวนการสลับระหว่างแพลตฟอร์มเจ็บปวดน้อยลงมาก บ่อยครั้งที่จำเป็นต้องเปลี่ยนสตริงการเชื่อมต่อฐานข้อมูลเท่านั้น


    บทความนี้เขียนขึ้นสำหรับผู้ที่ใช้ mysql และ mysqli เพื่อช่วยในการโยกย้ายไปยัง PDO ที่มีประสิทธิภาพและยืดหยุ่นมากขึ้น

    รองรับ DBMS

    ส่วนขยายนี้สามารถรองรับระบบการจัดการฐานข้อมูลใด ๆ ที่มีไดรเวอร์ PDO อยู่ ในขณะที่เขียน มีไดรเวอร์ดังต่อไปนี้:
    • PDO_CUBRID(คิวบริด)
    • PDO_DBLIB (FreeTDS/Microsoft SQL Server/Sybase)
    • PDO_FIREBIRD (ไฟร์เบิร์ด/อินเตอร์เบส 6)
    • PDO_IBM (ไอบีเอ็ม DB2)
    • PDO_INFORMIX (IBM Informix Dynamic Server)
    • PDO_MYSQL (มายเอสคิวแอล 3.x/4.x/5.x)
    • PDO_OCI (อินเทอร์เฟซการโทรของ Oracle)
    • PDO_ODBC (ODBC v3 (IBM DB2, unixODBC และ win32 ODBC))
    • PDO_PGSQL (โพสต์เกรสคิวแอล)
    • PDO_SQLITE (SQLite 3 และ SQLite 2)
    • PDO_SQLSRV (เซิร์ฟเวอร์ Microsoft SQL)
    • PDO_4D (4D)
    อย่างไรก็ตาม ไม่ใช่ทั้งหมดที่อยู่ในเซิร์ฟเวอร์ของคุณ คุณสามารถดูรายการไดรเวอร์ที่มีอยู่ดังนี้:
    print_r(PDO::getAvailableDrivers());

    การเชื่อมต่อ

    วิธีเชื่อมต่อกับ DBMS ต่างๆ อาจแตกต่างกันเล็กน้อย ด้านล่างนี้เป็นตัวอย่างของการเชื่อมต่อกับรายการยอดนิยมของพวกเขา คุณจะเห็นว่าสามรายการแรกมีไวยากรณ์เหมือนกัน ไม่เหมือน SQLite
    ลอง ( # MS SQL Server และ Sybase ผ่าน PDO_DBLIB $DBH = new PDO("mssql:host=$host;dbname=$dbname", $user, $pass); $DBH = new PDO("sybase:host=$host;dbname=$dbname", $user, $pass); # MySQL ผ่าน PDO_MYSQL $DBH = new PDO("mysql:host=$host;dbname=$dbname", $ ผู้ใช้ $pass); # SQLite $DBH = PDO ใหม่ ("sqlite:my/database/path/database.db"); ) catch(PDOException $e) ( echo $e->getMessage(); )
    โปรดให้ความสนใจกับบล็อก try/catch - คุณควรรวมการดำเนินการ PDO ทั้งหมดของคุณไว้ในนั้นเสมอ และใช้กลไกข้อยกเว้น (เพิ่มเติมในภายหลัง)

    $DBH ย่อมาจาก "database handle" และจะใช้ตลอดทั้งบทความนี้

    คุณสามารถปิดการเชื่อมต่อใดๆ ได้โดยกำหนดตัวแปรใหม่เป็น null
    # ปิดการเชื่อมต่อ $DBH = null;
    ดูข้อมูลเพิ่มเติมเกี่ยวกับหัวข้อตัวเลือก DBMS ต่างๆ และวิธีการเชื่อมต่อได้ที่ php.net

    ข้อยกเว้นและ PDO

    PDO รู้วิธีส่งข้อยกเว้นข้อผิดพลาด ดังนั้นทุกอย่างควรอยู่ในบล็อก try/catch เมื่อสร้างการเชื่อมต่อแล้ว PDO สามารถเข้าสู่โหมดข้อผิดพลาดสามโหมด:
    $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    แต่ควรสังเกตว่าข้อผิดพลาดเมื่อพยายามเชื่อมต่อจะทำให้เกิดข้อยกเว้นเสมอ

    PDO::ERRMODE_SILENT

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

    PDO::ERRMODE_WARNING

    โหมดนี้จะทำให้เกิดคำเตือนมาตรฐานและอนุญาตให้สคริปต์ทำงานต่อไป สะดวกสำหรับการดีบัก

    PDO::ERRMODE_EXCEPTION

    ในสถานการณ์ส่วนใหญ่ ควรใช้การควบคุมการดำเนินการสคริปต์ประเภทนี้ มันโยนข้อยกเว้นซึ่งช่วยให้คุณจัดการข้อผิดพลาดได้อย่างสง่างามและซ่อนข้อมูลที่ละเอียดอ่อน ตัวอย่างเช่นที่นี่:
    # เชื่อมต่อกับฐานข้อมูล ลอง ( $DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); # ให้ตายเถอะ ฉันพิมพ์ DELECT แทน SELECT! $DBH->prepare("DELECT name FROM people")->execute(); ) catch( ข้อยกเว้น PDO $e) ( echo "ฮุสตัน เรากำลังมีปัญหา"; file_put_contents("PDOErrors.txt", $e->getMessage(), FILE_APPEND); )
    มีข้อผิดพลาดทางไวยากรณ์ในคำสั่ง SQL ซึ่งจะทำให้เกิดข้อยกเว้น เราสามารถบันทึกรายละเอียดของข้อผิดพลาดในไฟล์บันทึกและบอกใบ้กับผู้ใช้เป็นภาษามนุษย์ว่ามีบางอย่างเกิดขึ้น

    แทรกและอัปเดต

    การแทรกข้อมูลใหม่และการอัปเดตข้อมูลที่มีอยู่เป็นหนึ่งในการดำเนินการฐานข้อมูลทั่วไป ในกรณีของ PDO กระบวนการนี้มักประกอบด้วยสองขั้นตอน (ในหัวข้อถัดไป ทุกอย่างใช้กับทั้ง UPDATE และ INSERT)


    ตัวอย่างเล็กน้อยของการแทรกข้อมูลใหม่:
    # STH หมายถึง "ตัวจัดการคำสั่ง" $STH = $DBH->prepare("INSERT INTO folks (first_name) value ("Cathy")"); $STH->ดำเนินการ ();
    คุณสามารถทำเช่นเดียวกันได้ด้วย exec() เมธอดเดียว แต่เมธอดแบบสองขั้นตอนให้ประโยชน์ทั้งหมดของข้อความที่เตรียมไว้ พวกมันช่วยป้องกันการฉีด SQL ดังนั้นจึงเหมาะสมที่จะใช้พวกมันแม้จะมีคำขอเดียว

    แถลงการณ์ที่เตรียมไว้

    การใช้คำสั่งที่เตรียมไว้จะเสริมการป้องกันการแทรก SQL

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

    ด้านล่างนี้คือสามตัวอย่างข้อความที่เตรียมไว้
    # ไม่มีตัวยึด - ประตูสู่การฉีด SQL เปิดอยู่! $STH = $DBH->prepare("INSERT INTO people (ชื่อ, addr, เมือง) ค่า ($name, $addr, $city)"); # ตัวยึดตำแหน่งที่ไม่มีชื่อ $STH = $DBH->prepare("INSERT INTO folks (name, addr, city) value (?, ?, ?)"); # ตัวยึดตำแหน่งที่มีชื่อ $STH = $DBH->prepare("INSERT INTO folks (name, addr, city) value (:name, :addr, :city)");
    ตัวอย่างแรกเป็นเพียงการเปรียบเทียบและควรหลีกเลี่ยง ความแตกต่างระหว่างตัวยึดตำแหน่งที่ไม่มีชื่อและชื่อคือวิธีที่คุณส่งข้อมูลไปยังข้อความที่เตรียมไว้

    ตัวยึดตำแหน่งที่ไม่มีชื่อ

    # กำหนดตัวแปรให้กับแต่ละ placeholder, indexed 1 ถึง 3 $STH->bindParam(1, $name); $STH->bindParam(2, $addr); $STH->bindParam(3, $เมือง); # ใส่หนึ่งบรรทัด $name = "Daniel" $addr = "1 Wicked Way"; $city = "อาร์ลิงตัน ไฮท์"; $STH->ดำเนินการ (); # แทรกแถวอื่นที่มีข้อมูลต่างกัน $name = "Steve" $addr = "5 Circle Drive"; $city = "ชอมเบิร์ก"; $STH->ดำเนินการ ();
    มีสองขั้นตอนที่นี่ ในอันแรก เรากำหนดตัวแปรให้กับตัวยึดตำแหน่งทั้งหมด (บรรทัดที่ 2-4) จากนั้นเรากำหนดค่าให้กับตัวแปรเหล่านี้และดำเนินการค้นหา หากต้องการส่งข้อมูลชุดใหม่ เพียงเปลี่ยนค่าของตัวแปรและเรียกใช้คำขออีกครั้ง

    หากนิพจน์ SQL ของคุณมีพารามิเตอร์จำนวนมาก การกำหนดตัวแปรให้แต่ละตัวนั้นไม่สะดวกอย่างยิ่ง ในกรณีเช่นนี้ คุณสามารถจัดเก็บข้อมูลในอาร์เรย์และส่งต่อ:
    # ชุดข้อมูลที่เราจะใส่ $data = array("Cathy", "9 Dark and Twisty Road", "Cardiff"); $STH = $DBH->prepare("INSERT INTO people (ชื่อ, addr, เมือง) ค่า (?, ?, ?)"); $STH->execute($data);
    $data จะถูกแทรกแทนที่ตัวยึดตำแหน่งแรก $data แทนที่ตัวที่สอง และอื่นๆ แต่ระวัง: หากดัชนีของคุณล้มลง สิ่งนี้จะไม่ทำงาน

    ตัวยึดตำแหน่งที่กำหนด

    # อาร์กิวเมนต์แรกคือชื่อของตัวยึดตำแหน่ง # เป็นเรื่องปกติที่จะเริ่มต้นด้วยเครื่องหมายทวิภาค # แม้ว่าจะใช้งานได้หากไม่มี $STH->bindParam(":name", $name);
    ที่นี่คุณสามารถส่งอาร์เรย์ได้ แต่ต้องเชื่อมโยง บทบาทของคีย์ควรเป็นชื่อของตัวยึดตามที่คุณคาดเดา
    # ข้อมูลที่เราใส่ $data = array("name" => "Cathy", "addr" => "9 Dark and Twisty", "city" => "Cardiff"); $STH = $DBH->prepare("INSERT INTO people (ชื่อ, addr, เมือง) ค่า (:name, :addr, :city)"); $STH->execute($data);
    ความสะดวกอย่างหนึ่งของการใช้ตัวยึดตำแหน่งที่มีชื่อคือความสามารถในการแทรกวัตถุลงในฐานข้อมูลโดยตรง หากชื่อคุณสมบัติตรงกับชื่อพารามิเตอร์ ตัวอย่างเช่น การแทรกข้อมูล คุณสามารถทำได้:
    # คลาสสำหรับคลาสอ็อบเจกต์อย่างง่าย ( public $name; public $addr; public $city; function __construct($n,$a,$c) ( $this->name = $n; $this->addr = $a; $this->city = $c; ) # etc... ) $cathy = new person("Cathy","9 Dark and Twisty","Cardiff"); # และนี่คือส่วนที่สนุก $STH = $DBH->prepare("INSERT INTO folks (name, addr, city) values ​​(:name, :addr, :city)"); $STH->execute((อาร์เรย์)$cathy);
    การแปลงวัตถุเป็นอาร์เรย์บน execute() ทำให้คุณสมบัติถูกปฏิบัติเหมือนเป็นคีย์อาร์เรย์

    การสุ่มตัวอย่างข้อมูล



    สามารถดึงข้อมูลได้โดยใช้เมธอด ->fetch() ก่อนที่จะโทรขอแนะนำให้ระบุรูปแบบที่คุณต้องการอย่างชัดเจน มีหลายตัวเลือก:
    • PDO::FETCH_ASSOC:ส่งคืนอาร์เรย์ที่มีชื่อคอลัมน์เป็นคีย์
    • PDO::FETCH_BOTH (ค่าเริ่มต้น):ส่งคืนอาร์เรย์พร้อมดัชนีทั้งในรูปแบบของชื่อคอลัมน์และเลขลำดับ
    • PDO::FETCH_BOUND:กำหนดค่าของคอลัมน์ให้กับตัวแปรที่เกี่ยวข้องซึ่งตั้งค่าด้วยเมธอด ->bindColumn()
    • PDO::FETCH_CLASS:กำหนดค่าของคอลัมน์ให้กับคุณสมบัติที่สอดคล้องกันของคลาสที่ระบุ หากไม่มีคุณสมบัติสำหรับบางคอลัมน์ จะถูกสร้างขึ้น
    • PDO::FETCH_INTO:อัปเดตอินสแตนซ์ที่มีอยู่ของคลาสที่ระบุ
    • PDO::FETCH_LAZY:รวม PDO::FETCH_BOTH และ PDO::FETCH_OBJ
    • PDO::FETCH_NUM:ส่งคืนอาร์เรย์ที่มีคีย์เป็นเลขลำดับของคอลัมน์
    • PDO::FETCH_OBJ:ส่งคืนวัตถุที่ไม่ระบุชื่อพร้อมคุณสมบัติที่สอดคล้องกับชื่อคอลัมน์
    ในทางปฏิบัติ โดยปกติแล้ว 3 รายการจะเพียงพอสำหรับคุณ: FETCH_ASSOC, FETCH_CLASS และ FETCH_OBJ ในการตั้งค่ารูปแบบข้อมูล ให้ใช้ไวยากรณ์ต่อไปนี้:
    $STH->setFetchMode(PDO::FETCH_ASSOC);
    คุณยังสามารถตั้งค่าได้โดยตรงเมื่อเรียกใช้เมธอด ->fetch()

    FETCH_ASSOC

    รูปแบบนี้สร้างอาร์เรย์ที่เชื่อมโยงกับชื่อคอลัมน์เป็นดัชนี ควรคุ้นเคยกับผู้ที่ใช้ส่วนขยาย mysql/mysqli
    # เนื่องจากนี่เป็นข้อความค้นหาปกติที่ไม่มีตัวยึดตำแหน่ง # คุณสามารถใช้ query() method ได้ทันที $STH = $DBH->query("SELECT name, addr, city from folks"); # ตั้งค่าโหมดการดึงข้อมูล $STH->setFetchMode(PDO::FETCH_ASSOC); while($row = $STH->fetch()) ( echo $row["name"] . "\n"; echo $row["addr"] . "\n"; echo $row["city"] . "\n"; )
    การวนซ้ำ while() จะวนซ้ำกับผลการสืบค้นทั้งหมด

    FETCH_OBJ

    ประเภทการดึงข้อมูลนี้สร้างอินสแตนซ์ของคลาส std สำหรับแต่ละแถว
    # สร้างแบบสอบถาม $STH = $DBH->แบบสอบถาม ("เลือกชื่อ, addr, เมืองจากคน"); # เลือกโหมดดึงข้อมูล $STH->setFetchMode(PDO::FETCH_OBJ); # พิมพ์ผลลัพธ์ while($row = $STH->fetch()) ( echo $row->name . "\n"; echo $row->addr . "\n"; echo $row->city . "\n"; )

    FETCH_CLASS

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

    หากข้อมูลของคุณต้องได้รับการประมวลผลทันทีหลังจากได้รับจากฐานข้อมูล สามารถนำไปใช้ในคลาสคอนสตรัคเตอร์ได้

    ตัวอย่างเช่น สมมติว่าคุณต้องการซ่อนส่วนหนึ่งของที่อยู่ของบุคคลหนึ่ง
    class secret_person ( public $name; public $addr; public $city; public $other_data; function __construct($other = "") ( $this->addr = preg_replace("//", "x", $this->addr); $this->other_data = $other; ) )
    เมื่อสร้างวัตถุ ตัวอักษรละตินตัวพิมพ์เล็กทั้งหมดจะต้องแทนที่ด้วย x ตรวจสอบ:
    $STH = $DBH->query("เลือกชื่อ, addr, เมืองจากคน"); $STH->setFetchMode(PDO::FETCH_CLASS, "secret_person"); ในขณะที่ ($obj = $STH->ดึงข้อมูล ()) ( echo $obj->addr; )
    หากที่อยู่ดูเหมือน '5 Rosebud' ในฐานข้อมูล ผลลัพธ์จะเป็น '5 Rxxxxxx'

    แน่นอน บางครั้งคุณอาจต้องการเรียกตัวสร้างก่อนที่จะกำหนดค่า PDO ก็อนุญาตเช่นกัน
    $STH->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, "secret_person");
    ตอนนี้คุณได้ทำตัวอย่างก่อนหน้านี้พร้อมตัวเลือกเพิ่มเติม (PDO::FETCH_PROPS_LATE) แล้ว ที่อยู่จะไม่ถูกแก้ไข เนื่องจากไม่มีอะไรเกิดขึ้นหลังจากเขียนค่าแล้ว

    สุดท้าย หากจำเป็น คุณสามารถส่งอาร์กิวเมนต์ไปยังตัวสร้างได้โดยตรงเมื่อสร้างวัตถุ:
    $STH->setFetchMode(PDO::FETCH_CLASS, "secret_person", อาร์เรย์("สิ่งของ"));
    คุณสามารถส่งอาร์กิวเมนต์ที่แตกต่างกันไปยังแต่ละออบเจกต์ได้:
    $i = 0; while($rowObj = $STH->fetch(PDO::FETCH_CLASS, "secret_person", array($i))) ( // ทำบางอย่าง $i++; )

    วิธีการที่เป็นประโยชน์อื่น ๆ

    แม้ว่าบทความนี้ไม่สามารถ (และไม่ได้พยายาม) ครอบคลุมทุกแง่มุมของการทำงานกับ PDO (เป็นโมดูลขนาดใหญ่!) คุณลักษณะบางอย่างต่อไปนี้ไม่สามารถละเลยได้
    $DBH->lastInsertId();
    เมธอด ->lastInsertId() ส่งคืน id ของระเบียนที่แทรกล่าสุด โปรดทราบว่าจะมีการเรียกใช้บนวัตถุฐานข้อมูลเสมอ (อ้างถึงในบทความว่า $DBH) ไม่ใช่บนวัตถุนิพจน์ ($STH)
    $DBH->exec("ลบออกจากคนที่ 1"); $DBH->exec("SET time_zone = "-8:00"");
    เมธอด ->exec() ใช้สำหรับการดำเนินการที่ไม่ส่งคืนข้อมูลอื่นนอกจากจำนวนระเบียนที่ได้รับผลกระทบ
    $safe = $DBH->quote($ไม่ปลอดภัย);
    เมธอด ->quote() ใส่เครื่องหมายคำพูดในข้อมูลสตริงในลักษณะที่ปลอดภัยที่จะใช้ในแบบสอบถาม มีประโยชน์หากคุณไม่ได้ใช้คำสั่งที่เตรียมไว้
    $rows_affected = $STH->rowCount();
    เมธอด ->rowCount() ส่งคืนจำนวนเร็กคอร์ดที่เข้าร่วมในการดำเนินการ ขออภัย ฟังก์ชันนี้ใช้ไม่ได้กับข้อความค้นหา SELECT จนถึง PHP 5.1.6 หากไม่สามารถอัปเดตเวอร์ชัน PHP ได้ จำนวนระเบียนสามารถรับได้ดังนี้:
    $sql = "เลือกนับ(*) จากคน"; if ($STH = $DBH->query($sql)) ( # ตรวจสอบจำนวนระเบียน if ($STH->fetchColumn() > 0) ( # ทำการดึงข้อมูลทั้งหมดที่นี่ เนื่องจากพบข้อมูล! ) อื่น ( # แสดงข้อความว่าไม่พบข้อมูลที่ตรงกับการค้นหา ) )

    บทสรุป

    ฉันหวังว่าเนื้อหานี้จะช่วยให้คุณบางคนย้ายจากส่วนขยาย mysql และ mysqli

    ภาคเรียน สพปเป็นคำย่อของ วัตถุข้อมูล PHP. ตามชื่อที่แนะนำ เทคโนโลยีนี้ช่วยให้คุณสามารถทำงานกับเนื้อหาของฐานข้อมูลผ่านวัตถุ

    ทำไมไม่ myqli หรือ mysql

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

    PDO เชิงวัตถุ

    พี.เอช.พีกำลังพัฒนาอย่างแข็งขันและมีเป้าหมายที่จะเป็นหนึ่งในเครื่องมือที่ดีที่สุดสำหรับการพัฒนาอย่างรวดเร็วของเว็บแอปพลิเคชัน ทั้งในระดับมวลชนและระดับองค์กร

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

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

    สิ่งที่เป็นนามธรรม

    ลองนึกภาพว่าเราพัฒนาแอปพลิเคชั่นมาเป็นเวลานานโดยใช้ มายเอสคิวแอล. และจากนั้นในช่วงเวลาที่เหมาะสมก็จำเป็นต้องเปลี่ยน มายเอสคิวแอลบน PostgreSQL.

    อย่างน้อยที่สุด เราจะต้องเปลี่ยนสายทั้งหมด mysqli_connect() (mysql_connect())บน pg_connect()และโดยการเปรียบเทียบ ฟังก์ชันอื่นๆ ที่ใช้ในการสืบค้นและประมวลผลข้อมูล

    โดยใช้ สพปเราจะจำกัดตัวเองให้เปลี่ยนพารามิเตอร์บางตัวในไฟล์คอนฟิกูเรชัน

    การเชื่อมโยงพารามิเตอร์

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

    รับข้อมูลเป็นวัตถุ

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

    ไม่รองรับส่วนขยาย mysql อีกต่อไป

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

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

    ตรวจสอบ PDO ในระบบ

    รุ่น PHP 5.5และเหนือสิ่งอื่นใด มักจะมีส่วนขยายสำหรับการทำงานด้วยอยู่แล้ว สพป. ในการตรวจสอบ เพียงเรียกใช้คำสั่งง่ายๆ ในคอนโซล:

    php -i | เกรป "พีโด"

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

    ทำความรู้จัก สพป

    ขั้นตอนการทำงานร่วมกับ สพปไม่ต่างจากแบบดั้งเดิมมากนัก โดยทั่วไปขั้นตอนการใช้งาน สพปดูเหมือนว่า:

    1. การเชื่อมต่อฐานข้อมูล
    2. หากจำเป็น ให้เตรียมคำขอและพารามิเตอร์การผูกมัด
    3. การดำเนินการตามคำขอ

    การเชื่อมต่อฐานข้อมูล

    ในการเชื่อมต่อกับฐานข้อมูล คุณต้องสร้างวัตถุใหม่ สพปและส่งผ่านชื่อแหล่งข้อมูลหรือที่เรียกว่า ดีเอสเอ็น.

    โดยทั่วไป ดีเอสเอ็นประกอบด้วยชื่อไดรเวอร์ที่คั่นด้วยเครื่องหมายทวิภาคจากสตริงการเชื่อมต่อเฉพาะสำหรับไดรเวอร์แต่ละตัว สพป.

    สำหรับ มายเอสคิวแอลการเชื่อมต่อทำได้ดังนี้:

    $connection = new PDO("mysql:host=localhost;dbname=mydb;charset=utf8", "root", "root");

    $connection = ใหม่ PDO( "mysql:host=localhost;dbname=mydb;charset=utf8", "ราก" , "ราก" );

    ในกรณีนี้, ดีเอสเอ็นมีชื่อของผู้ขับขี่ มายเอสคิวแอลระบุโฮสต์ (รูปแบบที่เป็นไปได้ โฮสต์=ชื่อโฮสต์:พอร์ต), ชื่อฐานข้อมูล, การเข้ารหัส, ชื่อผู้ใช้ มายเอสคิวแอลและรหัสผ่านของเขา

    คำขอ

    ไม่เหมือน mysqli_query(), วี สพปคำขอมีสองประเภท:

    • ผลลัพธ์ที่ส่งคืน ( เลือกแสดง);
    • ไม่ส่งคืนผลลัพธ์ ( แทรก, รายละเอียดและคนอื่น ๆ).

    ก่อนอื่นมาพิจารณาตัวเลือกที่สอง

    กำลังดำเนินการค้นหา

    พิจารณาตัวอย่างการดำเนินการค้นหาโดยใช้ตัวอย่าง แทรก.

    $connection->exec("INSERT INTO users VALUES (1, "somevalue"");

    $การเชื่อมต่อ -> ผู้บริหาร ();

    แน่นอน ข้อความค้นหานี้ส่งคืนจำนวนแถวที่ได้รับผลกระทบ และคุณจะเห็นได้ดังนี้

    $affectedRows = $connection->exec("INSERT INTO users VALUES (1, "somevalue""); echo $affectedRows;

    $affectedRows = $connection -> ผู้บริหาร ( "INSERT INTO ค่าผู้ใช้ (1, "somevalue"") ;

    echo $affectedRows ;

    รับผลการสืบค้น

    กรณีใช้งาน mysqli_query()รหัสอาจเป็นดังนี้

    $result = mysql_query("เลือก * จากผู้ใช้"); while($row = mysql_fetch_assoc($result)) ( echo $row["id"] . " " . $row["name"]; )

    $result = mysql_query ("เลือก * จากผู้ใช้" );

    ในขณะที่ ($row = mysql_fetch_assoc ($result ) ) (

    สำหรับ สพปรหัสจะง่ายและรัดกุมมากขึ้น

    foreach($connection->query("SELECT * FROM users") as $row) ( echo $row["id"] . " " . $row["name"]; )

    foreach ($connection -> query("SELECT * FROM users" ) เป็น $row ) (

    echo $row [ "id" ] . " " . $row [ "ชื่อ" ] ;

    โหมดการรับข้อมูล

    เช่นเดียวกับใน มายเอสคิวลี, สพปช่วยให้คุณรับข้อมูลในโหมดต่างๆ เพื่อกำหนดโหมดคลาส สพปมีค่าคงที่ที่สอดคล้องกัน

    • PDO::FETCH_ASSOC- ส่งคืนอาร์เรย์ที่สร้างดัชนีโดยชื่อของคอลัมน์ในตารางฐานข้อมูล
    • PDO::FETCH_NUM- ส่งคืนอาร์เรย์ที่จัดทำดัชนีตามหมายเลขคอลัมน์
    • PDO::FETCH_OBJ- ส่งคืนวัตถุนิรนามพร้อมชื่อคุณสมบัติที่สอดคล้องกับชื่อคอลัมน์ ตัวอย่างเช่น $row->id จะประกอบด้วยค่าจากคอลัมน์ id
    • PDO::FETCH_CLASS- ส่งคืนอินสแตนซ์ใหม่ของคลาสโดยมีค่าคุณสมบัติที่สอดคล้องกับข้อมูลจากแถวของตาราง หากระบุพารามิเตอร์ PDO::FETCH_CLASSTYPE(ตัวอย่างเช่น PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE) ชื่อคลาสจะถูกกำหนดจากค่าของคอลัมน์แรก

    บันทึก: นี่ไม่ใช่รายการที่สมบูรณ์ ค่าคงที่ที่เป็นไปได้ทั้งหมดและชุดค่าผสมมีอยู่ในเอกสารประกอบ

    ตัวอย่างของการได้รับอาร์เรย์ที่เชื่อมโยง:

    $statement = $connection->query("เลือก * จากผู้ใช้"); ในขณะที่($row = $statement->fetch(PDO::FETCH_ASSOC)) ( echo $row["id"] . " " . $row["name"]; )

    $statement = $connection ->

    ในขณะที่ ($row = $statement -> ดึงข้อมูล (PDO::FETCH_ASSOC ) ) (

    echo $row [ "id" ] . " " . $row [ "ชื่อ" ] ;

    บันทึก: ขอแนะนำให้คุณระบุโหมดการสุ่มตัวอย่างเสมอ เนื่องจากโหมดการสุ่มตัวอย่าง PDO::FETCH_BOTHจะต้องใช้หน่วยความจำมากเป็นสองเท่า - อันที่จริงแล้ว จะมีการสร้างอาร์เรย์สองอาร์เรย์ หนึ่งอาร์เรย์ที่เชื่อมโยงและอาร์เรย์ปกติ

    พิจารณาใช้โหมดตัวอย่าง PDO::FETCH_CLASS. มาสร้างคลาสกันเถอะ ผู้ใช้:

    ผู้ใช้ระดับ ( $id ที่ได้รับการป้องกัน; ชื่อ $ ที่ได้รับการป้องกัน; public function getId() ( return $this->id; ) ฟังก์ชันสาธารณะ setId($id) ( $this->id = $id; ) ฟังก์ชันสาธารณะ getName() ( return $this->name; ) ฟังก์ชันสาธารณะ setName($name) ( $this->name = $name; ) )

    ผู้ใช้คลาส

    ป้องกัน $id ;

    ป้องกัน $name ;

    ฟังก์ชันสาธารณะ getId()

    ส่งคืน $this -> id ;

    ฟังก์ชันสาธารณะ setId ( $id )

    $นี้ -> id = $id ;

    ฟังก์ชั่นสาธารณะ getName()

    ส่งคืน $this -> ชื่อ ;

    ฟังก์ชั่นสาธารณะ setName ($name )

    $นี่ -> ชื่อ = $ชื่อ ;

    ตอนนี้ให้เลือกข้อมูลและแสดงข้อมูลโดยใช้วิธีการเรียน:

    $statement = $connection->query("เลือก * จากผู้ใช้"); ในขณะที่($row = $statement->fetch(PDO::FETCH_CLASS, "ผู้ใช้")) ( echo $row->getId() . " " . $row->getName(); )

    $statement = $connection -> แบบสอบถาม ("เลือก * จากผู้ใช้" );

    ในขณะที่ ($row = $statement -> ดึงข้อมูล (PDO::FETCH_CLASS , "User" ) ) (

    ก้อง $row -> getId() " " . $row -> getName();

    แบบสอบถามที่เตรียมไว้และการผูกพารามิเตอร์

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

    เมื่อถูกเรียก การเชื่อมต่อ $ -> เตรียม ()มีการสร้างแบบสอบถามที่เตรียมไว้ แบบสอบถามที่เตรียมไว้คือความสามารถของระบบการจัดการฐานข้อมูลในการรับแม่แบบแบบสอบถาม คอมไพล์ และดำเนินการหลังจากได้รับค่าของตัวแปรที่ใช้ในแม่แบบ เอ็นจิ้นเทมเพลตทำงานในลักษณะเดียวกัน ฉลาดและ กิ่งไม้.

    เมื่อถูกเรียก $statement -> ดำเนินการ ()ค่าจะถูกส่งไปแทนที่ในเทมเพลตคิวรี และ DBMS ดำเนินการคิวรี การดำเนินการนี้คล้ายกับการเรียกใช้ฟังก์ชันเทมเพลต แสดงผล ().

    ตัวอย่างการใช้แบบสอบถามที่เตรียมไว้ใน PHP พีดีโอ:

    ในโค้ดด้านบน มีการเตรียมคิวรีสำหรับการเลือกเรกคอร์ดที่มีฟิลด์ รหัสเท่ากับมูลค่าที่จะทดแทน :รหัส. ในขั้นตอนนี้ DBMS จะแยกวิเคราะห์และคอมไพล์เคียวรี ซึ่งอาจใช้การแคช (ขึ้นอยู่กับการตั้งค่า)

    ตอนนี้คุณต้องส่งพารามิเตอร์ที่ขาดหายไปและดำเนินการตามคำขอ:

    $id = 5; $statement->execute([ ":id" => $id ]);

    ประโยชน์ของการใช้พารามิเตอร์ที่เชื่อมโยง

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

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

    แทนที่จะทำเช่นนี้:

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

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

    $numberOfUsers = $connection->query("เลือก COUNT(*) จากผู้ใช้")->fetchColumn(); $ผู้ใช้ = ; $statement = $connection->prepare("เลือก * จากผู้ใช้ WHERE id = ? LIMIT 1"); สำหรับ ($i = 1; $i<= 5; $i++) { $id = rand(1, $numberOfUsers); $users = $statement->ดำเนินการ([$id])->ดึง(PDO::FETCH_OBJ); )

    $numberOfUsers = $connection -> แบบสอบถาม ("เลือก COUNT(*) จากผู้ใช้" ) -> fetchColumn () ;

    $ผู้ใช้ = ;

    สำหรับ ($i = 1 ; $i<= 5 ; $i ++ ) {

    $id = แรนด์ (1 , $numberOfUsers ) ;

    $users = $statement -> ดำเนินการ ([ $id ] ) -> ดึงข้อมูล (PDO::FETCH_OBJ ) ;

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

    เมื่อได้จำนวนผู้ใช้ทั้งหมดในฐานข้อมูลจึงใช้วิธีการ ดึงคอลัมน์ (). วิธีนี้จะส่งคืนค่าของคอลัมน์เดียวและมีประโยชน์เมื่อส่งคืนค่าสเกลาร์ เช่น จำนวน ผลรวม ค่าสูงสุด หรือค่าต่ำสุด

    ค่าขอบเขตและตัวดำเนินการ IN

    บ่อยครั้งเมื่อเริ่มต้นด้วย สพปมีปัญหากับผู้ปฏิบัติงาน ใน. ตัวอย่างเช่น สมมติว่าผู้ใช้ป้อนหลายชื่อโดยคั่นด้วยเครื่องหมายจุลภาค อินพุตของผู้ใช้ถูกเก็บไว้ในตัวแปร $ชื่อ.

    วันนี้ฉันเริ่มบทความเกี่ยวกับ สพปซึ่งเราจะวิเคราะห์ PDO คืออะไรทำไมเราต้องการมันและวิธีการใช้

    แน่นอนหลายคนเคยได้ยินตัวย่อแล้ว สพปแต่มีเพียงไม่กี่คนที่รู้ว่ามันคืออะไร วันนี้มาพูดถึงเรื่องนี้กัน

    PDO คืออะไร?

    PDO (วัตถุข้อมูล PHP)- มันง่าย อินเตอร์เฟซทำให้เราสามารถแยกออกจากฐานข้อมูลเฉพาะได้ เป็นการดีที่สุดที่จะแสดงให้เห็นด้วยตัวอย่าง

    mysql_connect($host,$user,$pass); // มายเอสคิวแอล
    mysql_select_db($db);

    sqlite_open($db); // สคไลต์

    pg_connect("host=$host, dbname=$db, user=$user, password=$pass"); // PostgreSQL

    โค้ดด้านบนแสดงวิธีการเชื่อมต่อกับฐานข้อมูลสามแบบ: มายเอสคิวแอล, สแควร์ไลท์และ PostgreSQL. อย่างที่คุณเห็น หน้าที่ของแต่ละฐานข้อมูลจะแตกต่างกัน

    เช่นเดียวกับการกระทำอื่น ๆ เช่น การดึงข้อมูลจากฐานข้อมูล

    $sql = "INSERT INTO(name, pass) VALUES($name, $pass)";

    mysql_query($sql); // มายเอสคิวแอล
    sqlite_query($sql); // สคไลต์
    pg_query($sql); // PostgreSQL

    ทำไม PDO จึงจำเป็น?

    ลองนึกภาพเรามีฐานข้อมูลขนาดใหญ่ PostgreSQLและเราตัดสินใจที่จะเปลี่ยนเป็น มายเอสคิวแอล. เราจะต้องเขียนโค้ดจำนวนมากใหม่และส่วนใหญ่จะไม่ทำโดยไม่มีข้อผิดพลาด เพื่อแก้ปัญหานี้และมี สพปซึ่งช่วยให้เราไม่ต้องพึ่งพาฐานใดฐานหนึ่ง

    มาดูกันว่าเราจะเชื่อมต่อกันได้อย่างไร

    $db = new PDO("mysql:host=$host;dbname=$db", $user, $pass); // มายเอสคิวแอล
    $db = new PDO("sqlite:host=$host;dbname=$db", $user, $pass); // สคไลต์
    $db = new PDO("pgsql:host=$host;dbname=$db", $user, $pass); // PostgreSQL

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

    ในการเลือกบางอย่าง เราสามารถเขียนดังนี้:

    $db->exec($sql);

    ทั้งหมด! แบบสอบถามจะถูกดำเนินการโดยไม่คำนึงว่าเรามีฐานข้อมูลใด

    สนับสนุน

    สพปได้จาก PHP 5.1. เพื่อให้เราสามารถ "ลืม" ว่าเราใช้ฐานข้อมูลใด พวกเขาทำทุกอย่างเพื่อเรา ไดรเวอร์. หากต้องการเปิดใช้งาน ให้ไปที่ไฟล์ php.iniและมองหาบรรทัดที่ขึ้นต้นด้วย นามสกุล = php_pdo_ตามด้วยชื่อของฐานข้อมูล และยกเลิกการแสดงความคิดเห็น

    นั่นคือทั้งหมดสำหรับบทความเบื้องต้น และในตอนหน้า เราจะเริ่มเข้าใจ วิธีใช้ PDO.