Cara mengkonfigurasi dan menggunakan PDO untuk akses pangkalan data di Linux

Cara mengkonfigurasi dan menggunakan PDO untuk akses pangkalan data di Linux

Objektif

Ketahui Cara Mengkonfigurasi dan Gunakan PDO untuk Akses Pangkalan Data: Dari Mod Ralat untuk Ambil Kaedah.

Keperluan

  • Pengetahuan standard mysql dan mysql pelanggan baris arahan;
  • Berkenaan dengan konsep asas pengaturcaraan berorientasikan objek
  • Php> = 5.1
  • Mempunyai pangkalan data MySQL/MariaDB yang bekerja

Kesukaran

Medium

Konvensyen

  • # - Memerlukan arahan Linux yang diberikan dengan keistimewaan akar sama ada
    secara langsung sebagai pengguna akar atau dengan menggunakan sudo perintah
  • $ - Memerlukan arahan Linux yang diberikan sebagai pengguna yang tidak layak

Pengenalan

PDO adalah akronim untuk Objek data PHP: Ia adalah lanjutan PHP untuk berinteraksi dengan pangkalan data melalui penggunaan objek. Salah satu kekuatannya terletak pada hakikat bahawa ia tidak terikat dengan sesetengah pangkalan data tertentu: antara mukanya menyediakan cara yang sama untuk mengakses beberapa persekitaran yang berbeza, antara yang lain:

  • Mysql
  • SQLITE
  • PostgreSQL
  • Microsoft SQL Server

Panduan ini bertujuan untuk memberikan gambaran keseluruhan PDO yang cukup lengkap, membimbing pembaca langkah demi langkah dari penubuhan sambungan ke pangkalan data, kepada pilihan mod pengambilan yang paling sesuai, menunjukkan cara membuat kenyataan yang disediakan dan menerangkan mod ralat yang mungkin.

Buat pangkalan data dan jadual ujian

Perkara pertama yang akan kita lakukan ialah membuat pangkalan data untuk tutorial ini:

Buat pangkalan data Solar_System; Memberi semua keistimewaan di Solar_System.* Kepada 'testuser'@'localhost' yang dikenal pasti oleh 'testpassword'; 
Salinan

Kami memberikan pengguna penguji semua keistimewaan di solar_system pangkalan data, menggunakan testpassword sebagai kata laluan. Sekarang mari kita buat jadual dan isi dengan beberapa data (tidak ada ketepatan astronomi yang dimaksudkan):

Gunakan solar_system; Buat planet meja (id tinyint (1) unsigned not null auto_increment, kunci utama (id), nama varchar (10) tidak null, varchar warna (10) tidak null); Masukkan ke dalam planet (nama, warna) nilai ('bumi', 'biru'), ('mars', 'merah'), ('jupiter', 'pelik'); 
Salinan

DSN: Nama sumber data

Sekarang kita mempunyai pangkalan data, kita mesti menentukan a DSN. DSN bermaksud Nama sumber data, Dan pada dasarnya ia adalah satu set maklumat yang diperlukan untuk menyambung ke pangkalan data, yang diwakili dalam bentuk rentetan. Sintaks mungkin berbeza bergantung pada pangkalan data yang ingin anda sambungkan, tetapi kerana kami berinteraksi dengan MySQL/MariaDB, kami akan menyediakan:

  • Jenis pemandu yang hendak digunakan untuk sambungan
  • Nama hos mesin yang menganjurkan pangkalan data
  • Port untuk digunakan untuk sambungan (pilihan)
  • Nama pangkalan data
  • Charset (pilihan)

Format rentetan, dalam kes kami akan menjadi yang berikut (kami akan menyimpannya di $ dsn pembolehubah):

$ dsn = "mysql: host = localhost; port = 3306; dbName = solar_system; charset = utf8"; 
Salinan

Pertama sekali, kami menyediakan awalan pangkalan data. Dalam kes ini, kerana kami menyambung ke pangkalan data MySQL/MariaDB, kami menggunakan mysql. Kami kemudian memisahkan awalan dari seluruh rentetan oleh kolon dan setiap bahagian lain oleh titik koma.

