Monthly Archives: Nisan 2013

Genel

ASUS N56VZ üzerindeki Kablolu Ethernet Kartının Ubuntu 12.10 Üzerinde Çalışmaması Sorununun Giderilmesi

Ubuntu 12.10 Üzerinde ASUS N56VZ bilgisayarınızın Atheros AR8161 Gigabit Ethernet kablolu ethernet kartının çalışmaması sorunu ile ilgili olarak aşağıdaki işlemleri gerçekleştirmeniz gerekir.

1- Aşağıdaki linux paketlerini root izni ile yükleyin.

sudo apt-get install build-essential linux-headers-generic linux-headers-'uname -r'

2- Aşağıdaki komutu çalıştırarak sürücü dosyasını bilgisayarınıza indirin.

wget http://www.orbit-lab.org/kernel/compat-wireless-3-stable/v3.5/compat-wireless-3.5.4-1-snpc.tar.bz2

3- Sıkıştırılmış haldeki paketi açın ve kurulumu başlatın.

tar -xj compat*.tar.bz2
cd compat-wireless-3.5.4-1-snpc
sudo ./script/driver-select alx
sudo make
sudo make install

4- Bilgisayarınızı yeniden başlatınız.

Hepsi bu!

Programa Dilleri ve Çatıları

Bir Cool’unu Çok Sevdim

jQuery.coolRedirectBir Cool’unu çok sevdim, o beni hiç sevmiyor javascriptleri cachelemiş sayfa bir türlü değişmiyor… diyerekten berbat bir espiriyle konuya giriyorum…

Bu gece can sıkıntısından yazdığım basit bir jQuery eklentisini sizlerle paylaşmak istedim. Eklenti, html linkerini manipüle ederek tarayıcı yönlenme işlevini yerine getirmeden önce fade efekti ile sayfaya oturan bir katman üzerinde loading.. bla.. bla.. yazısı üstünde ziv.. ziv.. dönen bir gif görüntülenmesini sağlar.

Eklenti kodlarına aşağıdaki github reposundan ulaşabilirsiniz:
https://github.com/ibrahimgunduz34/CoolRedirect

Şöyle bir HTML linkimiz olsun.

Click to <a href="http://jquery.com">here</a> for jQuery.

document.ready olayının callback ine aşağıdaki kodu ekleyelim.

$('a').coolRedirect();

Hepsi bu kadar…!

Olurda canınız varsayılan yükleniyor mesajını değiştirmek isterse :

$('a').coolRedirect({loadingText: 'Yükleniyor. Lütfen bekleyiniz...'});
Programa Dilleri ve Çatıları

YII ile Basit Veritabanı İşlemleri

Aslında pek üstüne blog yazısı yazmaya deyecek bir konu olduğu söylenemez. :) Hem dağılan kafamızı biraz toparlayalım, hem de konuyu arayan birilerine Türkçe kaynak olsun. Hadi bakalım…

***

YII çatısı altında veritabanı uygulamaları geliştirirken dilerseniz DAO (Data Access Object), dilerseniz ORM (Object Relation Mapping) kullanarak veritabanına erişebilirsiniz.

1. DAO (Data Access Object) Kullanarak Veritabanı İşlemleri Gerçekleştirmek :

1. 1. Veritabanı Bağlantısı Oluşturmak

YII ile veritabanı bağlantısını isterseniz dilediğiniz herhangibir anda başlatıp sonlandırabilir veya doğrudan aplikasyon başladığı anda veritabanı bağlantısını başlatabilirsiniz. DAO nesnesi PDO dan türediği için sunucunuz tarafından desteklenen tüm PDO sürücülerini kullanabilir.

Aşağıdaki örnekte anlık veritabanı bağlantısının nasıl başlatılıp sonlandırıldığını görüyoruz.

$dsn = 'mysql:host=localhost;dbname=testdb';
$username = 'myuser';
$password = 'mypass';
$connection=new CDbConnection($dsn,$username,$password);
$connection->active=true; // veritabani baglantisini aciyoruz...
......
$connection->active=false;  // veritabani baglantisini kapatiyoruz...

