Zırvalama Tahtası symfony, debian, PHP5, SQL ve pek çok ayrıntı

31Oct/080

hadi symfony’yi pear paketi yapalım

Symfony’nin her hangi bir sürümünü internet bağlantısı olmayan bir makineye kurmamız gerekebilir, özellikle hor görülmüş, geliştirilmesi durmuş olan projeler için eski symfony sürümlerine ihtiyaç duyulabilinir veya kendi symfony sürümümüzü (patchler, yeni libraryler) kullanmış olabilirsiniz. . Bu durumda ihtiyacımız olan şey kurulum yapılacak olan makinede php5-pear bileşeni ile internet erişimi olan bir makine olacaktır. Yapılması gereken ise istenilen her hangi bir symfony sürümünü pear için paketlemektir.

İşlemler oldukça basit olmasına karşın nasıl yapılacağını bilmiyorsanız karnınızı ağrıtabiliyor. Size pake adındaki ağrı kesiciyi tavsiye edebilirim.

Pake symfony’nin yaratıcılarından Fabien’nin hazırladığı bir kütüphaneve araç, temel olarak Ruby’de bulunan ve make benzeri uygulama inşası için kullanılan rake’in PHP karşılığı.

Eh önce ilacımızı bulmamız sonrada elimize almamız gerekiyor.

#### ilacımızı bulalım ####

# pear channel-discover pear.symfony-project.com

#### ilacımızı alalım ####

# pear install symfony/pake

Artık ilaç elimizde olduğuna göre bardağımıza biraz su almamız iyi olacaktır ilacı yutmak kolay olsun diye.

$ svn co http://svn.symfony-project.org/tags/${VERSION_NAME} ./symfony-custom
$ cd ./symfony-custom

Şu anda bir elimizde içi su dolu bir bardak, diğer elimizde ise ilacımız var, hadi karnımızın ağrısını dindirelim artık.

$ pake relase symfony-custom-version.no alpha/beta/stable

Artık elimizde symfony-custom-version.no.tgz isimli bir pear paketi var, yapmamız gereken tek şey bu paketi istediğimiz makineye taşımak ve kurulumu gerçekleştirmek.

# pear install ./symfony-custom-version.no.tgz

Gördüğünüz gibi karın ağrısı hiç kalmadı.

3Aug/080

php 5.3 alpha 1

Yeni duyurulan 5.3 alpha 1 versionunu gerçekten ilginç özellikler barındırıyor, bunlardan en ilginç olanı ise, namespace, late static bindings ve lambda closures desteği,

namespace‘ler sayesinde artık aynı isimde sınıfların kullanılması problem olmaktan çıkacaki,, tıpkı python’da olduğu gibi.

lambda closures desteği sayesinde ise bloklar içerisinde fonksiyonlar tanımlanabilecek
ve late static bindings sayesinde extend edilen sınıf içerisinde hangi sınıf bizi extend etmiş bilebileceğiz artık.

29Jun/080

sfForm ile çalışmak

sfForm symfony framework‘ü içerisinde geliştirilen ve yeni versiyonu ile gelecek olan yeni bir
form tasarım ve otomasyon aracıdır. Kolay kullanımı ve özelliştirilebilmesi yetenekleri ile göze çarpan bu
yeni aracı biraz daha yakından tanımak için bir çalışma içeriside çıkan notlarımı aşağıda bulabilirsiniz.
sfForm sınıfı

sfForm sınıfı ArrayAccess interface’ini impletemte eden bir sınıftır böylece sınıf
içerisindeki özelliklere tıpkı bir arrayin elemanlarına erişebilir gibi kullanabiliriz. Hazırladığımız formlar eğer veri tabanı ile direk iletişim kurmayacak ise sfForm sınıfından türetilmeli aksi halde bir abstract sınıf olan sfPropelForm sınıfından türetilmelidir.

sfform ile form oluşturmak için formumuza uygun bir sınıf ismi vererek sfForm sınıfından türetmeliyiz,
örnek:

class projectNameRegister extends sfForm
{
 
}

Form nesnemiz şu anda oldukça kullanışsız bir nesnedir, kullanışlı hale getirmek için sfForm sınıfını içerisinde çağırılan configure methodunu tanımlayıp içerisinde formumuza ait input elemanlarını yerleştirmemiz gerekiyor. Bunun için ise form input alanlarını taşıyan sfWidgetFormSchema nesnesinden faydalanıyoruz, bu nesnenin ilk parametresi bir array olup içerisindeki elamanlar birer sfWidgetFormInput nesnesi taşırlar.

