Cara mengkonfigurasi dan menggunakan PDO untuk akses database di Linux

Cara mengkonfigurasi dan menggunakan PDO untuk akses database di Linux

Objektif

Pelajari cara mengkonfigurasi dan menggunakan PDO untuk akses database: dari mode kesalahan hingga metode pengambilan.

Persyaratan

  • Pengetahuan standar mySQL dan mysql klien baris perintah;
  • Akrab dengan konsep mendasar pemrograman berorientasi objek
  • Php> = 5.1
  • Memiliki database mysql/mariadb yang berfungsi

Kesulitan

SEDANG

Konvensi

  • # - mensyaratkan perintah linux yang diberikan untuk dieksekusi dengan hak istimewa root
    langsung sebagai pengguna root atau dengan menggunakan sudo memerintah
  • $ - mensyaratkan perintah Linux yang diberikan untuk dieksekusi sebagai pengguna biasa

Perkenalan

PDO adalah akronim untuk Objek Data PHP: Ini adalah ekstensi PHP untuk berinteraksi dengan database melalui penggunaan objek. Salah satu kekuatannya berada dalam kenyataan bahwa ia tidak terikat secara ketat dengan beberapa database tertentu: antarmukanya menyediakan cara umum untuk mengakses beberapa lingkungan yang berbeda, di antara yang lain:

  • Mysql
  • Sqlite
  • PostgreSQL
  • Microsoft SQL Server

Panduan ini bertujuan untuk memberikan gambaran yang cukup lengkap tentang PDO, membimbing pembaca langkah demi langkah dari pembentukan koneksi ke database, ke pilihan mode pengambilan yang paling tepat, menunjukkan cara membuat pernyataan yang disiapkan dan menggambarkan kemungkinan mode kesalahan yang mungkin terjadi kesalahan yang mungkin terjadi kesalahan kesalahan yang mungkin.

Buat Database dan Tabel Tes

Hal pertama yang akan kami lakukan adalah membuat database untuk tutorial ini:

Buat basis data solar_system; Berikan semua hak istimewa di solar_system.* Untuk 'testuser'@'localhost' yang diidentifikasi oleh 'testpassword'; 
Menyalin

Kami memberikan pengguna Testuser semua hak istimewa di tata surya Database, menggunakan testPassword sebagai kata sandi. Sekarang mari kita buat tabel dan isi dengan beberapa data (tidak ada akurasi astronomi yang dimaksudkan):

Gunakan solar_system; Buat planet meja (id tinyint (1) Unsigned not null auto_increment, kunci primer (id), nama varchar (10) bukan nol, warna varchar (10) bukan nol); Sisipkan ke planet (nama, warna) nilai ('bumi', 'biru'), ('mars', 'merah'), ('jupiter', 'aneh'); 
Menyalin

DSN: Nama Sumber Data

Sekarang kita memiliki database, kita harus mendefinisikan a DSN. DSN adalah singkatan dari Nama Sumber Data, Dan pada dasarnya ini adalah satu set informasi yang diperlukan untuk terhubung ke database, diwakili dalam bentuk string. Sintaksnya mungkin berbeda tergantung pada database yang ingin Anda hubungkan, tetapi karena kami berinteraksi dengan MySQL/MariaDB, kami akan menyediakan:

  • Jenis driver yang akan digunakan untuk koneksi
  • Nama host mesin yang menampung database
  • Port yang akan digunakan untuk koneksi (opsional)
  • Nama database
  • Charset (opsional)

Format string, dalam kasus kami adalah sebagai berikut (kami akan menyimpannya di $ dsn variabel):

$ dsn = "mysql: host = localhost; port = 3306; dbname = solar_system; charset = utf8"; 
Menyalin

Pertama -tama, kami menyediakan awalan basis data. Dalam hal ini, karena kami menghubungkan ke database MySQL/MariaDB, kami menggunakan mysql. Kami kemudian memisahkan awalan dari sisa string dengan usus besar dan masing -masing bagian lainnya oleh titik koma.

