29 Jun

PHP?nin Gizli Hazineleri?ffmpeg

Daha 0.6 sürümünde olan ve sürüm notları arasında “bu eklenti deneyseldir, kullanımdan doğabilecek risklerden siz sorumlusunuz” yazıyor olsa da, gelişitirlmeye devam ederse güzel bir eklenti olacağı kesin.

ffmpeg, Linux’da kullanılan video çevrim ve başka maharetleri de olan, konsoldan çalışan güzel bir uygulama. ffmpeg, video türleri arasında çevrim yapmak, videonun herhangi bir karesinden veya saniyesinden resim almak, ekran görüntünüsünü kaydetmek gibi daha birçok özelliğe sahiptir.

Bu php eklentisi de çalışabilmek için ffmpeg ve GD kütüphanesine ihtiyaç duymakta. Henüz ffmpegin yapabildiklerinin hepsini yapamasa da , ilerleyen zaman diliminde bu durum değişecek diye umuyorum.

Bu eklenti ile şu anda yapılabilecekler, video bilgilerini almak ( süre, boyut, frame rate vb ) ve videodan bir önizleme resmi alamaktır .

1
2
3
4
5
6
7
8
// videomuzu veriyoruz
$movie=new ffmpeg_movie("test.flv");
// resmin alınacağı kareyi veriyoruz
$frame = $movie->getFrame(1);
// GD nesnesini oluşturuyoruz
$gd = $frame->toGDImage();
// resmi kaydediyoruz
imagepng($gd,'ekran-goruntusu.png');

Bu birkaç kolay adımdan oluşan , videodan bir kare resim alma işlemi bile bu eklentiyi çekici kılmaya yeter gibi. Ama şunları unutmamak gerek : Hala deneysel bir çalışma, problem yaratması muhtemel.
Videodan alınan ekran görüntüsü pek kaliteli olmayabiliyor.

Son olarak, bu eklenti sadece Linux’da bulunmakta.

28 Jun

PHP?nin Gizli Hazineleri ? phar

Bence geleceği en parlak ve aynı zamanda çokca yararlı olabilecek bir PHP kütüphanesi. Phar eklentisinin temel amacı , yapmış olduğunuz uygulamayı, sıkıştırılmış bir dosyada toplayarak (phar – PHpARschive), projenizin kolayca dağıtılmasını ve kurulmasını sağlamak.

Hepimizin başında olan birşeydir bu, kendi oluşturduğumuz veya başka biri tarafından oluşturulmuş, class veya fonksiyonlardan oluşan php dosyalarını uygulamamız içerisine yükleriz. Bunu yaparken de en çok sıkıntısını çektiğimiz şey yüklemeye çalıştığımız dosyanın yolu olur genellikle.

Kendimize has dosya yükleme yöntemleri geliştirmiş olabiliriz, ama bir de şöyle düşünün : bütün dosyalarımızı tek bir çatı altında toplayabilseydik, hatta az yer kaplamasını sağlayabilseydik ve bunlara kolayca ulaşmanın bir yolu olsaydı.

İşte bütün bunları yapabilme olanağımız var. Phar eklentisi sayesinde bütün projemizi phar dosyası olarak , birden fazla sıkıştırma formatını destekleyen biçimde (tar,zip,gzip, bz) tek bir dosya olarak saklayabiliriz.

Phar eklentisi ile projemiz için ihtiacımız olan dosyaların hepsini bir phar arşiv dosyası olarak saklayabiliyoruz :

1
2
$phar=new Phar('test.phar');
$phar->buildFromDirectory('/var/www/test');

Yukarıdaki iki satır kod bloğu ile yapmaya çalıştığımız şey “/varr/www/test” klasörü içerisindeki dosyaları “test.phar” dosyasına atmak. Böylece tek bir arşiv dosyası içerisinden ihtiyacımız olan tüm dosyalara erişebiliriz :
( Örneğin /var/www/test klasörü içerisinde class dizini ve bu dizin içerisinde phar.php dosyamız olsun )