class projectNameRegister extends sfForm
{
  public function configure()
  {
    $formWidgetSchema = new sfWidgetFormSchema(
      array(
        'username' => new sfWidgetFormInput();
      )
    );
 
    $this->setWidgetSchema($formWidgetSchema);
  }
}

sfWidgetFormInput nesnesi 2 adet array parametre almaktadır. ilk parametre input alanına ait seçenekler diğeri ise input etiketine eklemek istediğimiz öznitelikler,

class projectNameRegister extends sfForm
{
  public function configure()
  {
    $formWidgetSchema = new sfWidgetFormSchema(
      array(
        'username' => new sfWidgetFormInput(array(), array('id'=>'register_username'));
      )
    );
 
    $this->setWidgetSchema($formWidgetSchema);
  }
}

Artık formumuzu view katmanında kullanabiliriz,

tek yapmamız gereken action içerisinde formunuza ait yeni bir instance oluşturmak ve view katmanında bu instance’ı render etmesini sağlamak bunun için sfForm nesnesine ait __toString
methodundan yardım alabileceğimiz gibi dahada özelleştirmek için her form elemanına tek tek erişerek her elemanı form içerisinde istediğimiz yerde görüntüleyebiliriz.

action:

public function executeRegister($request)
{
  $registerForm = new projectNameRegister();
  if($request->isMethod('post'))
  {
    $registerForm->bind(array(
      'username' => $request->getParameter('username')
    ));
  }
 
  $this->registerForm = $registerForm;
}

view:

<form action="<?php echo url_for('/register') ?>">
  <?php echo $registerForm; ?>
</form>

yada

1
2
3
4
 
<form action="<?php echo url_for('/register') ?>">
  <div class="field-container"><?php echo $registerForm['username']->render(); ?></div>
</form>

Formumuzun post edilmesi halinde ise formumuza ait input elemanlarının veri doğrulamasını yine form nesnemiz içerisinde gerçekleştiriyoruz. Bu işlemide tıpkı sfWidgetFormSchema nesnesi gibi bir başka nesneyi sfValidatorSchema nesnesini kullanarak gerçekleştiriyoruz.
sfValidatorSchema nesnesi bir array parametre almakta ve bu array’in elemanları formumuzun input alanlarına ait doğrulama nesnelerini taşımaktadır.

sfValidatorXXXXX nesneleri iki adet array parametre almaktadır, her validator sınıfının kendi parametreleri vardır, ancak her sınıf içerisinde required, trim ve empty_values isimli parametreler varsayılan olarak gelmektedir, ayrıca hata mesajları için
invalid ve required isimli iki hata mesajı öntanımlıdır. ilk parametre doğrulama işlemlerinin neler olduğunu tanımlarken ikinci parametre ise her doğrulama işleminin başarısızlık durumunda kullanıcıya verilecek bilgi mesajlarını içermektedir.

class projectNameRegister extends sfForm
{
  public function configure()
  {
    $formWidgetSchema = new sfWidgetFormSchema(
      array(
        'username' => new sfWidgetFormInput(array(), array('id'=>'register_username'));
      )
    );
 
    $validationSchema = new sfValidatorSchema(array(
      'username' => new sfValidatorString(array(
          // parametre   // değeri
          'min_lenght' => 3
        ),
        array(
          // parametre doğrulaması başarısız ise kullanıcıya verilecek mesaj
          'min_lenght' => 'your username too short, min 3 char'
        ))
    ));
 
    $this->setWidgetSchema($formWidgetSchema);
 
    $this->setValidatorSchema($validationSchema);
  }
}

Artık doğrulama niteliğini kullanmak için action içerisinde bir iki ufak değişiklik yapmamız gerekmektedir.

action:

public function executeRegister($request)
{
  $registerForm = new projectNameRegister();
  if($request->isMethod('post'))
  {
    $registerForm->bind(array(
      'username' => $request->getParameter('username')
    ));
 
    if($registerForm->isValid())
    {
      // form verileri doğru ise yapılacak işlemler.
      // eğer formumuz bir sfPropelForm nesnesi ise ->save() methodunu kullanarak
      // yeni veya güncellenmiş verileri database üzerinde saklayabiliriz.
    }
  }
 
  $this->registerForm = $registerForm;
}