Di dua bagian berikutnya kami menentukan nama host mesin tempat database di -host dan pelabuhan untuk digunakan untuk koneksi. Jika yang terakhir tidak disediakan, yang default akan digunakan, yang, dalam hal ini 3306. Segera setelah kami menyediakan Nama Basis Data, Dan setelah itu, Charset menggunakan.

Membuat Objek PDO

Sekarang DSN kami sudah siap, kami akan membangun Objek PDO. Konstruktor PDO mengambil string DSN sebagai parameter pertama, nama pengguna pada database sebagai parameter kedua, kata sandi sebagai yang ketiga, dan secara opsional merupakan array opsi sebagai yang keempat:

$ options = [pdo :: attr_errmode => pdo :: errmode_exception, pdo :: attr_default_fetch_mode => pdo :: fetch_assoc]; $ pdo = PDO baru ($ dsn, 'testuser', 'testpassword', $ options); 
Menyalin

Namun, opsi dapat ditentukan juga setelah objek dibangun, melalui Setattribute () metode:

$ pdo-> setAttribute (pdo :: attr_errmode, pdo :: errmode_exception); 
Menyalin

Mengatur perilaku PDO pada kesalahan

Mari kita lihat beberapa opsi yang tersedia untuk PDO :: ATTR_ERRMODE. Opsi ini sangat penting, karena mendefinisikan perilaku PDO jika terjadi kesalahan. Pilihan yang mungkin adalah:

Pdo :: errmode_silent

Ini adalah default. PDO hanya akan mengatur kode kesalahan dan pesan kesalahan. Mereka dapat diambil dengan menggunakan errorCode () Dan errorInfo () metode.

Pdo :: errmode_exception

Ini, menurut pendapat saya, yang direkomendasikan. Dengan opsi ini, selain mengatur kode kesalahan dan info, PDO akan melempar a PDOException, yang akan memecahkan aliran skrip, dan ini sangat berguna dalam hal Transaksi PDO (Kita akan melihat transaksi apa yang kemudian dalam tutorial ini).

Pdo :: errmode_warning

Dengan opsi ini, PDO akan mengatur kode kesalahan dan info seperti yang diindeks Pdo :: errmode_silent, tetapi juga akan menghasilkan a PERINGATAN, yang tidak akan memecahkan aliran naskah.

Mengatur mode pengambilan default

Pengaturan penting lainnya dapat ditentukan melalui PDO :: Default_fetch_mode. konstan. Ini memungkinkan Anda menentukan metode pengambilan default untuk digunakan saat mengambil hasil dari kueri. Ini adalah opsi yang paling umum digunakan:

Pdo :: fetch_both:

Ini adalah default. Dengan itu hasilnya diambil dengan kueri pengambilan akan diindeks baik oleh integer maupun dengan nama kolom. Menerapkan mode pengambilan ini saat mengambil barisan dari tabel planet akan memberi kita hasil ini:

$ stmt = $ pdo-> kueri ("Pilih * dari planet"); $ hasil = $ stmt-> fetch (pdo :: fetch_both); 
Menyalin
Array ([id] => 1 [0] => 1 [name] => earth [1] => earth [warna] => biru [2] => biru) 

Pdo :: fetch_assoc:

Dengan opsi ini, hasilnya akan disimpan dalam array asosiatif di mana setiap kunci akan menjadi nama kolom, dan setiap nilai akan menjadi nilai yang sesuai dalam satu baris:

$ stmt = $ pdo-> kueri ("Pilih * dari planet"); $ hasil = $ stmt-> fetch (pdo :: fetch_assoc);
Menyalin
Array ([id] => 1 [name] => earth [color] => blue) 

Pdo :: fetch_num

Mode pengambilan ini mengembalikan baris yang diambil ke a Array 0-indeks:

Array ([0] => 1 [1] => earth [2] => biru) 

Pdo :: fetch_column

Metode pengambilan ini berguna saat mengambil hanya nilai kolom dan akan mengembalikan semua hasil di dalam array satu dimensi polos. Misalnya kueri ini:

$ stmt = $ pdo-> kueri ("Pilih Nama dari Planet");
Menyalin

Akan mengembalikan hasil ini:

Array ([0] => earth [1] => mars [2] => jupiter) 

Pdo :: fetch_key_pair

Metode pengambilan ini berguna saat mengambil nilai hanya 2 kolom. Ini akan mengembalikan hasil dalam bentuk array asosiatif di mana nilai -nilai yang diambil dari database untuk kolom yang ditentukan pertama dalam kueri, akan digunakan sebagai tombol array, sedangkan nilai yang diambil untuk kolom kedua, akan mewakili asosiatif Nilai Array:

$ stmt = $ pdo-> kueri ("Pilih Nama, Warna dari Planet"); $ result = $ stmt-> fetchall (pdo :: fetch_key_pair); 
Menyalin

Akan kembali:

Array ([earth] => blue [mars] => merah [jupiter] => aneh) 

Pdo :: fetch_object:

Saat menggunakan Pdo :: fetch_object konstan, an objek anonim akan dibuat untuk setiap baris yang diambil. Properti (publik) akan dinamai setelah kolom, dan hasil kueri akan digunakan sebagai nilainya. Menerapkan mode pengambilan ini ke kueri yang sama di atas akan mengembalikan hasilnya dalam formulir:

$ hasil = $ stmt-> fetch (pdo :: fetch_obj);
Menyalin
objek stdclass ([name] => earth [color] => blue) 

Pdo :: fetch_class:

Mode pengambilan ini, seperti yang di atas, akan menetapkan nilai kolom ke properti suatu objek, tetapi dalam hal ini kita harus menentukan kelas yang ada yang harus digunakan untuk membuat objek. Mari kita tunjukkan, pertama -tama kita akan membuat kelas:

planet kelas private $ name; Warna $ pribadi; fungsi publik setName ($ planet_name) $ this-> name = $ planet_name;  fungsi publik setColor ($ planet_color) $ this-> color = $ planet_color;  fungsi publik getName () return $ this-> name;  fungsi publik getColor () return $ this-> color;  
Menyalin

Harap abaikan naif kode di atas dan perhatikan bahwa properti kelas planet pribadi dan kelas tidak memiliki konstruktor. Sekarang mari kita coba untuk mengambil hasilnya.

Ketika menggunakan mengambil() dengan Pdo :: fetch_class Anda harus menggunakan setFechMode () Metode pada objek pernyataan sebelum mencoba mengambil data, misalnya:

$ stmt = $ pdo-> kueri ("Pilih Nama, Warna dari Planet"); $ stmt-> setFetchMode (pdo :: fetch_class, 'planet');
Menyalin

Kami menyediakan opsi pengambilan konstanta Pdo :: fetch_class sebagai argumen pertama dari metode setFetchMode (), dan nama kelas yang harus digunakan untuk membuat objek ('planet' dalam hal ini) sebagai yang kedua. Sekarang kami menjalankan:

$ planet = $ stmt-> fetch ();
Menyalin

Objek planet seharusnya dibuat:

var_dump ($ planet);
Menyalin
Objek Planet ([Nama: Planet: Private] => Earth [Warna: Planet: Private] => Biru) 

Perhatikan bagaimana nilai -nilai yang diambil yang dihasilkan dari kueri, telah ditugaskan ke properti yang sesuai dari objek bahkan jika mereka pribadi.

Menetapkan properti setelah konstruksi objek

Kelas planet tidak memiliki konstruktor eksplisit yang didefinisikan, jadi tidak ada masalah saat menetapkan properti; Tetapi bagaimana jika kelas memiliki konstruktor di mana properti itu ditugaskan atau dimanipulasi? Karena nilainya ditetapkan sebelum konstruktor dipanggil, mereka akan ditimpa.

PDO membantu menyediakan Fetch_props_late Konstanta: Saat menggunakannya, nilai akan ditetapkan ke properti setelah objek dibangun. Misalnya:

planet kelas private $ name; Warna $ pribadi; fungsi publik __construct ($ name = moon, $ color = grey) $ this-> name = $ name; $ this-> color = $ color;  fungsi publik setName ($ planet_name) $ this-> name = $ planet_name;  fungsi publik setColor ($ planet_color) $ this-> color = $ planet_color;  fungsi publik getName () return $ this-> name;  fungsi publik getColor () return $ this-> color; 
Menyalin

Kami memodifikasi kelas planet kami, menyediakan konstruktor yang mengambil dua argumen: yang pertama adalah nama Dan yang kedua adalah warna. Argumen tersebut masing -masing memiliki nilai default bulan Dan abu-abu: Ini berarti bahwa jika tidak ada nilai yang secara eksplisit asalkan itu akan menjadi default yang ditetapkan.

Dalam hal ini, jika kami tidak menggunakan Fetch_props_late, Tidak peduli nilai -nilai yang diambil dari database, properti akan selalu memiliki nilai default, karena mereka akan ditimpa ketika objek dibangun. Mari kita verifikasi. Pertama kami menjalankan kueri:

$ stmt = $ pdo-> kueri ("Pilih Nama, Warna dari Solar_System Where Name = 'Earth'"); $ stmt-> setFetchMode (pdo :: fetch_class, 'planet'); $ planet = $ stmt-> fetch ();
Menyalin

Lalu kami membuang Planet objek dan periksa nilai apa yang dimiliki propertinya:

var_dump ($ planet); objek (planet)#2 (2) ["name": "planet": private] => string (4) "moon" ["color": "planet": private] => string (4) "abu -abu" 
Menyalin

Seperti yang diharapkan, nilai yang diambil dari database telah ditimpa oleh default. Sekarang, kami menunjukkan bagaimana masalah ini dapat diselesaikan dengan menggunakan Fetch_props_late (Kueri sama seperti di atas):

$ stmt-> setFetchMode (pdo :: fetch_class | pdo :: fetch_props_late, 'planet'); $ planet = $ stmt-> fetch (); var_dump ($ planet); objek (planet)#4 (2) ["name": "planet": private] => string (5) "earth" ["color": "planet": private] => string (4) "biru" 
Menyalin

Akhirnya kami mendapatkan hasil yang diinginkan. Tetapi bagaimana jika konstruktor kelas tidak memiliki nilai default, dan mereka harus disediakan ? Sederhana: Kami dapat menentukan parameter konstruktor dalam bentuk array sebagai argumen ketiga, setelah nama kelas, dalam metode setFetchMode (). Misalnya, biarkan mengubah konstruktor:

planet kelas private $ name; Warna $ pribadi; fungsi publik __construct ($ name, $ color) $ this-> name = $ name; $ this-> color = $ color;  […]
Menyalin

Argumen konstruktor sekarang wajib, jadi kami akan menjalankan:

$ stmt-> setFetchMode (pdo :: fetch_class | pdo :: fetch_props_late, 'planet', ['moon', 'grey']);
Menyalin

Dalam hal ini, parameter yang kami berikan berfungsi sebagai nilai default, yang diperlukan untuk menginisialisasi objek tanpa kesalahan: mereka akan ditimpa oleh nilai yang diambil dari database.

Mengambil banyak objek

Tentu saja dimungkinkan untuk mengambil beberapa hasil sebagai objek, baik menggunakan mengambil() Metode di dalam waktu sementara:

while ($ planet = $ stmt-> fetch ()) // lakukan hal-hal dengan hasilnya 
Menyalin

atau dengan mengambil semua hasil sekaligus. Dalam hal ini, seperti yang dikatakan di atas, menggunakan fetchall () Metode, Anda tidak perlu menentukan mode pengambilan sebelum memanggil metode itu sendiri, tetapi saat ini Anda menyebutnya:

$ stmt-> fetchall (pdo :: fetch_class | pdo_fetch_props_late, 'planet', ['moon', 'grey']); 
Menyalin

Pdo :: fetch_into

