SQL’de Sonraki ve Önceki Satırdaki Veriyi Getirmek

Bir gönderi/blog sistemi düşünelim. Hatta WordPress’ten örnekleyebiliriz. Bazı bloglarda, bir gönderiye girdiğimizde sonraki ve önceki gönderiler için bağlantı olduğunu görürüz. Bunlar için ayrı veriler çekmemiz gerekiyor. Örnek verirken bir model dosyasında kod yazıyormuş gibi örnekleyeceğim, SQL kodundan yola çıkarak sizde geliştirebilirsiniz.

text-transform: uppercase ve Türkçe Karakter

CSS’de text-transform: uppercase özelliğini kullanmak istediğimizde, bazı tarayıcılarda, bazen türkçe karakterleri büyük harfe çevirmiyor. Bunun çözümü, HTML’de parametresini kullanmak.

<!DOCTYPE html>
<html lang="tr">
...

Yaptığımız vakit türkçe karakterler yani i harfi I olarak değil, İ olarak büyüyecektir. Aynı zamanda bu özelliği diğer etiketlerde de kullanabiliyoruz. Örn.

<h1 lang="tr" style="text-transform: uppercase">
Türkçe Karakter Denemesi işüğçö
</h1>

Kolay gelsin.

SQL’de Gün İçindeki/Bugüne Ait Kayıtları Listelemek

SQL’de gün içindeki kayıtları listelemek için şöyle bir sorgu gerekiyor:

SELECT * FROM kayitlar WHERE DATE(tarih) = CURDATE()

Bu sorgu, o gün içindeki kayıtları listeliyor. Yani bugün ayın 5’i ise, 5’inde girilen kayıtları gösteriyor.

Bir diğer kullanım ise, son bir günlük kayıtları göstermek. Sorguyu inceleyelim:

SELECT * FROM kayitlar WHERE tarih > DATE_SUB(CURDATE(), INTERVAL 1 DAY)

Bu sorguda son bir gün, yani 24 saatlik kayıtları listeliyor. 1 DAY yazan yeri 1 WEEK yaparak bir haftalık kayıtları, 1 MONTH yazarak son bir aylık kayıtları alabiliyoruz.

Veritabanındaki Tablonun Varlığını Kontrol Etmek

PHP’de PDO ile çalışırken bir tablonun var olup olmadığını kontrol etmek için aşağıdaki yöntem kullanılabilir:

public function checkTable()
{
  try {
    return $this->fetchRow('SELECT * FROM posta');
  } catch(\Exception $e) {
    return false;
    // Veya $this->exec('CREATE TABLE IF NOT EXISTS posta ...');
  }
}

Bir kurulum aşamasında, veritabanındaki tabloları yapılandırma sırasında işe yarayabilir.

PHP ile PDO Sorgu Hatalarını Yakalamak

PHP PDO uzantısını kullanırken, try/catch blokları içerisinde veritabanı bağlantısında oluşabilecek hataları şu şekilde yakalayabiliyoruz.

try {
  $pdo = new \PDO($dsn, $user, $pass);
} catch (\PDOException $e) {
  throw new \Exception('Bağlantı hatası: ' . $e->getMessage());
}

Fakat sorgulardaki hataları bu şekilde yakalayamıyoruz maalesef. Sorgu hatalarını yakalamak için, PDO bağlantısının hemen altına aşağıdaki gibi bir metodla tanımlama yapmamız gerekiyor:

$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);

Bunu yaptıktan sonra, aşağıdaki gibi sorgu hatalarını yakalayabiliyoruz:

try {
  $query = $pdo->prepare('SELECT * FROM post');
  $query->execute();
  $posts = $query->fetchAll();
} catch (\PDOException $e) {
  throw new \Exception('Sorgu hatası: ' . $e->getMessage());
}

gibi. Kolay gelsin.

PHP Mgk Kod Çatısı