Eğer formumuzu özelleştirmek istersen bunun iki adet farklı yolu bulunmaktadır,
birincisi yeni bir form formatter nesnesi hazırlama, diğeri ise form nesnesi içerisindeki elemanlara erişerek html içerisine gömmek, ilk yol daha kolay gibi dursada şu an için bazı kısıtlayıcı durumu bulunmakdatır, bunların en önemlisi form alanlarındaki doğrulama hatası durumunda doğrulama hatasını taşıyan html etiketine form-error-username gibi bir id verilemiyor oluşudur. buna rağmen bu durum sizi rahatsız etmeyebilir, o halde yeni bir formatter sınıf hazırlamak oldukça kolaydır. sfForm sınıfına ait iki adet formatter sınıf mevcuttur birincisi formlarımızı table olarak görüntülerken diğeri liste elemanları olarak görüntülemektedir ve varsayılan formatter aracı table’dır. yeni bir form formatter sınıfı hazırladıktan sonra tek yapmamız gereken formumuz içerisinde bu formatter sınıfını kullanmak istediğimizi belirtmektir.

class projectNameRegister extends sfForm
{
  public function configure()
  {
    $formWidgetSchema = new sfWidgetFormSchema(
      array(
        'username' => new sfWidgetFormInput(array(), array('id'=>'register_username'));
      )
    );
 
    $validationSchema = new sfValidatorSchema(array(
      'username' => new sfValidatorString(array(
          // parametre   // değeri
          'min_lenght' => 3
        ),
        array(
          // parametre doğrulaması başarısız ise kullanıcıya verilecek mesaj
          'min_lenght' => 'your username too short, min 3 char'
        ))
    ));
 
    $this->setWidgetSchema($formWidgetSchema);
 
    $this->setValidatorSchema($validationSchema);
    // hey yeni bir formatter hazırladık bunu kullan ay sfForm aracı.
    $this->getWidgetSchema()->setFormFormatterName('Register');
  }
}

Form formatter sınıfı mutlak olarak sfWidgetFormSchemaFormatter abstract sınıfından extend etmelidir. yeni hazırlanan formatter sınıfı içerisinde sfWidgetFormSchemaFormatter da bulunan öz nitelikleri değiştirmemiz yeterlidir.

class sfWidgetFormSchemaFormatterRegister extends sfWidgetFormSchemaFormatter
{
    $rowFormat       = "<div class='form-field-container'>n %label%n  %field%n %help%n %error%n %hidden_fields%</div>n",
    $errorRowFormat  = "<div class='form-error'>n%errors%</div>n",
    $helpFormat      = "<span class='form-help'>%help%</span>",
    $decodatorFormat = '';
}

sfForm label metinlerini form input alanlarını taşıyan array içerisindeki eleman isimlerinden alır, ancak kimi durumda bunu değiştirmemiz gerekir bunun için yapılacak en kısa ve kolay yok form nesnemiz içerisinde
widgetSchema nesnesine ait setLabels methodunu kullanmak olacaktır.

class projectNameRegister extends sfForm
{
  public function configure()
  {
    $formWidgetSchema = new sfWidgetFormSchema(
      array(
        'username' => new sfWidgetFormInput(array(), array('id'=>'register_username'));
      )
    );
 
    $validationSchema = new sfValidatorSchema(array(
      'username' => new sfValidatorString(array(
          // parametre   // değeri
          'min_lenght' => 3
        ),
        array(
          // parametre doğrulaması başarısız ise kullanıcıya verilecek mesaj
          'min_lenght' => 'your username too short, min 3 char'
        ))
    ));
 
    // username alanına ait label text değerini değiştir.
    $formWidgetSchema->setLabels(array(
      'username' => 'Choose your username'
    ));
 
    $this->setWidgetSchema($formWidgetSchema);
 
    $this->setValidatorSchema($validationSchema);
    // hey yeni bir formatter hazırladık bunu kullan ay sfForm aracı.
    $this->getWidgetSchema()->setFormFormatterName('Register');
  }
}

sfForm aracına ait edindiğim bilgileri en kısa zamanda tekrar burada bulabilirsiniz.

19Mar/080

Php ile komut satırı işlemleri

Eğer bir gün komut satırından çalışacak bir PHP script yazmak zorunda kalır ve HEDE_HODO methodu/fonksiyonu yoktur diye bir hata alırsanız yerel değişkenlerini kontrol etmenizi tavsiye ediyorum aksi halde $mg->get_list() olarak kullanabildiğiniz bir methodu $mg->GET_LIST(); biçiminde kullanamayabilirsiniz, çözüm yine aynı ecport LC_ALL="C" && php -f /sizin/php/dosyanız.php

İyi bir gün geçirmeniz dileği ile...

28Dec/071

PHP-Qt 0.9 Yayınlandı