Dengan set metode pengambilan ini, PDO tidak akan membuat objek baru, sebaliknya itu akan memperbarui properti yang sudah ada, tetapi hanya jika mereka publik, atau jika Anda menggunakan __mengatur Metode Sihir di dalam objek.

Pernyataan disiapkan vs langsung

PDO memiliki dua cara untuk menjalankan pertanyaan: satu adalah cara langsung, satu langkah. Yang lain, lebih aman adalah menggunakan pernyataan yang disiapkan.

Kueri langsung

Saat menggunakan kueri langsung, Anda memiliki dua metode utama: pertanyaan() Dan exec (). Yang pertama pengembalian pengembalian a Pdostatemnt objek yang dapat Anda gunakan untuk mengakses hasil melalui mengambil() atau fetchall () Metode: Anda menggunakannya untuk pernyataan yang tidak memodifikasi tabel, seperti PILIH.

Yang terakhir, sebaliknya, mengembalikan jumlah baris yang diubah oleh kueri: kami menggunakannya untuk pernyataan yang memodifikasi baris, seperti MENYISIPKAN, MENGHAPUS atau MEMPERBARUI. Pernyataan langsung hanya akan digunakan ketika tidak ada variabel dalam kueri dan Anda benar -benar percaya itu aman dan melarikan diri dengan benar.

Pernyataan yang disiapkan

PDO mendukung juga pernyataan dua tahap, disiapkan: Ini berguna saat menggunakan variabel dalam kueri, dan lebih aman secara umum, karena mempersiapkan() Metode akan melakukan semua yang diperlukan untuk melarikan diri untuk kita. Mari kita lihat bagaimana variabel digunakan. Bayangkan kita ingin memasukkan properti objek planet ke dalam Planet meja. Pertama kami akan menyiapkan kueri:

$ stmt = $ pdo-> persiapkan ("masukkan ke dalam planet (nama, warna) nilai (?, ?) "); 
Menyalin

Seperti yang dikatakan sebelumnya, pertama -tama kita akan menggunakan mempersiapkan() metode yang mengambil kueri SQL sebagai argumen, menggunakan placeholder untuk variabel. Sekarang placeholder bisa dari dua jenis:

Placeholder Posisi

Ketika menggunakan ? Placeholder Posisi Kami dapat memperoleh lebih banyak kode ringkas, tetapi kami harus memberikan nilai -nilai yang akan diganti dalam urutan nama kolom yang sama, dalam array yang disediakan sebagai argumen untuk menjalankan() metode:

$ stmt-> execute ([$ planet-> name, $ planet-> color]); 
Menyalin

Bernama placeholder

Menggunakan bernama placeholder, Kami tidak harus menghormati pesanan tertentu, tetapi kami akan membuat lebih banyak kode verbose. Saat mengeksekusi menjalankan() metode kita harus memberikan nilai dalam bentuk array asosiatif di mana masing -masing kunci akan menjadi nama placeholder yang digunakan, dan nilai yang terkait akan menjadi yang diganti dalam kueri. Misalnya kueri di atas adalah:

$ stmt = $ pdo-> persiapkan ("masukkan ke planet (nama, warna) nilai (: nama ,: color)"); $ stmt-> execute (['name' => $ planet-> name, 'color' => $ planet-> color]); 
Menyalin

Metode persiapan dan jalankan dapat digunakan baik saat melakukan kueri yang memodifikasi atau hanya mengambil data dari database. Dalam kasus sebelumnya kami menggunakan metode pengambilan yang kami lihat di atas untuk mengambil data, sementara yang terakhir kami dapat mengambil jumlah baris yang terpengaruh dengan menggunakan rowcount () metode.

Metode bindValue () dan bindparam ()

Untuk memberikan nilai yang akan diganti dalam kueri, kita juga dapat menggunakan bindValue () Dan bindparam () metode. Yang pertama mengikat nilai variabel yang disediakan untuk posisi yang terkait atau bernama placeholder yang digunakan saat menyiapkan kueri. Menggunakan contoh di atas yang akan kami lakukan:

$ stmt-> bindValue ('name', $ planet-> name, pdo :: param_str); 
Menyalin

Kami mengikat nilainya $ planet-> nama ke :nama placeholder. Perhatikan bahwa menggunakan metode bindValue () dan bindparam () yang dapat kita tentukan, sebagai argumen ketiga, jenis dari variabel, menggunakan konstanta PDO terkait, dalam hal ini Pdo :: param_str.

Menggunakan bindparam (), Sebaliknya, kita dapat mengikat variabel ke placeholder terkait yang digunakan saat menyiapkan kueri. Perhatikan bahwa dalam hal ini variabel terikat oleh referensi, dan nilainya hanya akan diganti dengan placeholder pada saat itu menjalankan() metode itu disebut. Sintaksnya sama seperti di atas:

$ stmt-> bindparam ('name', $ planet-> name, pdo :: param_str) 
Menyalin

Kami mengikat variabel $ planet-> nama ke :nama placeholder, bukan nilainya saat ini! Seperti yang dikatakan di atas konversi akan dilakukan tepat saat menjalankan() metode akan dipanggil, jadi placeholder akan diganti dengan nilai variabel yang dimiliki pada saat itu.

Transaksi PDO

Transaksi menyediakan cara untuk mempertahankan konsistensi saat mengeluarkan banyak pertanyaan. Semua pertanyaan dilakukan dalam "batch", dan berkomitmen untuk database hanya jika semuanya berhasil. Transaksi tidak akan berfungsi di semua database dan bukan untuk semua SQL konstruksi, karena beberapa di antaranya menyebabkan dan implisit komit (daftar lengkap di sini)

Dengan contoh yang ekstrem dan aneh, bayangkan bahwa pengguna harus memilih daftar planet, dan setiap kali ia mengirimkan pilihan baru, Anda ingin menghapus yang sebelumnya dari database sebelum memasukkan yang baru. Apa yang akan terjadi jika penghapusan berhasil, tetapi bukan penyisipan? Kami akan memiliki pengguna tanpa planet! Biasanya ini adalah bagaimana transaksi diimplementasikan:

$ pdo-> beginTransaction (); coba $ stmt1 = $ pdo-> exec ("hapus dari planet"); $ stmt2 = $ pdo-> persiapkan ("masukkan ke planet (nama, warna) nilai (?, ?) "); foreach ($ planet sebagai $ planet) $ stmt2-> execute ([$ planet-> getName (), $ planet-> getColor ()]); $ pdo-> commit (); catch ( PdoException $ e) $ pdo-> rollback ();
Menyalin

Pertama -tama begintransaction () Metode objek PDO menonaktifkan kueri Autocommit, lalu di dalam blok mencoba-tangkapan, kueri dieksekusi dalam urutan yang dicari. Pada titik ini jika tidak PDOException diangkat, pertanyaannya berkomitmen dengan melakukan() metode, jika tidak, melalui rollback () metode, transaksi dikembalikan dan autocommit dipulihkan.

Dengan cara ini akan selalu ada konsistensi saat mengeluarkan banyak pertanyaan. Cukup jelas bahwa Anda dapat menggunakan transaksi PDO hanya saat PDO :: ATTR_ERRMODE diatur ke Pdo :: errmode_exception.

Tutorial Linux Terkait:

  • Hal -hal yang harus diinstal pada ubuntu 20.04
  • Cara mengubah kata sandi pengguna mariadb
  • Cara membuat tumpukan lampu berbasis Docker menggunakan Docker di…
  • Instalasi ampache raspberry pi
  • Pengantar Otomatisasi Linux, Alat dan Teknik
  • Instalasi OpenLitespeed WordPress
  • Hal -hal yang harus dilakukan setelah menginstal ubuntu 20.04 FOSSA FOSSA Linux
  • Ubuntu 20.04 WordPress dengan Instalasi Apache
  • Ubuntu 20.04: WordPress dengan instalasi nginx
  • Instal MySQL di Ubuntu 20.04 LTS Linux