Dalam dua bahagian berikutnya kami menentukan Nama Host mesin di mana pangkalan data dihoskan dan pelabuhan untuk digunakan untuk sambungan. Sekiranya yang terakhir tidak disediakan, lalai akan digunakan, yang, dalam hal ini adalah 3306. Sejurus selepas kami menyediakan Nama pangkalan data, Dan selepas itu, Charset untuk menggunakan.

Membuat objek PDO

Sekarang DSN kami sudah siap, kami akan membina Objek PDO. Pembina PDO mengambil rentetan DSN sebagai parameter pertama, nama pengguna pada pangkalan data sebagai parameter kedua, kata laluannya sebagai ketiga, dan pilihan pelbagai pilihan 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); 
Salinan

Walau bagaimanapun, pilihan boleh ditentukan juga selepas objek telah dibina, melalui SetAttribute () Kaedah:

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

Menetapkan tingkah laku PDO atas kesilapan

Mari kita lihat beberapa pilihan yang tersedia untuk Pdo :: attr_errmode. Pilihan ini sangat penting, kerana mentakrifkan tingkah laku PDO dalam hal kesilapan. Pilihan yang mungkin adalah:

Pdo :: errmode_silent

Ini adalah lalai. PDO hanya akan menetapkan kod ralat dan mesej ralat. Mereka boleh diambil dengan menggunakan kod salah() dan errorInfo () kaedah.

Pdo :: errmode_exception

Ini, pada pendapat saya, yang disyorkan. Dengan pilihan ini, sebagai tambahan kepada menetapkan kod ralat dan maklumat, PDO akan membuang PdoException, yang akan memecahkan aliran skrip, dan ia amat berguna sekiranya berlaku Transaksi PDO (Kami akan melihat urus niaga yang kemudian dalam tutorial ini).

Pdo :: errmode_warning

Dengan pilihan ini, PDO akan menetapkan kod ralat dan maklumat yang diindeks Pdo :: errmode_silent, tetapi juga akan mengeluarkan a Amaran, yang tidak akan memecahkan aliran skrip.

Menetapkan Mod Ambil Lalai

Satu lagi tetapan penting boleh ditentukan melalui pdo :: default_fetch_mode. malar. Ini membolehkan anda menentukan kaedah pengambilan lalai untuk digunakan apabila mengambil hasil dari pertanyaan. Ini adalah pilihan yang paling biasa digunakan:

Pdo :: fetch_both:

Ini adalah lalai. Dengan itu hasil yang diambil oleh pertanyaan pengambilan akan diindeks oleh integer dan dengan nama lajur. Memohon mod pengambilan ini apabila mengambil satu baris dari jadual planet akan memberi kami hasil ini:

$ stmt = $ pdo-> query ("pilih * dari planet"); $ hasil = $ stmt-> fetch (pdo :: fetch_both); 
Salinan
Array ([id] => 1 [0] => 1 [name] => bumi [1] => bumi [warna] => biru [2] => biru) 

Pdo :: fetch_assoc:

Dengan pilihan ini, hasilnya akan disimpan dalam Arahan bersekutu di mana setiap kunci akan menjadi nama lajur, dan setiap nilai akan menjadi nilai yang sama berturut -turut:

$ stmt = $ pdo-> query ("pilih * dari planet"); $ hasil = $ stmt-> fetch (pdo :: fetch_assoc);
Salinan
Array ([id] => 1 [name] => bumi [warna] => biru) 

Pdo :: fetch_num

Mod pengambilan ini mengembalikan baris yang diambil ke dalam Array 0-indeks:

Array ([0] => 1 [1] => Bumi [2] => Biru) 

Pdo :: fetch_column

Kaedah pengambilan ini berguna apabila mengambil hanya nilai lajur dan akan mengembalikan semua hasil di dalam pelbagai, satu dimensi array. Contohnya pertanyaan ini:

$ stmt = $ pdo-> query ("Pilih nama dari planet");
Salinan

Akan mengembalikan hasil ini:

Array ([0] => bumi [1] => mars [2] => Musytari) 

Pdo :: fetch_key_pair

Kaedah pengambilan ini berguna apabila mengambil nilai hanya 2 lajur. Ia akan mengembalikan hasil dalam bentuk array bersekutu di mana nilai -nilai yang diambil dari pangkalan data untuk lajur yang ditentukan pertama dalam pertanyaan, akan digunakan sebagai kunci array, sementara nilai yang diambil untuk lajur kedua, akan mewakili bersekutu Nilai Array:

$ stmt = $ pdo-> query ("Pilih nama, warna dari planet"); $ result = $ stmt-> fetchall (pdo :: fetch_key_pair); 
Salinan

Akan kembali:

Array ([bumi] => biru [mars] => merah [Musytari] => pelik) 

Pdo :: fetch_object:

Apabila menggunakan Pdo :: fetch_object malar, an objek tanpa nama akan dibuat untuk setiap baris yang diambil. Sifatnya (awam) akan dinamakan selepas lajur, dan hasil pertanyaan akan digunakan sebagai nilai mereka. Memohon mod ambil ini ke pertanyaan yang sama di atas akan mengembalikan hasil kami dalam bentuk:

$ hasil = $ stmt-> fetch (pdo :: fetch_obj);
Salinan
objek stdclass ([name] => bumi [warna] => biru) 

Pdo :: fetch_class:

Mod pengambilan ini, seperti di atas, akan memberikan nilai lajur kepada sifat objek, tetapi dalam hal ini kita harus menentukan kelas yang ada yang harus digunakan untuk membuat objek. Mari kita tunjukkan, pertama kita akan membuat kelas:

Kelas Planet Private $ Name; warna $ swasta; Fungsi awam setName ($ planet_name) $ this-> name = $ planet_name;  fungsi awam setColor ($ planet_color) $ this-> color = $ planet_color;  fungsi awam getName () return $ this-> name;  fungsi awam getColor () return $ this-> color;  
Salinan

Tolong abaikan kekeliruan kod di atas dan hanya perhatikan bahawa sifat kelas planet persendirian dan kelas tidak mempunyai pembina. Sekarang mari kita cuba mengambil hasilnya.

Semasa menggunakan ambil() dengan Pdo :: fetch_class anda mesti menggunakan setFechMode () Kaedah pada objek penyataan sebelum cuba mengambil data, sebagai contoh:

$ stmt = $ pdo-> query ("Pilih nama, warna dari planet"); $ stmt-> setFetchMode (pdo :: fetch_class, 'planet');
Salinan

Kami menyediakan pilihan pengambilan pilihan Pdo :: fetch_class sebagai hujah pertama kaedah setFetchMode (), dan nama kelas yang harus digunakan untuk membuat objek ('planet' dalam kes ini) sebagai yang kedua. Sekarang kita berlari:

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

Objek planet sepatutnya dibuat:

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

Perhatikan bagaimana nilai yang diambil dari pertanyaan, telah diberikan kepada sifat yang sepadan objek walaupun mereka adalah peribadi.

Menetapkan Hartanah Selepas Pembinaan Objek

Kelas planet tidak mempunyai pembina yang jelas, jadi tidak ada masalah ketika memberikan sifat -sifat; Tetapi bagaimana jika kelas mempunyai pembina di mana harta itu diberikan atau dimanipulasi? Oleh kerana nilai -nilai diberikan sebelum pembina dipanggil, mereka akan ditimpa.

PDO membantu menyediakan Fetch_props_late tetap: Apabila menggunakannya, nilai akan diberikan kepada sifat selepas Objek dibina. Sebagai contoh:

Kelas Planet Private $ Name; warna $ swasta; fungsi awam __construct ($ name = moon, $ color = kelabu) $ this-> name = $ name; $ this-> color = $ color;  fungsi awam setName ($ planet_name) $ this-> name = $ planet_name;  fungsi awam setColor ($ planet_color) $ this-> color = $ planet_color;  fungsi awam getName () return $ this-> name;  fungsi awam getColor () return $ this-> color; 
Salinan