Veritabanı bağlantısını uygulama ayağa kalktığında başlatmak için ise veritabanı erişim bilgilerini konfigürasyona yazmanız yeterli.
protected/config/main.php:

array(
    ......
    'components'=>array(
        ......
        'db'=>array(
            'class'=>'CDbConnection',
            'connectionString'=>'mysql:host=localhost;dbname=testdb',
            'username'=>'myusername',
            'password'=>'mypassword',
            'emulatePrepare'=>true,  // YII nin sitesinde bazi SQL sorgulari icin gerekli oldugundan bahsediyor. Muhtemelen parametre iceren SQL sorgularinin dogrudan calistirilmamasi icin kullanilmasi gereken bir parametre.
        ),
    ),
)

Veritabanı bağlantısını ugulama ayağa kalktığında başlattığınızda connection nesnesine aşağıdaki şekilde ulaşabilirsiniz:

$connection = Yii::app()->db;

1. 2. SQL sorgusu çalıştırmak

SQL sorguları, veritabanı bağlantısı üzerinden bir fabrika metodu ile command nesnesinin yaratılıp bu nesnenin execute() edilmesi suretiyle gerçekleştirilir. Aslında bu kullanım şekli, PDOşinas olan arkadaşlarımıza son derece tanıdık gelecektir.

Adi bir select sorgusunu aşağıdaki şekilde çaılştırabilirsiniz.

/* @var $connection CDbConnection */
$connection = Yii::app()->db;
$sqlQuery = 'SELECT `id`, `name`, `amount` FROM `mytable` WHERE `id`=23';
/* @var $command CDbCommand */
$command = $connection->createCommand($sqlQuery);
/* @var $reader CDbDataReader */
$reader = $command->query();
foreach($reader as $row) {
 ...
}

YII, bize bir veritabanı sorgusunu çalıştırabilmemiz için aşağıdaki metodları sunar.

$rowCount=$command->execute();
/*
Bu kullanim, genellikle sonuc beklentisi olmayan 
INSERT, UPDATE, DELETE sorgulari icindir. Calitirildiginda 
sorgu sonucunda etkilenen satir sayisini doner.
*/

$dataReader=$command->query();   
/*
Bu kullanım şeklinde sonuc traversable bir obje olan 
CDbDataReader tipinde döner. Sorgu sonuclari döngü 
ile fetch edilir.
*/

$rows=$command->queryAll();
/*
Bu kullanim seklinde sorgu once calistirilir sonra tum 
sonuclar fetch edilir.
*/

$row=$command->queryRow();
/*
Bu kullanim seklinde sorgu once calistirilir sonra 
sonuca ait ilk satir fetch edilir.
*/

$column=$command->queryColumn(); 
/*
Bu kullanım şeklinde sorgu calistirilir ve sonucun ilk kolonu doner.
*/

$value=$command->queryScalar();  
/*
Bu kullanim sekli sorguyu calistirir ve ilk satirin ilk kolonunu doner.
*/

1. 3. Sorgu sonuçlarının fetch edilmesi

CDbCommand::query() metodu çağırıldığında CDbDataReader tipinde bir örnek üretilir. Sorgu sonuçlarını almak istediğinizde ise döngü içerisinde CDbDataReader::read() metodu tekrarlı olarak çağırılır.

$reader = $command->query();
while($row = $reader->read() ) {...}
foreach($reader as $row) {...}
//Bu kullanim sekli sorgu sonucundaki tum satirlari alir.
$rows = $reader->readAll();

1. 4. Transaction Kullanımı

Üstüne söylenecek çok fazla birşey yok. Sorguları çalıştırmaya başlamadan önce transaction ı başlatır sorguları çalıştırdıktan sonra commit edersiniz. Buyrun kod örneği :