1
include 'phar://test.phar/class/phar.php';

Bu kod satırı ile de test.phar arşiv dosyası içerisine attığımız ,class dizini içerisindeki “phar.php” dosyasının yüklenmesini sağlıyoruz. Bunu yapan ise “phar://” akım sarmalayıcısı (stream wrapper) dır. Bu akım sarmalayıcısı sayesinde arşiv dosyasını harddiske açmadan , içerisindeki dosyaya erişebilmemizi sağlamakta.

Phar ile yapabileceklerimiz sadece bunlar değil tabiki. Daha fazla ayrıntı için phpnin dökümantasyonuna göz atabilirsiniz.

24 Jun

PHP’nin Gizli Hazineleri – inotify

Fırsat buldukça php.net den dökümantasyona yeni birşey eklenmişmi diye bakarım. Windows kullandığım zamanlar “sadece linuxda çalışır” ibareli dökümanları es geçmek zorunda kalırdım. Ama artık durum değişti, windows bağımlılığımdan kurtuldum ve şimdi temizim 🙂

Artık PECL’de bulunan yeni eklentileri rahatlıkla deneyebiliyorum. Eklentinin, kullandığım platforma uygun biçimde derlenmesini beklemeden, kaynak kodundan direkt eklentiyi yüklüyorum . Bu ne büyük bir keyif anlatamam.

Benden size bir öneri, hala Linux kullanmıyorsanız , en kısa sürede bilgisayarınızın bir bölümüne kurun. Bağımlılıklarınız olabilir, başka bir işletim sistemine geçmek sizi korkutuyor olabilir, yaşadığınız veya yaşayacağınız sıkıntılar sizi yıldırma seviyesine getirebilir. Ama ne olursa olsun, kurun ve mutlaka yenilikleri takip ederek bunları mümkün olduğunca deneyin.

inotify, çok kolay kullanımı olan ve gayet sade bir PHP eklentisi. Yaptığı şey, bir dosya veya dizin üzerindeki değişiklikleri izleyebilmenizi sağlamak.

Tabi bunu tam anlamı ile yerine getirdiğini söylemek zor. Örneğin bir klasörü izlediğinizde, klasör oluşturulduğunda bunu algılıyor. Ama klasörü, ilk oluşturulduğu zamanki isim ile algılıyor ( Örneğin yeni klasör) daha sonra bu klasör veya dosya ismini değişrtirdiğinizde bunu algılamıyor. Bunu algılayabilmesi için, yeni oluşturulan klasör için de bir izleme işlemi başlatılması gerekiyor. Bu garip durum haricinde güzel çalışıyor.

Diyelimki /var/www klasörünü izlemek istiyoruz :

1
2
3
4
5
6
7
8
#!/usr/bin/php
<?php
$inotify=inotify_init();
inotify_add_watch($inotify,'/var/www',IN_ALL_EVENTS);

while( $notify=inotify_read($inotify)){
    print_r($notify);
}

Yukarıdaki kısa kod bloğu, “/var/www” klasöründeki değişiklikleri size bildiriyor. Tabi bunu web tarayıcınızdan çalıştırmamanız gerektiğini söyleyeyim. Bu php dosyasını ancak konsoldan php-cli ile çalıştırırsanız sağlıklı sonuç alabilirsiniz.

Bu konuya dair çok ayrıntıya girmiyorum, çünkü çok kullanılacak bir yöntem değil ve aynı zamanda deneysel birşey.
Bu konu ile ilgili daha fazla ayrıntıya buradan ulaşabilirsiniz

19 Jun

Linux Dizinlerinin Boyutlarını Öğrenmek

Harddiskimizin limitlerine ulaştık, ama bunu anormal buluyoruz. Eminizki bize yetecek kadar yer var. Peki bunu nasıl bulabiliriz.

İşte burda linux komutlarından olan “du” imdadımıza koşuyor :