PHP Mgk Çatısı olarak isimlendirdiğim bu küçük PHP uygulaması, herkesin bildiği basit bir PHP Framework’tür. Bu PHP çatısını yazmamdaki esas sebep, bu işlerle uğraşırken, PHP’de Çatı (Framework) hakkında yeterli türkçe kaynak bulamamamdı. Hiç yok değildi, ama var olanlar da maalesef ingilizce kod yapısına sahipti ve ben de ingilizceye hakim değildim. Belli zaman zarfında ingilizce kod yazmaya başladım ve değişken/fonksiyon/metod isimlerini ingilizce yazmaya devam ettim ve bu şekilde de insanları yönlendirdim.

Şimdiyse Mgk adında bir çatı yazdım ve yayınladım. Mgk; Model/Görünüm/Kontrol katmanlarının kısaltılmış hali. Aslında farklı kelimelerle de kısaltılabilirdi ama böyle uygun gördüm.

Neden Mgk? Çünkü, insanların artık düzenli kod yazmaları gerekiyor. İnsanlar genellemesinden bahsettiğim kısım, yeni başlayanlar, forum tayfaları ve ek iş yaparak makarna kod yazan insanlar. Belki farkındalar Model/Görünüm/Kontrol katmanıyla kod yazmanın daha iyi olduğunu ama bir türlü yanaşamıyorlar. Bunun sorumlusu, bu şekilde kod yazanların bildiklerini yeterli şekilde paylaşmamaları aslında.

Burada bundan sonra PHP Mgk Çatısı hakkında bilgiler verip, yeni uygulamalar hakkında, elimden geldiğince PHP’ye yeni başlayanların da anlayacağı şekilde, özellikle amatör bir ruhla bazı şeyler paylaşmayı planlıyorum.

Umarım birilerine yardımcı olurum. Paylaşmayı ve dayanışmayı büyütmek ümidiyle.

Github’da: https://github.com/yidemir/PHP-Mgk
İndirmek için: https://github.com/yidemir/PHP-Mgk/releases

Sublime Text Klasör/Dosya Listesi Problemi

Mac üzerinde Sublime Text 2 metin/kod editörünü kullanıyorum. Öncedir çok rastladığım bir problem vardı ve şu an devamlı aynı sıkıntıyla karşılaşıyorum. Sublime Text, dosya yöneticisi kısmında yeni oluşturduğum dosyaları listeye dahil etmiyor yani güncellemiyor. Biraz çözüm aradım ama pek kayda değer bir şey çıkmadı.

Geçici bir çözüm olarak klavye kısayolu atayarak dosya listesini yenilemesini sağladım. Sublime Text 2 -> Preferences -> Key Bindings - User yolundan kısyolların bulunduğu dosyayı açıp kısayol tanımladım.

[
    {"keys": ["command+shift+r"], "command": "refresh_folder_list"}
]

Ben Mac kullandığım için CMD Shift ve R kombinasyonu ile yenilemeyi tercih ettim. Windows/Linux kullanıcıları ctrl+shift+r ya da kendilerine uygun bir kısayol belirleyebilirler.

Kolay gelsin.

Girdi Değerini Büyük Harfe Çevirmek

Merhaba, JavaScript ile girdi değerini büyük harfe çevirme ihtiyacı duydum. Daha önceden de karşılaşmıştım. Bu sefer Angular JS ile gerekti. Ama ben hepsini burada yazacağım.

<input type="text" onKeyup="this.value = this.value.replace('i','İ').toUpperCase()">

Yukarıda özellikle i harfini İ harfine değiştirdim (replace). Çünkü ingilizce karakter olan i, değiştirmediğimde I harfine çevriliyor.

jQuery ile

$(function() {
    $('input').keyup(function() {
        this.value = this.value.replace('i','İ').toUpperCase();
    });
});

Güncelleme: Yazıldıktan sonra değil de, yazıldığı anda büyük harf yazılması için şu da uygundur:

$('.buyukHarf').on('input', function(evt) {
  $(this).val(function (_, val) {
    return val.replace('i', 'İ').toUpperCase();
  });
});

Angular JS ile

$scope.girdi = $scope.girdi.replace("i", "İ").toUpperCase();

Kolay gelsin.

PHP’de PDO Veritabanı İşlemleri Sınıfı