Kami mengubahsuai kelas planet kami, menyediakan pembina yang mengambil dua hujah: yang pertama adalah nama Dan yang kedua adalah warna. Hujah -hujah itu mempunyai nilai lalai masing -masing bulan dan kelabu: ini bermaksud bahawa jika tiada nilai secara eksplisit disediakan, mereka akan menjadi lalai yang diberikan.

Dalam kes ini, jika kita tidak menggunakan Fetch_props_late, Tidak kira nilai yang diambil dari pangkalan data, sifat -sifatnya akan selalu mempunyai nilai lalai, kerana mereka akan ditimpa oleh objek yang dibina. Mari sahkan. Mula -mula kita menjalankan pertanyaan:

$ stmt = $ pdo-> query ("Nama pilih, warna dari solar_system di mana name = 'earth'"); $ stmt-> setFetchMode (pdo :: fetch_class, 'planet'); $ planet = $ stmt-> fetch ();
Salinan

Kemudian kami membuang Planet objek dan periksa nilai apa sifatnya:

var_dump ($ planet); Objek (planet)#2 (2) ["Nama": "Planet": Private] => String (4) "Moon" ["Warna": "Planet": Private] => String (4) "Grey" 
Salinan

Seperti yang dijangkakan, nilai yang diambil dari pangkalan data telah ditimpa oleh lalai. Sekarang, kami menunjukkan bagaimana masalah ini dapat diselesaikan dengan menggunakan Fetch_props_late (pertanyaan adalah sama seperti di atas):

$ stmt-> setFetchMode (pdo :: fetch_class | pdo :: fetch_props_late, 'planet'); $ planet = $ stmt-> fetch (); var_dump ($ planet); objek (planet)#4 (2) ["nama": "planet": private] => string (5) "bumi" ["warna": "planet": private] => string (4) "biru" 
Salinan

Akhirnya kami mendapat hasil yang diinginkan. Tetapi bagaimana jika pembina kelas tidak mempunyai nilai lalai, dan mereka mesti disediakan ? Sederhana: Kami boleh menentukan parameter pembina dalam bentuk array sebagai hujah ketiga, selepas nama kelas, dalam kaedah setFetchMode (). Sebagai contoh, biarkan perubahan pembina:

Kelas Planet Private $ Name; warna $ swasta; fungsi awam __construct ($ nama, $ warna) $ this-> name = $ name; $ this-> color = $ color;  [...]
Salinan

Argumen pembina kini wajib, jadi kami akan berjalan:

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

Dalam kes ini, parameter yang kami berikan berkhidmat hanya sebagai nilai lalai, yang diperlukan untuk memulakan objek tanpa kesilapan: mereka akan ditimpa oleh nilai yang diambil dari pangkalan data.

Mengambil pelbagai objek

Sudah tentu mungkin untuk mengambil pelbagai hasil sebagai objek, sama ada menggunakan ambil() kaedah di dalam gelung sementara:

manakala ($ planet = $ stmt-> fetch ()) // do thing dengan hasil 
Salinan

atau dengan mengambil semua keputusan sekaligus. Dalam kes ini, seperti yang dinyatakan di atas, menggunakan Fetchall () kaedah, anda tidak perlu menentukan mod pengambilan sebelum memanggil kaedah itu sendiri, tetapi pada masa ini anda memanggilnya:

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

Pdo :: fetch_into

Dengan set kaedah pengambilan ini, PDO tidak akan membuat objek baru, sebaliknya ia akan mengemas kini sifat -sifat yang ada, tetapi hanya jika mereka awam, atau jika anda menggunakan __Set kaedah sihir di dalam objek.

Penyataan langsung yang disediakan vs

PDO mempunyai dua cara untuk melaksanakan pertanyaan: satu adalah cara langsung, satu langkah. Yang lain, lebih selamat adalah menggunakan Kenyataan yang disediakan.