du -h / ––max-depth=1

Yukarıdaki parametreleri açıklarsak :
-h , dosya boyutlarını bizlerin okuyacağı şekilde olması için
/ , root klasörümüz . root klasörünü verdim, çünkü bütün ana dizinleri görmek istiyorum
––max-depth , unutulmaması gereken, her klasörün sadece ilk elemanını ele almasını alt dizinlere gitmemesini belirtmek için.

Bu işlemlerden sonra, root dizinindeki tüm ana klasörlerin ne kadar yer kapladığını listeleyecek. Burdan yola çıkarak , şüphelendiğimiz her bir klasöre ayrı ayrı bakarak, en çok yer kaplayan dizini bulabilir, eğer bir müdahale söz konusu ise bunu gerçekleştirebiliriz.

19 Jun

Serialization – Nesne ve Veri Yapılarını Taşıma

Serialization’a karşılık uygun bir Türkçe karşılık bulduğumu söyleyemem, her ne kadar birebir çevrisi “sıralama” olsa da tam olarak yapılan işlemi karşılamıyor.

Serialization, veri yapılarının veya nesnelerin daha sonra yeniden kullanabilmesi için bir dosyada veya hafıda saklanması, ağ yardımı ile bir bilgisayardan başka bir bilgisayara aktarılmasını sağlayan bir yöntemdir (*)

PHP ile bu işlemleri yapmak gerçekten çok kolay. Sadece gerekli nesneyi serialize fonksiyonuna vererek , nesnenin serileştirilmesini sağlayabiliriz.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
class Ogrenci {
  public $ad;
  public $soyad;
  public $sinif;

  public function __construct($_ad,$_soyad,$_sinif){
      $this->ad=$_ad;
      $this->soyad=$_soyad;
      $this->sinif=$_sinif;
  }
}

$ogrenci= new Ogrenci('ersin','dogan','6 edb-a');

file_put_contents('ogrenci.nesnesi',serialize($ogrenci));

Yukarıdaki örnekte bir Ogrenci classı oluşturduk ve gerekli parametreleri vererek bir örneğini oluşturduk. Sonra bu nesneyi serialize ederek ogrenci.nesnesi adlı dosyada sakladık ( dosya ismini rasgele seçtim, hehangi bir özelliği yok ). Burdaki amaç, oluşturulmuş nesneyi daha sonra tekrar kullanmak istememiz.

Kodları aşağıdaki gibi güncellersek :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
class Ogrenci {
  public $ad;
  public $soyad;
  public $sinif;

  public function __construct($_ad,$_soyad,$_sinif){
      $this->ad=$_ad;
      $this->soyad=$_soyad;
      $this->sinif=$_sinif;
  }
}

$ogrenci=unserialize(file_get_contents('ogrenci.nesnesi'));

echo $ogrenci->ad;

Bize vereceği çıktı “ersin” dir. Örnekte de görüldüğü gibi, nesneyi dosyadan okuyarak yeniden oluşturduk ( unserialize ) ve daha önce verdiğimiz parametre değerleri ile yeniden kullanailiriz.
Burda dikkat etmeniz gereken, classın bir örneğini serialize ederek sakladıktan sonra, yeniden kullanma aşamasında o classı kodlarınızın içerisine dahil etmeyi unutmamız gerektiğidir.

19 Jun

PHP ile Sayfa Yenilenmesini Algılama

Aslında garip bir yöntem, çokca ihtiyaç duyulabilecek birşey değil diye tahmin ediyorum.
Ama işte, yeri gelince ihtiyaç da olabiliyor.

Aşağıda vereceğim yöntem tek başına sağlıklı bir kontrol-ölçme biçimi değil. Eğer sayfa yenilemesinin algılanması çok önemli ise, mutlaka ekstra yöntemler de gelişitirilmeli.

1
echo '<pre>',print_r($_SERVER,true);