$queries = array();
$queries[] = 'INSERT INTO `mytable` (`id`, `name`, `amount`) VALUES(1, 'zeynep', 100);';
$queries[] = 'INSERT INTO `mytable` (`id`, `name`, `amount`) VALUES(2, 'ayşe', 250);';
$queries[] = 'INSERT INTO `mytable` (`id`, `name`, `amount`) VALUES(3, 'elif', 115);';

$success = true;
$transaction = $connection->beginTransaction();
foreach($queries as $sqlQuery) {
    try {
        $connection->createCommand($sqlQuery)->execute();
    } catch(Exception $e) {
        $transaction->rollback();
        $success = false;
    }
}

if( $success ) {
    $transaction->commit();
}

Bir sonraki yazıda YII ‘nin basit, şirin ORM kütüphanesi ActiveRecord u inceleyeceğiz.
Sevgi, selam ötesi hürmet..

Programa Dilleri ve Çatıları

Hadise var dediler, geldik!

HadiseHadise, çok ilkel (basit) bir olay güdümlü programlama kütüphanesidir. Mevcut PHP aplikasyonunuza basitce implemente ederek yazılımınızın akışını tetiklediğiniz olaylar doğrultusunda yönetebilirsiniz.

Hadise kütüphanesinin en güncel sürümünü aşağıdaki github reposunda bulabilirsiniz:
https://github.com/ibrahimgunduz34/hadise

Örneğin projenizin içindeki basit bir api implementasyonuna hadise kütüphanesini uyarlayalım.

Öncelikle olay dinleyecilerimizi kodlayalım.
İlk olarak istek göndermeden önce tetikleyeceğimiz olay dinleyicimizi ile başlayalım.