Pertanyaan Langsung

Apabila menggunakan pertanyaan langsung, anda mempunyai dua kaedah utama: pertanyaan () dan exec (). Bekas pulangan kembali a Pdostatemnt objek yang boleh anda gunakan untuk mengakses hasil melalui ambil() atau Fetchall () Kaedah: Anda menggunakannya untuk pernyataan yang tidak mengubah suai jadual, seperti Pilih.

Yang terakhir, sebaliknya, mengembalikan bilangan baris yang diubah dengan pertanyaan: kami menggunakannya untuk pernyataan yang mengubah baris, seperti Masukkan, Padam atau Kemas kini. Kenyataan langsung hanya akan digunakan apabila tidak ada pembolehubah dalam pertanyaan dan anda benar -benar mempercayai ia selamat dan betul melarikan diri.

Kenyataan yang disediakan

PDO menyokong juga dua peringkat, pernyataan yang disediakan: ini berguna apabila menggunakan pembolehubah dalam pertanyaan, dan ia lebih selamat secara umum, kerana Sediakan () kaedah akan melaksanakan semua yang diperlukan untuk kita. Mari lihat bagaimana pembolehubah digunakan. Bayangkan kita mahu memasukkan sifat objek planet ke dalam Planet Jadual. Pertama kita akan menyediakan pertanyaan:

$ stmt = $ pdo-> Sediakan ("Masukkan ke dalam planet (nama, warna) nilai (?, ?) "); 
Salinan

Seperti yang dikatakan sebelum ini, pertama kita akan menggunakan Sediakan () kaedah yang mengambil pertanyaan SQL sebagai hujah, menggunakan ruang letak untuk pembolehubah. Sekarang ruang letak boleh mempunyai dua jenis:

Tempat letak posisional

Semasa menggunakan ? tempat letak posisi kita boleh mendapatkan lebih banyak kod ringkas, tetapi kita mesti memberikan nilai -nilai yang akan digantikan dengan urutan yang sama dari nama lajur, dalam array yang disediakan sebagai argumen kepada Jalankan () Kaedah:

$ stmt-> Execute ([$ planet-> name, $ planet-> color]); 
Salinan

Dinamakan tempat letak

Menggunakan Dinamakan tempat letak, Kita tidak perlu menghormati pesanan tertentu, tetapi kita akan membuat lebih banyak kod verbose. Semasa melaksanakan Jalankan () kaedah kita harus memberikan nilai dalam bentuk suatu Arahan bersekutu di mana setiap kunci akan menjadi nama pemegang tempat yang digunakan, dan nilai yang berkaitan adalah yang akan digantikan dalam pertanyaan. Contohnya pertanyaan di atas akan menjadi:

$ stmt = $ pdo-> siapkan ("masukkan ke dalam planet (nama, warna) nilai (: nama ,: warna)"); $ stmt-> Execute (['name' => $ planet-> name, 'color' => $ planet-> color]); 
Salinan

Kaedah menyediakan dan melaksanakan boleh digunakan kedua -duanya semasa melakukan pertanyaan yang mengubah atau hanya mengambil data dari pangkalan data. Dalam kes bekas kita menggunakan kaedah pengambilan yang kita lihat di atas untuk mengambil data, sementara di dalamnya kita dapat mengambil bilangan baris yang terjejas dengan menggunakan ROWCOUNT () kaedah.

Kaedah bindValue () dan bindParam ()

Untuk memberikan nilai yang akan digantikan dalam pertanyaan, kami juga boleh menggunakan BindValue () dan bindParam () kaedah. Yang pertama mengikat nilai pembolehubah yang diberikan kepada tempat yang berkaitan atau bernama tempat yang digunakan semasa menyiapkan pertanyaan. Menggunakan contoh di atas yang akan kami lakukan:

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