Bu kod ile, PHP tarafından oluşturulan, sunucuya ve ortama dair bazı bilgileri tutan, $_SERVER dizesindeki verileri ekrana yazdırıyoruz. Bunu yapmamızın sebebi, sayfaya direkt olarak girilmesi ile sayfa yenilendiği zaman ortaya çıkan farklılığı orataya koyabilmek. Bu kodun bendeki çıktısı aşağıdaki gibi :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Array
(
    [HTTP_HOST] => localhost
    [HTTP_USER_AGENT] => Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.3) Gecko/20100423 Ubuntu/10.04 (lucid) Firefox/3.6.3 FirePHP/0.4
    [HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    [HTTP_ACCEPT_LANGUAGE] => en-us,en;q=0.5
    [HTTP_ACCEPT_ENCODING] => gzip,deflate
    [HTTP_ACCEPT_CHARSET] => ISO-8859-1,utf-8;q=0.7,*;q=0.7
    [HTTP_KEEP_ALIVE] => 115
    [HTTP_CONNECTION] => keep-alive
    [PATH] => /usr/local/bin:/usr/bin:/bin
    [SERVER_SIGNATURE] =>
Apache/2.2.14 (Ubuntu) Server at localhost Port 80


    [SERVER_SOFTWARE] => Apache/2.2.14 (Ubuntu)
    [SERVER_NAME] => localhost
    [SERVER_ADDR] => 127.0.0.1
    [SERVER_PORT] => 80
    [REMOTE_ADDR] => 127.0.0.1
    [DOCUMENT_ROOT] => /var/www
    [SERVER_ADMIN] => webmaster@localhost
    [SCRIPT_FILENAME] => /var/www/i.php
    [REMOTE_PORT] => 50699
    [GATEWAY_INTERFACE] => CGI/1.1
    [SERVER_PROTOCOL] => HTTP/1.1
    [REQUEST_METHOD] => GET
    [QUERY_STRING] =>
    [REQUEST_URI] => /i.php
    [SCRIPT_NAME] => /i.php
    [PHP_SELF] => /i.php
    [REQUEST_TIME] => 1276953783
)

Bu kodu denerken, sayfayı yenilediğinizde ek olarak şu çıktıyı görürsünüz :

1
 [HTTP_CACHE_CONTROL] => max-age=0

Bu farklılığın sebebi, tarayıcının ikinci isteği yaptığında, karşılığında önbellekten gelen bilgileri değil, sayfayı asıl kaynaktan direkt olarak almak istediğini belirtmesidir.

İşte bizde bu değişkeni takip ederek, sayfanın yenilendiğinin ya da sayfaya direkt olarak erişildiğini anlamaya çalışıyoruz :

1
2
3
if(!empty($_SERVER['HTTP_CACHE_CONTROL'])) {
  echo 'sayfa yenilendi';
}

Bu kontrol ile, sadece işi kuralına göre yapan tarayıcılar ile başarı oranımız yüksek olur. Ama bot dediğimiz siteleri gezen programcıklar için farklı yöntemler de gerekli.

18 Jun

Neden PDO Kullanmalıyız ? İşlevsellik

PDO kullanmanın yararlarına dair burada ve şuradaki yazılarım ile başlayan PDO serisinin, kendimce son halkası olan bu yazı ile son buluyor.

Yoğun veritabanı işlemlerinin olduğu, çok fazla girdi olan işlemler hep sıkmıştır beni. Çünkü her parametreyi tek tek kontrol etmek, hata takibi vb işlemler.

Bu söylediğim can sıkıcı durumu hafifleten PDO, sunduğu olanaklar ile kodlamada ve kontrolde bize yardımcı oluyor. Bunu nasıl mı yapıyor ?

PDO bildirimleri ile, SQL cümleciklerine gönderilmesi gereken paremetreleri zahmetsizce ekleyebiliyor ve aynı zamanda etkisizleştirebiliyoruz :