Dikkat: Bu yazıyı ve kodları yazmamın üzerinden seneler geçti. Bu sebepten bu sınıf güncel işlemleri yapabilecek kapasiteye sahip değil. Bu sınıftan sonra daha gelişmiş birkaç sınıf daha yazdım (blog içerisinden ulaşabiirsiniz), bu sınıflardan faydalanmanız daha sağlıklı olacaktır; iyi çalışmalar.

Çok kullandığım veritabanı işlemleri için bir sınıf yazdım. Bu PHP sınıfı sayesinde veri çekme, listeleme, ekleme, güncelleme ve silme işlemlerini hızlıca alabiliyorum. Kodları aşağıda paylaştıktan sonra nasıl kullanıldığına dair bilgiler vereceğim.

<?php
/**
 * Hızlı Veritabanı İşlemleri
 * @author Yılmaz Demir
 * @link http://yilmazdemir.com.tr
 * @version 0.1
 */

class Database extends PDO {
	/**
	 * Veritabanı bilgilerine ait sabitler
	 * Kendinize göre düzenleyebilirsiniz
	 */
	const DB_HOST = "localhost";
	const DB_NAME = "veritabaniadi";
	const DB_USER = "kullaniciadi";
	const DB_PASS = "sifre";

	// Tablodaki asıl anahtar (Primary key)
	const PK = "id";

	public $query;

	/**
	 * Başlatıcı
	 * PDO veritabanı bağlantısı kurar
	 * Karakter setini UTF-8 olarak belirler
	 * Olası hatada çalışmayı durdurur
	 */
	public function __construct()
	{
		try {
			parent::__construct(
				"mysql:host=" . 
				self::DB_HOST . 
				";dbname=" . 
				self::DB_NAME, 
				self::DB_USER, 
				self::DB_PASS,
				array(
					PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8",
					PDO::MYSQL_ATTR_INIT_COMMAND => "SET CHARACTER SET utf8"
					)
				);
		} catch (PDOException $e) {
			exit($e->getMessage());
		}
	}

	/**
	 * Tablo adına ve koşullara göre tek satır veri döndürür
	 * @param string $table Tablo adı
	 * @param string $conditions Şartlar (WHERE id=? gibi)
	 * @param array $parameters Parametreler (array(1) gibi)
	 * @return object Obje şeklinde döndürür ($post->title gibi)
	 */
	public function getOne($table, $conditions = null, $parameters = [])
	{
		$this->query = $this->prepare("SELECT * FROM " . $table . " " . $conditions);
		$this->query->execute($parameters);
		return $this->query->fetch(PDO::FETCH_OBJ);	
	}

	/**
	 * Tablo adına ve koşullara göre çoklu veri döndürür
	 * @param string $table Tablo adı
	 * @param string $conditions Şartlar (type=? gibi)
	 * @param array $parameters Parametreler (array("post") gibi)
	 * @return object Obje şeklinde döndürür ($post->title gibi)
	 */
	public function getAll($table, $conditions = null, $parameters = [])
	{
		$this->query = $this->prepare("SELECT * FROM " . $table . " " . $conditions);
		$this->query->execute($parameters);
		return $this->query->fetchAll(PDO::FETCH_OBJ);
	}

	/**
	 * Tabloya yeni veri eklemek için kullanılır
	 * @param string $table Tablo adı
	 * @param array $data Dizi şeklinde sütun adları
	 * ve karşılarında veriler olmak üzere
	 * @return int Son eklenen verinin ID'sini döndürür
	 */
	public function insert($table, $data)
	{
		$values = array();
		$columns = array();
		foreach ($data as $column => $value) {
			$values[] = $value;
			$columns[] = $column;
		}

		$columns = implode(",", $columns);
		$marks = trim(substr(str_repeat("?,", count($values)), 0, -1));

		$this->query = $this->prepare("INSERT INTO " . $table . " (" . $columns . ") VALUES (" . $marks . ")");
		if ($this->query->execute($values)) {
			return $this->lastInsertId();
		}
		return false;
	}