use \Hadise\IEventListener;
use \Hadise\Event;
class BeforeRequestListener implements IEventListener
{
  public function invoke(Event $event)
  {
    $logData = sprintf("Source:\n" .
                       "------------------\n" .
                       "%s\n" .
                       "Request:\n" .
                       "------------\n" .
                       "%s\n", get_class($event->getSource()),
                       var_export($event->getParameters(), true);
    file_put_contents('transaction_log', $logData, FILE_APPEND);
  }
}

Şimdi de istek gönderdikten sonra tetikleyeceğimiz olay dinleyicimizi kodlayalım.

use \Hadise\IEventListener;
use \Hadise\Event;
class AfterRequestListener implements IEventListener
{
  public function invoke(Event $event)
  {
    $logData = sprintf("Source:\n" .
                       "------------------\n" .
                       "%s\n" .
                       "Response:\n" .
                       "------------\n" .
                       "%s\n", get_class($event->getSource()),
                       var_export($event->getParameters(), true);
    file_put_contents('transaction_log', $logData, FILE_APPEND);
  }
}

Mevcut api implementasyonumuzda istek öncesi ve sonrasında olay dinleyicilerimizin tetiklenmesini sağlayalım.

class MyApiImpl implements MyApiImplInterface
{
  //...
  protected function __sendRequest($url, array $data)
  {
    $requestXML = http_build_query($data);
    EventManager::getManager('MyApiImpl')->riseEvent('beforeRequest', $this, array('data' => $requestXML));
        
    $ch = curl_init();
    //...
    $responseData = curl_exec($ch);
    //...
    EventManager::getManager('MyApiImpl')->riseEvent('afterRequest', $this, array('data' => $responseData));
  }
  //...
}

Son olarak olay dinleyicilerimizi olay yöneticimize iliştirelim.

EventManager::getManager('MyApiImpl')
            ->addListener('beforeRequest', new BeforeRequestListener());
EventManager::getManager('MyApiImpl')
            ->addListener('afterRequest', new AfterRequestListener());

Hepsi bu kadar. İyi eğlenceler :)

Yazılım ve Sistem Mühendisliği

Tasarım, tasmam kime ne ?

Aslında bugün “Bir fonksiyon yazdım-2” başlıklı yazıyla karşınıza çıkmayı hedeflemiştim ancak şu sıra üstüne çok konuştuğum, çokca da içinde bulunduğum projelere b.k atmama vesile olan başka bir konuyla karşınızdayım.

Hepimiz farklı şirketlerde geliştirici olarak değişik projelerde görev alıyoruz. PHP dünyası için konuşmak gerekirse şanslı bir azınlık popüler frameworklerle geliştirilmiş, kurallara/standartlara uygun yazılmış projelerde çalışırken malesef büyük bir çoğunluk kötü kodlanmış, çoğunlukla spagettiye dönmüş kodların içinde debelenip duruyoruz. Bu durum müşteriden gelen isteklere verilen zamansal hedeflerin tutturulamamasına, yeni geliştirmelerin bir şekilde eski geliştirmeleri bozarak yazılımın hatalı çalışmasına ve en kötüsü test edilemeyen kod üretimine neden olmaktadır. Peki doğru bir yazılımın tasarımı nasıl olmalı ?
İyi yazılım tasarımının nasıl olabileceğini açıklayabilmek için öncelikle kötü bir tasarımın ne gibi özelliklere sahip olduğunu bilmeliyiz. Robert Martin abimiz kötü bir yazılım tasarımının 3 temel özelliğe sahip olabileceğini söylemiş.
Rigidity
Rigidity (Esnemezlik):
Kötü tasarımlar geliştirmeye uygun değildir, Esneklikleri yoktur. Birgün, belki birkaç saat süreceğini düşündüğünüz bir iş haftalar sürebilir. İşin ne zaman biteceği kestirilemez. Dolayısıyla tasarım sorunu gün geçtikce yönetimsel bir problem halini alır.

Fragidity
Fragidity (Kırılganlık):
Hepimizin aşine olduğu bir konu. Yeni bir geliştirmenin eski bir geliştirmenin bozulmasına neden olmasıdır. Bu durum, yapılan her geliştirmede çalışan başka bir yerin bozulacağı korkusunu yaratır ki işinizi yapamaz hale gelirsiniz. “IT bir yeri yaparken bir yeri bozuyor be arkadaş” cümlesini sıklıkla duymanıza neden olur.

Immobility
Immobility (Taşınamamazlık) :
Bağımlılıklar nedeniyle bir kodun başka bir yerde kullanılamaması durumudur. Bu tarz durumlarda aynı modülün tekrar kullanılması gerektiği durumlarda modül/kod bloğu bir kere daha yazılır. Lojik değişikliği gerektiği durumlarda pek çok yerde değişiklikyapmanız gerekir, çoğunluklada atlanan/unutulan yerler nedeniyle sistemin stabilitesi bozulur, yazılım hatalı çalışmaya başlar.

Ortalama birgününüz, çözdüğünüz issue lar ve dahil olduğunuz projeler gözünüzün önünden geçti değil mi ? :)

Peki doğru bir tasarım nasıl olmalı ? Doğru tasarım aşağıda kısaca açıklamaya çalıştığım S.O.L.I.D. prensiplerine uygun olmalıdır.

Single Responsibility (Tekil sorumluluk):
Her kod bloğu (modül, sınıf, metod) kendi sorumluluğundaki işi yapmalı. Kod bloklarının kendi sorumluluğu dışında işleri yapması bağımlılığı arttırır. (Bkz. Bi fonksiyon yazdım… )

Open-Close (Açık – Kapalı) :
Modülleriniz gelişime açık, değişime kapalı olmalıdır. Herhangibir değişiklik gereksinimi olduğunda mevcutu değiştirmek yerine yeni bir özellik olarak eklenmelidir.

Liskov (Liskov prensibi) :
Türemiş bir sınıf atası olan sınıfla aynı davranışı sergilemelidir.

Interface Segregation (Arayüz ayırma):
Benzer özellikler taşıyan sınıflardaki metodların gruplanarak tek bir interface e tabi olmaları sağlanmalıdır. Böylece programınız tarafından kullanılmayan metodları projenize dahil etmemiş olursunuz.

Dependency Inversion (Bağımlılıkların azaltılması):
Bağımlılıklar, concreate sınıflardan yapılmak yerine mümkün olduğunca soyut sınıflar ve arayüzler üzerinden gerçekleştirilmelidir.