1
2
3
4
5
6
7
try{
  $pdo=new PDO('mysql:dbname=testdb;host=localhost','kullanici','sifre');
  $sorgu=$pdo->prepare('INSERT INTO kullanicilar VALUES (?,?,?)');
  $sorgu->execute(array('ersin dogan','ersin','12345'));
}catch(Exception $e){
  echo $e->getMessage();
}

Yukarıdaki kod ile yapmaya çalıştığım şey, veritabanına bağlanarak kullanıcılar tablosuna verilen bilgileri kaydetmek. Eski yönteme göre yapmmış olsaydık :
– bağlantıyı açacak
– veritabanını seçecek
– verilen her parametreyi SQLe geçirecek
– sorguyu çalıştırcak
– ve her adımda hata kontrolü yapacaktık.

Yukarıda yazdığım adımları, aklınızdan koda döktüğünüzde, PDO ile yazılmış örnekten çok daha fazla satıra ve uğraşa mal olacağını kolaylıkla bulabilirsiniz.

Örneğimizde bütün işlemleri try – catch bloğu içerisine alarak hata kontrolünü kolaylıkla yapabiliyoruz.

prepare metodu ile, SQL cümleciğini bir PDO bildirimine (statement) dönüştürüyoruz. Bu bildirimin execute metoduna gerekli parametreleri verdiğimizde, bu bildirim otomatik olarak parametre eşleşmelerini yaparak sorguyu çalışıtırır.

Eşleşmeyi ? işareti yerine , execute içerisine verilen array deki parametreleri sırası ile vererek yapar. Eğer arraydeki parametreleri yanlış sıralarsanız tabloya yanlış kaydedilir veya hiç kaydedilmez.

Bunu önlemek için , parametre eşleşmelerini isim vererek de yapabilirsiniz :

1
2
3
4
5
6
7
try{
  $pdo=new PDO('mysql:dbname=testdb;host=localhost','kullanici','sifre');
  $sorgu=$pdo->prepare('INSERT INTO kullanicilar VALUES (:adsoyad,:kullanici,:sifre)');
  $sorgu->execute(array('adsoyad'=>'ersin dogan','kullanici'=>'ersin','sifre'=>'12345'));
}catch(Exception $e){
  echo $e->getMessage();
}

Bu yöntem karışıklıkları engellemek için daha etkili. Daha önceki konuda verdiğim kodları incelerseniz, konuya dair daha fazla fikre sahip olabilirsiniz.

Konuya dair toparlayabildiklerim bunlar. Eksik, anlaşılmayan veya hatalı yerler var ise beni uyarırısanız, gerekli değişiklikleri en kısa zamanda yaparım.

Güzel günler dileği ile.

09 Jun

Neden PDO Kullanmalıyız – Esneklik

Evet, nerde kalmıştık. Esneklik ile kastettiğim şeyi açıklayabilmek için bir örnek hazırladım. Örneği buradan indirebilirsiniz.

Bu örnek ile yapmaya çalıştığım şey, kodda yapısal hiçbir değişikliğe gitmeden 2 farklı veritabanını kullanabilen bir uygulama yapabilmekti.

Kolay ve bilinen bir örnek olarak , basit ötesi bir ziyaretçi defteri oluşturdum. Bu ziyaretçi defteri hem sqlite hem de mysql destekliyor. Bunu PDO sayesinde yapabiliyor.

Bildiğiniz gibi PDO aşağıdaki veriatabanlarına destek veriyor :
* MS SQL Server (PDO) ? Microsoft SQL Server ve Sybase (PDO_DBLIB)
* Firebird/Interbase (PDO) ? Firebird/Interbase (PDO_FIREBIRD)
* IBM (PDO) ? IBM (PDO_IBM)
* Informix (PDO) ? Informix (PDO_INFORMIX)
* MySQL (PDO) ? MySQL (PDO_MYSQL)
* Oracle (PDO) ? Oracle (PDO_OCI)
* ODBC and DB2 (PDO) ? ODBC ve DB2 (PDO_ODBC)
* PostgreSQL (PDO) ? PostgreSQL (PDO_PGSQL)
* SQLite (PDO) ? SQLite (PDO_SQLITE)
* 4D (PDO) ? 4D (PDO_4D)

