PHP’de explode Fonksiyonu

PHP’de en çok karşıma çıkan fonksiyonlardan birisi olan explode() fonksiyonu hakkında bir kaç kelam etmek gerekiyor. Bu fonksiyonun kullanım amacı, belirli bir karakteri kullanarak bu karakteri içeren dizgeyi parçalara ayırıp dizge haline getirmek.

(PHP 4, PHP 5, PHP 7)
explode — Bir dizgeyi bir ayraca göre bölüp bir dizi haline getirir

Kullanımı

explode(dizge $ayraç, dizge $dizge)

Örneklemelerle kullanımını anlayalım. Örneğin bir formdan etiketler alanı gelmiş olsun. Bu etiketleri virgül yardımıyla parçalara ayırıp dize haline getirelim.

// Örnek POST alan içeriği: php dersleri, fonksiyonlar, nasıl yapılır, içerik
$etiketler = $_POST['etiketler'];

// , karakteriyle dizgeyi bölüyoruz
$etiketlerDizesi = explode(',', $etiketler);
// Her dizge öğesine trim() fonksiyonu uyguluyoruz
// bu fonksiyon, sağdaki ve soldaki boşlukları temizler
$etiketlerDizesi = array_map('trim', $etiketlerDizesi);

// Dizge içeriğini ekrana yazdıralım:
print_r($etiketlerDizesi);

/* 
Sonuç olarak dönen değer şu olacaktır:
Array
(
    [0] => php dersleri
    [1] =>  fonksiyonlar
    [2] =>  nasıl yapılır
    [3] =>  içerik
)
*/

explode Fonksiyonunun Kullanım Alanları

Nerelerde kullanıyoruz bu fonksiyonu hemen söyleyelim. Örneğin, URL barındaki adresi anlamak için kullanıyoruz ya da belli karakterlerle listelenmiş bir yazıyı parçalara bölmek için kullanıyoruz. Ben, örnek olarak basit bir yöntemi anlatacağım. Bu anlatacağım yöntemde URL satırındaki adresi alıp, daha anlaşılabilir hale getireceğiz.

Bahsedeceğim örnekte, modül ve bölüm sistemi olacak. Modüller, anasayfa, haber, galeri gibi kök yöneticiler, bölümler ise alt yöneticileri olacak. Yani örneğin haber modülü için haberGoster, haberEkle gibi ek bölümler olacak.


// Eğer rota varsa rotadır, yoksa kök halindedir
$rota = isset($_GET['rota']) ? $_GET['rota'] : '/';
// Burada explode ile / karakterini kullanara dizgeyi böldük
$rotalar = explode('/', $rota);
// Eğer dize içindeki ilk rota boşsa diziden çıkaralım
// array_shift fonksiyonu dizideki ilk öğeyi çıkarır
if (empty($rotalar[0])) array_shift($rotalar);

// Burada modül eğer varsa ve boş değilse modüldir, değilse geçerli olarak anasayfa'dır
$modul = isset($rotalar[0]) && !empty($rotalar[0]) ? $rotalar[0] : 'anasayfa';
// Burada aynı şekilde modül gibi varsa vardır yoksa giriş'dir
$bolum = isset($rotalar[1]) && !empty($rotalar[1]) ? $rotalar[1] : 'giris';

// Yukarıdaki işlemin diğer bir kullanımı şöyledir:
$modul = null;
if (isset($rotalar[0]) && !empty($rotalar[0])) {
	$modul = $rotalar[0];
} else {
	$modul = 'anasayfa';
}

Yukarıdaki örneği olabildiğince basite indirgediğim için işimizi tam anlamıyla ve sürekli olarak görmeyebilir ama anlamak açısından iyi gelebilir. MVC çatıları sayfanın ne olduğunu explode fonksiyonu ile anlar ve işlemi buna göre yönlendirirler.

PHP’de array_sum Fonksiyonunu Alt Dizelerde Kullanmak

PHP’de array_sum fonksiyonu kullanmam gerekti. Ama normal kök dizide değilde, alt dizideki değerleri toplamam gerekiyordu.

array_sum fonksiyonu ne işe yarar?
Bu fonksiyon bir dize içerisindeki değerlerin toplamını döndürür.

Örnek senaryo, her müşteriye ait tutar/bakiye değerlerini listeleyip hepsinin toplamını en son göstermek.

['Müşteri' => ['Tutar' => 150.00, 'Bakiye' => 360.00]]

<?php
$amount = [];
$balance = [];

foreach ($result as $result) {
    $amount[] = $result['amount'];
    $balance[] = $result['balance'];
    # Listeleme yapacak kod bloğu
}

$totalAmount = array_sum($amount);
$totalBalance = array_sum($balance);