Kami mengikat nilai $ planet-> nama kepada : nama pemegang tempat. Perhatikan bahawa menggunakan kedua -dua kaedah bindValue () dan bindParam () yang boleh kita tentukan, sebagai hujah ketiga, Jenis pembolehubah, menggunakan pemalar PDO yang berkaitan, dalam kes ini Pdo :: param_str.

Menggunakan bindParam (), Sebaliknya, kita boleh mengikat pemboleh ubah kepada pemegang tempat yang berkaitan yang digunakan semasa menyiapkan pertanyaan. Perhatikan bahawa dalam kes ini pemboleh ubah terikat dengan rujukan, dan nilainya hanya akan digantikan dengan pemegang tempat pada masa itu Jalankan () kaedah ia dipanggil. Sintaks adalah sama seperti di atas:

$ stmt-> bindParam ('nama', $ planet-> nama, pdo :: param_str) 
Salinan

Kami mengikat pembolehubah nama $ planet-> ke : nama pemegang tempat, bukan nilai semasa! Seperti yang dikatakan di atas penukaran akan dilakukan hanya apabila Jalankan () kaedah akan dipanggil, jadi pemegang tempat akan digantikan dengan nilai pembolehubah yang ada pada masa itu.

Transaksi PDO

Urus niaga menyediakan cara untuk mengekalkan konsistensi semasa mengeluarkan pelbagai pertanyaan. Semua pertanyaan dilakukan dalam "batch", dan komited untuk pangkalan data hanya jika semuanya berjaya. Urus niaga tidak akan berfungsi dalam semua pangkalan data dan bukan untuk semua SQL membina, kerana sesetengah daripada mereka menyebabkan dan komitmen tersirat (senarai penuh di sini)

Dengan contoh yang melampau dan pelik, bayangkan pengguna perlu memilih senarai planet, dan setiap kali dia mengemukakan pilihan baru, anda ingin memadam yang sebelumnya dari pangkalan data sebelum memasukkan yang baru. Apa yang akan berlaku jika penghapusan berjaya, tetapi bukan penyisipan? Kami akan mempunyai pengguna tanpa planet! Biasanya ini adalah bagaimana urus niaga dilaksanakan:

$ pdo-> begIntransaction (); cuba $ stmt1 = $ pdo-> exec ("padam dari planet"); $ stmt2 = $ pdo-> siapkan ("masukkan ke dalam planet (nama, warna) nilai (?, ?) "); foreach ($ planet sebagai $ planet) $ stmt2-> Execute ([$ planet-> getName (), $ planet-> getColor ()]); $ pdo-> commit (); Catch ( PdoException $ e) $ pdo-> rollback ();
Salinan

Pertama dari semua BegIntransaction () Kaedah objek PDO melumpuhkan pertanyaan AutoCommit, kemudian di dalam blok percubaan, pertanyaan dilaksanakan dalam urutan yang dikehendaki. Pada ketika ini jika tidak PdoException dibangkitkan, pertanyaan dilakukan dengan melakukan () kaedah, jika tidak, melalui kembalikan() kaedah, urus niaga dikembalikan dan autocommit dipulihkan.

Dengan cara ini selalu ada konsistensi ketika mengeluarkan banyak pertanyaan. Agak jelas bahawa anda boleh menggunakan urus niaga PDO hanya apabila Pdo :: attr_errmode ditetapkan ke Pdo :: errmode_exception.

Tutorial Linux Berkaitan:

  • Perkara yang hendak dipasang di Ubuntu 20.04
  • Cara menukar kata laluan pengguna Mariadb
  • Cara membuat timbunan lampu berasaskan Docker menggunakan Docker pada ..
  • Pemasangan ampache raspberry pi
  • Pengenalan kepada Automasi, Alat dan Teknik Linux
  • Pemasangan WordPress OpenLiteSpeed
  • Perkara yang perlu dilakukan setelah memasang ubuntu 20.04 Focal Fossa Linux
  • Ubuntu 20.04 WordPress dengan pemasangan Apache
  • Ubuntu 20.04: WordPress dengan pemasangan nginx
  • Pasang mysql di Ubuntu 20.04 LTS Linux