Uzun bir süredir php ve gtk'yı kullanarak Masaüstü uygulamaları geliştirebiliyorduk, bir süre önce ise artık PHP uygulamalarımızı QT ile yazabilir olduk, şimdi ise çok daha esnek bir Qt kütüphanesine sahibiz, Qt'nin getirdiği kolaylıklar ve nesne yönelimli yapısı sayesinde php-gtk gibi hazin ve yanlız kalmayacağını düşünüyorum ama elbette bu düşüncemin altında kde kullanıyor oluşum da etkili olabilir. (objektif olamıyor olabilirim).

Geçtiğimiz günlerde yeni sürümü duyurulan Php-Qt ile Qt uygulamarını PHP ile yazmak isteyenler (kimi kendini bilmezler, kimi acayipler, kimi dengesizler) için pek çok kolaylık geldi, bunlardan en önemlisi QT designer ile tasarladığımız kullanıcı arabirimini PHP içerisinden direk olarak kullanabilecek olmamız ile Qt'de bulunan her hangi bir slot yada signal'e bağlanabiliyor olmamız, böylece uygulamamızdaki her hareketten haberimiz olabiliyor. PHP yeni nesne yönelimli yapısı ile daha fazla kullanım alanı bulacak gibi gözüküyor.

Daha ayrıntılı bilgi için sizi şöyle, nedir bu PHP-Qt kardeşim diyorsanız böyle, yok kardeşim saol diyorsanız buraya alalım.

Etiketleri: , , 1 Yorum var
31Aug/070

PHP 5.2.4

PHP geliştirme takımı PHP5'in yeni sürümü olan 5.2.4'ü dün duyurdu, yeni version ile birlikte 120 kadar bug temizlenmiş ve 14 güvenlik hatası giderilmiş, geliştiriler PHP kullanıcılarının yeni sürüme geçmesini tavsiye ediyorlar. Sanırım her geliştiricinin rüyası 0 açık bug raporu olan tertemiz bir bugzilladır, PHP geliştirme takımı bu rüyayı gerçek yapabileceklermi bilmiyorum ama şu anda PHP5 için 504 adet açık bug (bu sayıya dökümantasyonda bulunan hatalar dahil değil) bulunuyor.

30Aug/070

PHP vs. Ruby on Rails

İnternette gezerken oldukça fazla rastlamaya başladığım bu tür propaganda video veya makalelerinden pek hoşlanmıyorum bütün bu dedikleri doğru olsa bile RoR ile PHP'yi kıyaslamak nedir? Bir platform ile bir dili nasıl kıyaslar insanlar ve başka insanlar buna nasıl inanır? Sinirlenmemek için susmak daha iyi olacak sanırım.

17Jul/070

Çok yaşa PHP5

13 Temmuz'da php.net sitesinde yapılan duyuruya göre 2007 sonundan sonra PHP4 için yeni bir sürüm çıkartılmayuacak ve php4'e destek (sadece hata düzeltimi) sadece 2008'in ağustos ayına kadar sürecek, PHP4 uygulamaları ise PHP5'e yavaş yavaş transfer edilmeye başlansa iyi olacak ;)

PHP4 öldü, yaşasın PHP5

2Dec/060

# Eaccelerator

PHP yazılımlarının hızı meşhurdur ancak çok hit alan bir web siteniz varsa ve bir süre için donanımsal yatırım yapamıyorsanız yapılacak ilk şey kodunuzun optimizesini arttırmak için (sql sorguları öncelikli) çalışmalara başlamaktır.

Elbette uzun zaman alan bu işleme başlamadan önce yapılacak ilk şeyler arasında kullandığınız veri tabanında optimizasyona gitmek ve SQL sorgularını düzenlerken aynı zamanda veri tabanının cache ve bellek miktarını arttırmaktır. Elbette bunlarda uzun bir süreçtir. Peki en kötü ihtimalle %15 / %25 arasında performans'ı en kısa zamanda almak isterseniz ve çok fazla zamanınız yok ise? İşte yardımınıza Eaccelerator koşar adım gelir ve hayatınızı kurtarmak için ilk yardımı size sunar.

Kurulumu oldukça basit olan (elbette unix türevleri için kolay win32 için bilmiyorum denemedim ) bu eklenti sayesinde PHP kodlarınız çalışma zamanında optimize edilir ve bir süre için cache'de tutulur. Kullanımı ve parametreleri için bir ara yine yazarım burada bir şeyler ama siz beni beklemek yerine kendi sayfasından bilgi alabilirsiniz.