PDO (Php Data Object) bir arayüz sunarak, bu arayüzü destekleyen sürücüleri ile birlikte veritabanı üzerinde işlem yapılmasını sağlıyor. Bütün işlemler PDO üzerinden yürütüldüğü için kodda herhangi bir yapısal değişikliğe gidilmiyor, yani tek satır yeni kod yazmadan (sadece parametre değişikliği ile) birden fazla veritabanını ile çalışabilen bir uygulama mümkün oluyor.

Örneğimizin çalışabilmesi için testdb adında bir mysql veritabanı oluşturun. Bu veritabanı üzerinde, dosyalar içerisinde bulunan, schema.txt dosyasındaki mysql kodunu çalıştırın :

CREATE TABLE `defter` (
`id` INTEGER AUTO_INCREMENT,
`konu` VARCHAR(100),
`mesaj` TEXT,
`yazar` VARCHAR(32),
`eposta` VARCHAR(32),
PRIMARY KEY (`id`)
)
ENGINE = InnoDb
CHARACTER SET utf8 COLLATE utf8_general_ci;

Kodları web sunucunuza açın. Dosyalar arasındaki sayfa.php de bulunan şu satıra gidin

1
2
3
4
5
6
7
8
9
10
11
   public function __construct(){
      /**
       *  mysql dsn
       *  'mysql:dbname=testdb;host=127.0.0.1'
       *  
       *   sqlite dsn
       *   'sqlite:sqlite-defter.db'
       */

     
      $this->defter=new Defter('sqlite:sqlite-defter.db');
   }

Burada veritabanı işlemleri yapmamıza (defeteri okuyup yazmamıza) olanak sağlayan sınıfımızın ( Defter ) alacağı parametreler görülmekte.
Hiçbir değişiklik yapmadan ve PDO_SQLite sürücüsü aktif iken testi çalıştırırsanız SQLite destekli bir ziyaretçi defteri çalıştırmış olursunuz.

Bu ziyaretçi defterini mysql ile kullanmak isterseniz yapmanız gereken tek şey Defter sınıfının kurucusuna verilen parametreyi değiştirmek :

1
    $this->defter=new Defter('mysql:dbname=testdb;host=127.0.0.1','kullanici-adi','sifre');

Evet, hepsi bu. Sadece parametre değişikliği ile bu esnekliği sağlıyoruz. Burdaki parametre PDO nesnesinin ilgili veritabanı sürücüsünü yüklemesi için gereklidir.
Bunu PDO’suz da yapabilirdik, ama kodları incelediğinizde PDO’nun gücünü daha iyi anlayacaksınız.

Tabi herşey bu ziyaretçi defterindeki gibi kolay olmuyor, her veritabanı kendine has özelliklere sahip ve bu özellikler geçiş esnasında sıkıntılar yaşatabilir.
Ama eğer ara katman düzgün planlanmış / yazılmışsa , sadece veriatabanı /SQL değişiklikleri ile kodda çok fazla değişikliğe gidilmeden ( hatta bu örnekte olduğu gibi sadece DSN değişikliği ile ) geçiş yapmak mümkün olabilir.

03 Jun

Neden PDO kullanmalıyız – Güvenlik

Uzun bir ara oldu yazmayalı, iş-güç derken baya boşladım blogumu. Ayrıca, yazmak istediğim konulara dair pek bir kararsızdım. En sonunda PDO ya dair yazılar yazarak devam etmeye karar verdim.
Daha önce PDO ile ilgili yazılar yazmıştım, konuyu tamamlamak adına birkaç şey var, onları dilimin döndüğünce aktarmaya çalışacağım.
Güvenlik önemli bir unsur, web uygulamalarımızda her zaman karşı kaşıya kaldığımız bir konudur. Güvenlik açıklarından biri SQL Injection, yani SQL aşılamadır.
SQL Injection’ı, veritabanından veri çekmek için kullandığımız SQL sorgularının istemediğimiz biçimde değiştirilmesi olarak özetleyebiliriz.
Bir örnek ile olaya daha yakından bakalım :

