Vue.js ve PHP İle MySQL Database İşlemleri

Temel Vue.js ve PHP İşlemleri başlıklı yazıda Vue.js işlemlerini bir PHP dosyasına klasik yöntemle (cdn) etmiş, vue-router ve Axios ile uygulamaya çeşitli yetenekler kazandırmıştık.

AA

Yazının son bölümünde de belirttiğim üzere, PHP işlemlerini biraz daha detaylandırıp Vue.js içerisinde anlamlı eylemler gerçekleştireceğiz. Bu yazının konusu olarak, uzak bir MySQL veritabanına bağlanacak (PDO ile), listeleme, ekleme, silme ve düzenleme işlemlerini örneklendirmeye çalışacağım. Mümkün olduğu kadar kodları basit tutmaya çalışacağım. İlerleyen zaman içerisinde ilgili işlemi bir başka yazı altında (benzer örneği MySQL yerine Firebase ile yineleyeceğim) yeniden ele alacağım (refactoring).

PHP İle MySQL Database İşlemleri

MySQL işlemlerini PHP Veri Nesneleri (PDO) eklentisi ile sağlayacağız. PDO arayüzü tanımı bir veri erişimli soyutlama katmanı sağlar. Bu sayede kullandığımız veritabanından bağımsız olarak sorguları çalıştırmak ve sonuçları döndürmek için aynı işlevleri kullanabiliriz. DB işlemlerini db4free.net uzak bağlantı (remote) ile gerçekleştirebiliriz. Aşağıda konu ile ilgili daha önce yayınlanmış bazı yazıları görebilirsiniz.

Gelim PDO ile veritabanı erişiminin sağlanmasına. PDO, hatalarla ilgili istisnalar atabilir. Bu nedenle işlemler genellikle try / catch bloğunda tutulur.

try {
      $db = new PDO("mysql:host=db4free.net:3306;dbname=vuedb_01;charset=utf8", "vuedbuser", "vuedbproject_01");
  } catch ( PDOException $e ){
      print $e->getMessage();
  }

Bir sonraki aşamada method bilgisini edinmemiz gerekir ki POST ve GET‘e göre tanılamalar yapabilelim; $_SERVER['REQUEST_METHOD'] bize ihtiyaç duyduğumuz request method bilgisini verecektir.

switch ($method) {
   case 'GET':
    ...
   break;
   case 'POST':
    ...
   break;
   defaut:
    http_response_code(404);
}

Switch ile method’lara göre tanımlamalarımızı oluşturabiliriz. PHP ile PUT ve DELETE için ayrı işlemler gerçekleştirmek gerekiyor1. Örnekte işlemleri GET ve POST üzerinden yürütmeye devam edeceğim. Listeleme ile başlayalım. rowCount() ile kayıt olup olmadığını kontrol edip $query ile edindiğim verileri $json‘a aktaralım. $id bir değere sahipse ilgili satırı, değilse tüm satırları listelesin.

$query = $db->query("SELECT * FROM contacts".($id ? " WHERE id=$id" : ''), PDO::FETCH_OBJ);

if ( $query->rowCount() ){
      foreach ($query as $row) {
            $json[] = [
                  'id' => $row->id,
                  'name' => $row->name,
                  'email' => $row->email,
                  'country' => $row->country,
                  'city' => $row->city,
                  'job' => $row->job
            ];
      }
}

$query‘de yer alan PDO::FETCH_OBJ özellik isimlerinin sınıf isimlerine denk düştüğü bir anonim nesne örneği döndürür2. Dönen nesneyi $json‘a aktarmıştık. Son adımda json_encode($json) ile json formatı dönüştürme işlemini gerçekleştirmiş oluruz.

Şimdi bu bilgileri bir dosyada toplamamız lazım. Dosyamızın adı api.php olsun. Dosyamız bir json dökümanı gibi değerlendirilmeli. Dolayısıyla Content-type: application/json kullanacağız. Son olarak, tüm bu işlemlerin yanı sıra veritabanıyla işimiz bittiğinde oluşturduğumuz bağlantıyı sonlandırmayı unutmamalıyız. Dosyamızı bu bilgiler ışığında toparlayalım.

Şimdi, Postman ile GET request gerçekleştirelim ve api.php‘nin (endpoint) bize ne gibi bilgiler döneceğini görelim.

Postman GET Request

Her şey yolunda. O halde, api.php dosyasının POST request durumunda edindiği form verilerini (Content-Type': 'multipart/form-data) insert etmesini sağlayalım.

if ($name && $email) {
        $query = $db->prepare("INSERT INTO contacts (name, email, country, city, job) VALUES (:name, :email, :country, :city, :job)");
        $query->execute(['name' => $name, 'email' => $email, 'country' => $country, 'city' => $city, 'job' => $job]);
        if($query) {
                $json[] = [
                  'id' => $db->lastInsertId(),
                  'name' => $name,
                  'email' => $email,
                  'country' => $country,
                  'city' => $city,
                  'job' => $job,
                  'message' => "Contact added successfully"
                ];
          } else {
            $json[] = ['error' => "Contact insert failed!"];
          }
        } else{
          $json[] = ['error' => 'Error: Name and E-mail are required!'];
        }