Şeklinde kullanılabilir, kolay gelsin.

PDO’nun En Kolay Hali

Genelde, mysql fonksiyonundan PDO’ya geçişte biraz zorlanılır. Bu yazıda, PHP ile veri çekerken ve eklerken en çok kullandığımız yöntemlerin PDO karşılığını yazacağım.

PDO ile MySQL Veritabanına Bağlanmak

$pdo = new PDO('mysql:host=localhost;dbname=veritabani;charset=utf8', 'kullaniciAdi', 'sifre');

Bu satır, mysql_connect() satırıyla aynı işi hatta daha fazlasını yapar. Hem belirttiğimiz veritabanına bağlanır hem de karakter setini belirler. Böylece türkçe karakter sıkıntısı yaşamayız.

PDO ile Veri Listelemek

$sorgu = $pdo->query('SELECT * FROM tablo');
$ogeler = $sorgu->fetchAll();

foreach ($ogeler as $oge) {
	echo $oge['baslik'] . '<br>';
}

Burada, query() ile sorguyu yazdık ve fetchAll() metodu ile verileri birden fazla yani hepsini çekecek biçimde aldık. Daha sonra foreach() ile sayfaya yazdırdık.

PDO ile Veri Çekmek

PHP’de PDO ile veri çekerken veya listelerken iki yöntemimiz var. Bunlardan birincisi query() metodu diğeriyse önce prepare() yani hazırlama metodu sonrasında execute() yani çalıştır metodu. İlk metodun örneğini veri listelemek bölümünde yaptık, şimdi tekil veri çekerken, ikinci yöntemi yani prepare() metodunu kullanacağız.

$id = $_GET['id'];
$sorgu = $pdo->prepare('SELECT * FROM table WHERE id=?');
$calistir = $sorgu->execute(array($id));
$oge = $calistir->fetch();
echo $oge['baslik'];

Neden ilkinden farkı bir yöntem kullandık?

Çünkü, veritabanı ile bilgi alışverişi yaparken güvenliğe önem vermemiz gerekiyor. Son örnekte, kullanıcıdan gelen bilgiye göre ($id = $_GET['id'] satırına dikkat) bilgi çekiyoruz. Önceleri, yani PDO’dan evvel değişkeni sorgu içine ekleyip de veriler çekiliyordu. Ama SQL Injection dediğimiz açıkları da beraberinde getiriyordu. Biz, bu örnekte önce sorguyu hazırladık, şart yerine ? işareti koyduk ve soru işareti gelen yere $sorgu->execute(array($id)); kısmında göründüğü üzere gelecek verinin $id değişkeni olduğunu söyledik.

Bunun gibi ve bundan farklı birçok örnek mevcut ve kullanıma açık. Mesele mantığı kavramak. Ama en basit hali bu hali. Kolay gelsin. Bir dahaki yazıda, PDO ile veri ekleme, silme ve güncelleme konularına değineceğim.

Esen kalın.

Deprecated: mysql_connect() Hatası Üzerine

PHP’ye yeni başlayanlar, öğrenmek için çaba harcayanlar muhtemelen bu hatayla karşılaşacaklardır. Kafa karıştırmadan hatanın çözümünü söyleyelim…

Hata tam olarak şöyle:

 Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in /dosya/yolu/bilmemne.php on line 1

Bu hatayı alıyorsanız, çok eski ve artık desteklenmeyen bir yöntem kullanıyorsunuz demektir. Hatanın türkçesi:

Kullanımı önerilmiyor: mysql_connect(): msyql uzantısının kullanımı önerilmiyor ve yakın gelecekte bu fonksiyon kaldırılacak. mysqli veya PDO kullanın

Peki neden artık bu fonksiyon desteklenmiyor? Çünkü, bu fonksiyon kullanışlı ve yönetilebilir bir fonksiyon değil. Bunun yerine mysqli ve PDO kullanmak gerekiyor.

mysqli nedir?

Bu da tıpkı mysql fonksiyonları gibi bir fonksiyondur ve PHP’nin mysql fonksiyonlarına alternatifidir, eğer illa ki fonksiyonlarla veri çekeceğim diyorsanız bunu kullanın ama bana kalırsa PDO kullanmanızı öneririm.

PDO nedir?

PDO, PHP’nin bir uzantısıdır. PHP Data Objeleri diye anlayabiliriz. Neden öneriyorum, çünkü bu yöntem daha bir nesne yönelimli ve öğrenince daha da kolayınıza gelecektir. Yakın zamanda PDO hakkında bir şeyler yazmak istiyorum, bakalım.

Sonuç olarak, artık bu fonksiyonu kullanmamanızı öneriyorum.

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.

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’de PDO Veritabanı İşlemleri Sınıfı

Ç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.