kullanıcı adında ,id -kullanici ve sifre alanlarının oluşan bir tablomuz var. Bu tabloyu üyelik sistemi için kullanıyoruz,kullanıcıya dair bilgileri bu tabloda saklıyoruz. Böylece sisteme girişleri (login) bu tablodaki bilgiler aracılığı ile gerçekleştiriyoruz. Buraya kadar herşey normal, şimdi basit bir şekilde bir sorgu yaparak, giriş yapmak isteyen kullanıcımzının bilgilerini kontrol edelim

1
2
3
4
5
6
$baglanti=mysql_connect('localhost','kullanici_adi','sifre');
mysql_select_db('testdb');
$sorgu='select*from user where name="'.$_GET['u'].'" and password="'.$_GET['p'].'"';
$sonuc=mysql_query($sorgu);
echo '<pre>',print_r(mysql_fetch_assoc($sonuc),true);
mysql_close($baglanti);

Test etmesi kolay olsun diye, sadece GET ile gelen verilere göre işlem yapıyoruz. Bu sorgudan veri dönerse kullanıcımız var demektir, böylece kullanıcımızı giriş yapmış olarak kabul edebiliriz. Tabiki yukarıdaki gibi bir yöntem hiçbir yerde kullanılamaz, ama konuya verilebilecek iyi bir örnek.
Bu dosyayı kendi sunucumuzun diznine yerleştirip şu şekilde çalıştırdığımızda :

Örn : http://localhost/test.php?u=ersin&p=12345

sorgumuz çalışacak, şartları sağlayan veri varsa ekrana yazdırılacak. Şimdi gelin biraz kötü niyetli davranalım, çünkü,bu kodu yazan hiçbir güvenlik önlemi almamış, cezalandırılmayı hak etmiş 🙂

Adres satırından şöyle bir giriş yaparsak :

http://localhost/test.php?u=” or 1=1–&p=” or 1=1–

karşımıza ilk kullanıcının verisi gelir. İşte bu SQL aşılamanın en bilinen örneği. Tabi bundan korunmanın tek yolu PDO değil ama gerçekten en akılcı ve etkin yöntemlerden biridir. Yukarıdaki satır, nasıl sonuç döndürülmesine sebep oldu derseniz, kullanıcıdan gelen veriyi filtrelemediğimiz için, kötü niyetli kullanıcı SQLi değiştirerek ( sorgu şu biçimde olur select*from user where name=”” or 1=1–” and password=”” or 1=1–“) , önemli bilgilere erişme olanağı bulmuştur.

Şimdi PDO ile bunun nasıl engellenebileceğine bakalım :

1
2
3
4
5
6
7
$p=new Pdo('mysql:dbname=testdb;host=127.0.0.1','kullanici','sifre');

$st=$p->prepare('select*from user where name=? and password=?');

$st->execute(array($_GET['u'],$_GET['p']));

echo '<pre>',print_r($st->fetchAll(),true);

Gördüğünüz gibi PDO ile hem daha anlaşılır, hem de daha kolay bir biçimde güvenli bir sorgulama yapabiliyoruz. Burada dikkat etmeniz gereken , PDO bizim yerimize verileri yerleştirirken (? işareti yerine bizim verdiğimiz veriler atanır), verdiğimiz parametrelerin sırasına göre yerleştirir .
Farklı yöntemlerde var ama şimdilik bu yazının konusu değil, sonrasında değinmeye çalışacağım.
PDO bu işlemi yaparken, kullanıcılar tarafından girilen verileri otomatik olarak etkisizleştirir. Böylece bizlere daha az yük düşer.