POST request kontrolü için Postman body / form-data ile çeşitli veriler göndererek nasıl dönüşler alacağımıza bir bakalım.

Postman POST Request

Evet, görüldüğü üzere form üzerinden gönderdiğimiz veriler veritabanına kayıt edilmekte. İlgili dosyanın güncel halini görüntülemek için burayı tıklayabilirsiniz.

Şimdi, tüm bu adımları Vue ve Axios ile yürütmeye başlayabiliriz.

Vue.js ve Axios Kullanımı

Bir önceki örnekte Axios ile get ve post işlemleri gerçekleştirmiştik. Bu yazıda var olan işlemleri genişletecek ve MySQL veritabanında kayıtlı olan verileri işleyeceğiz. Instance’imiz şu şekilde:

var app = new Vue({
  el: '#app',
  data() {
    return {
      isActive: false,
      contact: {
        id: '',
        name: '',
        email: '',
        country: '',
        city: '',
        job: ''
      },
      contacts: [],
      currentContact: [],
      fields: ['Position', 'ID', 'Name', 'E-mail', 'Country', 'City', 'Job', 'Manage'],
    }
  },
});

Mümkün olduğu kadar örneği farklı tanımlamalara gerçekleştirmeye çalıştım. Bazı alanlarda kod tekrarları mevcut. Hatta UPDATE ve INSERT işlemleri tek method ile işlenebilir. Şimdilik anlatımı kolay tutabilmek için ayrı tutacağım. Yazının girişinde de bahsettiğim gibi, Firebase kullanım örneğinde kod yeniden ele alınacağı için karşılaştırma da yapılabilir.

Arayüz işlemlerini Bulma CSS ile gerçekleştireceğim. Listelemeyi bu framework’ün tablo yapısı çerçevesinde şu şekide sunabiliriz.

      <table class="table is-bordered is-hoverable is-fullwidth">
        <thead><tr><th v-for="field in fields" v-text="field"></th></tr></thead>
        <tbody>
          <tr v-if="!contacts.length"><td colspan="7">Veriler getiriliyor...</td></tr>
          <tr v-for="(contact, index) in contacts" :key="index" v-else>
            <th>{{ index+1 }}</th>
            <td>{{ contact.id }}</td>
            <td>{{ contact.name }}</td>
            <td>{{ contact.email }}</td>
            <td>{{ contact.country }}</td>
            <td>{{ contact.city }}</td>
            <td>{{ contact.job }}</td>
          </tr>
        </tbody>
        <tfoot><tr><th v-for="field in fields" v-text="field"></th></tr></tfoot>
      </table>

Yeni contact ekleme işlemini bir modal üzerinden sağlayacağım. data içeriğindeki isActive modal’in is-active class’ını kontrol etmekte.

<div class="modal" :class="{'is-active': isActive}">...</div>

Modal içeriğinde yer alan form contact nesnesi ile bind edilmekte ve son olarak addContact() metotu ile axios aracılığıyla POST olarak api.php dosyasına iletilmekte.

addContact: function () {
      let formData = new FormData();

      formData.append('name', this.contact.name)
      formData.append('email', this.contact.email)
      formData.append('city', this.contact.city)
      formData.append('country', this.contact.country)
      formData.append('job', this.contact.job)

      var contact = {};
      formData.forEach(function (value, key) {
        contact[key] = value;
        console.log(contact[key]);
      });

      axios({
          method: 'post',
          url: 'api/test.php',
          data: formData,
          config: {
            headers: {
              'Content-Type': 'multipart/form-data'
            }
          }
        })
        .then(function (response) {
          console.log(response)
          app.contacts.push(app.contact)
          app.resetForm();
          app.getContacts();
        })
        .catch(function (response) {
          console.log(response)
        });
    },
});

getContacts() ise hem mounted olarak hem de ekleme işlemi başarılı olduğunda çağırılan bir diğer metotumuz.

   getContacts: function () {
      axios.get('api/test.php')
        .then(function (response) {
          console.log(response.data);
          app.contacts = response.data;
        })
        .catch(function (error) {
          console.log(error);
        });
    }

Yukarıdaki işlemleri app.js adında bir dosya üzerinden yürütebilirsiniz. Oluşturulan dosyanın son haline burayı tıklayarak ulaşabilirsiniz.

Evet, uygulamamız hazır. İlgili uygulamayı (CRUD) Gitlab üzerinden görüntüleyebilir, git clone ile indirerek hemen test edebilirsiniz. Daha fazla örneğe ise Vue-Examples üzerinden ulaşabilirsiniz.

İleri Okumalar

  1. HTTP protocol’s PUT and DELETE and their usage in PHP
  2. REST Webservice: PUT & Delete methods
  3. axios: Promise based HTTP client for the browser and node.js
  4. Fetch records from MySQL Database with Vue.js and PHP