Not: PHP5 için 0.9.5 sürümünü kullanmanız gerekiyor.
Not2: Bu tür eklentiler hayatınızı kolaylaştırabilir ve günü kurtarmanıza yardımcı olabilir ancak bu sizin düzgün ve optimizasyonu eksik kod yazmanız için bir gerekçe değildir.

15Aug/060

cursor, propel

Bazen veri tabanında büyük veriler ile çalışmanız gerekebilir. (şu andaki bir projemizde haftada 500 bin satır veri girilen bir tablomuz var örneğin) ve PHP5′in pek bir güzel framework’ü olan symfony ile bu büyüklükteki bir datayı işlemek isteyebilirsiniz. Karşınıza çıkacak sorunlar kısaca şunlardır. PHP’nin çalışma zamanını aşması (evet bu miktar çözülebilinir) ve PHP için ayrılan bellek miktarının yetmemesi. Bu gün symfony e-posta listesine benzer bir soru geldi ve büyük datalarla çalışan bir arkadaş (test amaçlı 100.000 satır veri ile) PHP’nin bellek sorununa takıldığını 100MB belleğin yetmediğini ve paket ürün olduğunda bu veri miktarının 10 misli artacağını ve sorunu nasıl çözeceğini soran bir e-posta atmış. (ben biraz geç fark ettim yoksa hemen üstüne atlardım. ) MySQL’de bu işler nasıl bilmiyorum ama PostgreSQL denen enfes veri tabanında CURSOR denen pek bir güzel kavram vardır. BEGIN COMMIT bloğu içerisinde bir cursor tanımlarsınız ve yapmış olduğunuz işlemin sonucu PostgreSQL tarafından bellekte tutulur ve bu bellekteki veriye belirttiğiniz CURSOR ile erişebilirsiniz. Bunun güzel tarafı sonucun postgreSQL tarafında tutulması böylece büyük resultset’ler sonucunda PHP’nin kullandığı bellek miktarını daha uygun bir şekilde kullanabilirsiniz. Elbette bu sonuç seti içerisinde ileri geri hareket edebilirsiniz.

Hemen bir e-posta ile hızlı ve tu kaka cinsinden bir yanıt verdim ve ardından verdiğim yanıtın testini yaptım (baya ukela biriyim önce test yapsana be adam alla alla) bir iki hata dışında CURSOR kullanımını Propel içerisinden nasıl yapılacağına dair bir kod ortaya çıktı. Eminim birileri bir gün büyük datalarla Propel nasıl çalışır diye arayacaktır (yada ben unutacağım ve o zaman buraya bakacağım) diye buraya yazayım dedim.


public static function getCity()
{
$con = Propel::getConnection();
try
{
$con->begin();
$stmt = $con->PrepareStatement("DECLARE mycursor CURSOR FOR SELECT * FROM ".self::TABLE_NAME);
$stmt->executeQuery();
$loop=true;
while($loop)
{
$loop = false;
$res = $con->executeQuery("FETCH FORWARD 60 FROM mycursor");
while($res->next())
{
$loop = true;
//birşeyler yapın
}
}
$con->rollback();
}catch(Exception $e)
{
// birşeyler yapın
}
// sonucu döndürebilirsiniz ama tavsiye etmem
}

İşlem yapacağınız Tablonun Peer sınıfına yukarıdaki bir method yazıyoruz yaptığımız iş kısaca,
DECLARE deyimini kullanabilmek için BEGIN ile bir transaction açıp, ardından
$stmt = $con->PrepareStatement(”DECLARE mycursor CURSOR FOR SELECT * FROM “.self::TABLE_NAME); satırı ile mycursor isimli bir CURSOR’ü “SELECT * FROM “.self::TABLE_NAME” deyimi için tanımlamak.
ardından sorgumuzu çalıştırmak, burada bize bir result set dönecektir bu result set boş olduğundan ihtiyacımız yok.

Hemen ardından loop içerisinde mycursor adındaki sonuç kümesinden 60′ar adet veri alabilmek için ” $res = $con->executeQuery(’FETCH FORWARD 60 FROM mycursor’); ” deyimini çalıştırıyoruz buradan bize 60 satırlık bir result set dönecektir. bu resultset’ide diğer bir loop içerisinde kullanarak içerisindeki verilerimizi alıp işliyoruz (ne yapacağınız size kalmış.) Yukarıdaki kod bloğunda “FETCH FORWARD 60 FROM mycursor” deyimi bir adet fazla çalışıyor. Nedenini biliyorum, peki siz düzeltebilirmisiniz? (hızlı bir PHP bilgisi testidir efendim kazananlar uzay havası ile ödüllendirileceklerdir. )