	/**
	 * Tablodaki veriyi güncellemek için kullanılır
	 * @param string $table Tablo adı
	 * @param int $id Güncellenecek verinin ID'si
	 * @param array $data Dizi şeklinde sütun adları
	 * ve karşılarında veriler olmak üzere
	 * @return int Güncellenen verinin ID'sini ya da false döndürür
	 */
	public function update($table, $id, $data)
	{
		$values = array();
		$columns = array();
		foreach ($data as $column => $value) {
			$values[] = $value;
			$columns[] = $column;
		}

		$columnsAndMarks = implode("=?,", $columns) . "=?";

		$this->query = $this->prepare("UPDATE " . $table . " SET " . $columnsAndMarks ." WHERE " . self::PK . "=" . $id);
		if ($this->query->execute($values)) {
			return $id;
		}
		return false;
	}

	/**
	 * Tablodaki veriyi silmek/kaldırmak için kullanılır
	 * @param string $table Tablo adı
	 * @param int $id Silinecek verinin ID'si
	 * @return int Silinen verinin ID'sini ya da false döndürür
	 */
	public function delete($table, $id)
	{
		$this->query = $this->prepare("DELETE FROM " . $table . " WHERE " . self::PK . "=" . $id);
		if ($this->query->execute()) {
			return $id;
		}
		return false;
	}

	/**
	 * Tablo adına ve koşullara göre satır sayısını döndürür
	 * @param string $table Tablo adı
	 * @param string $conditions Şartlar (WHERE type=? gibi)
	 * @param array $parameters Parametreler (array("post") gibi)
	 * @return int Kaç satır veri olduğunu döndürür
	 */
	public function count($table, $conditions = null, $parameters = [])
	{
		$this->query = $this->prepare("SELECT * FROM " . $table . " " . $conditions);
		$this->query->execute($parameters);
		return $this->query->rowCount();
	}
}

Sınıfın kullanımı

Veri çekme

Sınıf içerisindeki getOne() methodu ile tek satırlık veri çekiyoruz. Kullanımı:

$db = new Database;
$gonderi = $db->getOne("gonderi", "WHERE id=?", array(5));
echo $gonderi->baslik;

Veri Listeleme

getAll() methodu ile bütün gönderileri çekebiliyoruz. Parametrelerle şartlar belirlenebiliyor.

$db = new Database;
$gonderiler = $db->getAll("gonderi", "WHERE taslak=?", array(0));
foreach ($gonderiler as $gonderi) {
	echo $gonderi->baslik . "<br/>";
}

Veri Ekleme

insert() methodu ile veri ekleyebiliyoruz.

$db = new Database;
$id = $db->insert("gonderi", array(
	"baslik" => "Gönderi Başlığı",
	"icerik" => "<p>Gönderi İçeriği</p>",
	"taslak" => 1
	)
);

echo $id ? $id . " ID'li gönderi eklendi." : "Gönderi eklenemedi";

Veri Güncelleme

update() methodu ile veri güncelleyebiliyoruz. İkinci parametre düzenlenecek gönderinin ID’sini alıyor.

$id = 5;
$db = new Database;
$guncelle = $db->update("gonderi", $id, array(
		"baslik" => "Güncellenen başlık",
		"icerik" => "<p>Güncellenen içerik</p>",
		"taslak" => 0
	)
);

echo $guncelle ? "Gönderi başarıyla güncellendi" : "Güncelleme başarısız";

Veri Silme

Verileri silmek için delete() methodundan faydalanabiliriz.

$id = 5;
$db = new Database;
$sil = $db->delete("gonderi", $id);
echo $sil ? "Gönderi silindi" : "Silme başarısız";

 Toplam Sayısı Alma

Toplam satır sayısı için count() methodunu kullanabiliriz. Parametre de eklenebiliyor.

$db = new Database;
$sayi = $db->count("gonderi");
echo "Toplamda " . $sayi . " adet gönderi bulunuyor";

Ek olarak, dikkat edilmesi gereken diğer bir nokta sınıf içerisindeki PK sabitini belirlemek gerekiyor. Ben asıl anahtar (primary key) olarak id adını kullanıyorum. Farklı bir isim kullanılıyorsa örn. tblId ise, bu şekilde değiştirilmesi gerekiyor.

Kolay gelsin.