Zend Framework Doctrine 2 Entegrasyonu

1 Comment

PHP yazanlar için en iyi framework ve en iyi ORM yi entegre edelim.

Kaynak : http://www.oelerich.org/?p=315

Zend Framework ün kurulu olduğunu varsayarak anlatacağım.

Efendim ilk olarak http://www.doctrine-project.org/projects/orm/download adresinden stabil olan Doctrine 2.0 sürümünü indiriyoruz.Daha sonrasında Doctrine dizinini Zend de bulunana library dizini altına koyuyoruz. bin dizinini ise zf nin root dizinine koyuyoruz.

application.ini dosyamızda Doctrine entegrasyonunuda kullanacağımız konfigürasyonları belirtiyoruz.

doctrine.conn.host = '127.0.0.1'
doctrine.conn.user = 'root'
doctrine.conn.pass = root''
doctrine.conn.driv = 'pdo_mysql'
doctrine.conn.dbname = 'zf-test'
doctrine.path.models = APPLICATION_PATH "/models"

Bu ayarlamayı yaptıktan sonra Bootstrap dosyasında belli değişiklikler yapıyoruz. Doctrine kütüphanelerini Bootstrap.php dosyasında yüklüyoruz.Örnek kod aşağıdaki gibidir.

<?php

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
    /**
     * generate registry
     * @return Zend_Registry
     */
    protected function _initRegistry(){
        $registry = Zend_Registry::getInstance();
        return $registry;
    }

    /**
     * Register namespace Default_
     * @return Zend_Application_Module_Autoloader
     */
    protected function _initAutoload()
    {
        $autoloader = new Zend_Application_Module_Autoloader(array(
            'namespace' => 'Default_',
            'basePath'  => dirname(__FILE__),
        ));
        return $autoloader;
    }

    /**
     * Initialize Doctrine
     * @return Doctrine_Manager
     */
    public function _initDoctrine() {
        // include and register Doctrine's class loader
        require_once('Doctrine/Common/ClassLoader.php');
        $classLoader = new \Doctrine\Common\ClassLoader(
            'Doctrine',
            APPLICATION_PATH . '/../library/'
        );
        $classLoader->register();

        // create the Doctrine configuration
        $config = new \Doctrine\ORM\Configuration();

        // setting the cache ( to ArrayCache. Take a look at
        // the Doctrine manual for different options ! )
        $cache = new \Doctrine\Common\Cache\ArrayCache;
        $config->setMetadataCacheImpl($cache);
        $config->setQueryCacheImpl($cache);

        // choosing the driver for our database schema
        // we'll use annotations
        $driver = $config->newDefaultAnnotationDriver(
            APPLICATION_PATH . '/models'
        );
        $config->setMetadataDriverImpl($driver);

        // set the proxy dir and set some options
        $config->setProxyDir(APPLICATION_PATH . '/models/Proxies');
        $config->setAutoGenerateProxyClasses(true);
        $config->setProxyNamespace('App\Proxies');

        // now create the entity manager and use the connection
        // settings we defined in our application.ini
        $connectionSettings = $this->getOption('doctrine');
        $conn = array(
            'driver'    => $connectionSettings['conn']['driv'],
            'user'      => $connectionSettings['conn']['user'],
            'password'  => $connectionSettings['conn']['pass'],
            'dbname'    => $connectionSettings['conn']['dbname'],
            'host'      => $connectionSettings['conn']['host']
        );
        $entityManager = \Doctrine\ORM\EntityManager::create($conn, $config);

        // push the entity manager into our registry for later use
        $registry = Zend_Registry::getInstance();
        $registry->entitymanager = $entityManager;

        return $entityManager;
    }

}


İlk iki metod Doctrine ile ilgili bir işlem yapmıyor. Sadece Zend in Autoloader ve Registry modüllerini oluşturuyor. _initDoctrine metodunda ise gerekli belirtilen konfigürasyonlara göre Doctrine nesnesini oluşturuyoruz.Doctrine e bağlı olarak ArrayCache Proxy ve EntitiyManager oluşturuluyor.Bunları tam olarak incelemediğim için pek yorum yapamıyorum.Kaynakta belirtilen ise ArrayCache performansı daha üst seviyede tutabilmek için Doctrine in cache mekanizması, Proxy sanırım o da incelememiş :) , EntityManager veritabanı ve bizim modellerimiz arasındaki bir interface.Daha detaylı incelediğimde umarım bu konu hakkında da bir yazı yazabilirim :)

Sonrasında bir model yeni adıyla bir entity oluşturuyoruz.

<?php

/**
 * @Entity
 * @Table(name="test123")
 */
class Default_Model_Test
{
    /**
     * @Id @Column(type="integer")
     * @GeneratedValue(strategy="AUTO")
     */
    private $id;

    /** @Column(type="string") */
    private $name;

    public function setName($string) {
        $this->name = $string;
        return true;
    }
}

Doctrine 2 ile gelen yeni bir olay ise model oluşturma veya modelden DB oluşturma işlerini bin adlı dizinden yapabiliyor olmanız.Kaynakta söylendiği gibi bin/doctrine.php dosyasını aşağıdaki şekilde değiştirdim.

<?php

define('APPLICATION_ENV', 'development');

define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));

set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . '/../library'),
    get_include_path(),
)));

// Doctrine and Symfony Classes
require_once 'Doctrine/Common/ClassLoader.php';
$classLoader = new \Doctrine\Common\ClassLoader('Doctrine', APPLICATION_PATH . '/../library');
$classLoader->register();
$classLoader = new \Doctrine\Common\ClassLoader('Symfony', APPLICATION_PATH . '/../library/Doctrine');
$classLoader->register();
$classLoader = new \Doctrine\Common\ClassLoader('Entities', APPLICATION_PATH . '/models');
$classLoader->setNamespaceSeparator('_');
$classLoader->register();

// Zend Components
require_once 'Zend/Application.php';

// Create application
$application = new Zend_Application(
    APPLICATION_ENV,
    APPLICATION_PATH . '/configs/application.ini'
);

// bootstrap doctrine
$application->getBootstrap()->bootstrap('doctrine');
$em = $application->getBootstrap()->getResource('doctrine');

// generate the Doctrine HelperSet
$helperSet = new \Symfony\Component\Console\Helper\HelperSet(array(
    'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()),
    'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em)
));

\Doctrine\ORM\Tools\Console\ConsoleRunner::run($helperSet);

Sonrasında oluşturduğum bin dizinine giderek doctrine i executable yapıyorum.

chmod +x ./doctrine

Şu şekilde de modelden veritabanını oluşturuyorum.Pardon entitiy den :)

./doctrine orm:schema-tool:create

Kullanımı da şu şekilde oluyor :

<?php

class IndexController extends Zend_Controller_Action
{
    public function init()
    {
        $registry = Zend_Registry::getInstance();
        $this->_em = $registry->entitymanager;
    }

    public function indexAction()
    {
        $testEntity = new Default_Model_Test;
        $testEntity->setName('Zaphod Beeblebrox');
        $this->_em->persist($testEntity);
        $this->_em->flush();
    }

}

Fakat siz de benim gibi ters bir adamsanız şöyle birşeye ihtiyaç duyacaksınız.”İşte efendim ben DB yi oluşturayım entitiyler buna göre oluşsun” der iseniz eğer şunu yapıyoruz.

./doctrine orm:convert-mapping --from-database php /tmp/
Böylece /tmp dizinine tablolarınızın php çıktısını alabilirsiniz.Aynı şekilde ph p yerine yaml ve xml de alabiliyorsunuz.Bunun için php yerine xml veya yaml yazmanız yeterli.
İyi gönler efendim… :)

Zend Framework ile subdomainlerinizi ilgili modüllere yönlendirin

No Comments

Gecenin saat 2 sinde beni bu yazıyı yazmay iten şey inat etmemdir :) Efendim geleim konuya.Diyelim li domainim.com adında bir domaininz olsun.Zend Framework ile kodlamışsınız bir güzel. İşte bunun mobil versiyonunu yaptınız, servisler modülü falan var admin i var falan filan işte tüm bu modüllerin ayrı domainlerde hizmet vermesini istiyorsunuz.İşte tam bu konuda Zend_Router devreye giriyor.Bilmeyene bela öğrenene sefa hesabı.1 saatlik araştırmalarım sonucunda yine çözümü stackoverflow da bulldum.** Bu siteyi yapanlardan Allah razı olsun :)

Gelelim koda application.ini dostama şu satırları ekledim (Bu arada benim domainim cevremdenevar.com ve bunun mobile modülünü farklı bir domain ile hizmete sunacağım.)

resources.router.routes.mobile.type = “Zend_Controller_Router_Route_Hostname”
resources.router.routes.mobile.route = “mobile.cevremdenevar.com”
resources.router.routes.mobile.chains.list.route = “:controller/:action/*”
resources.router.routes.mobile.defaults.module = “mobile”
resources.router.routes.mobile.defaults.controller = “index”
resources.router.routes.mobile.defaults.action = “index”

resources.router.routes.mobile.type = “Zend_Controller_Router_Route_Hostname”
resources.router.routes.mobile.route = “mobile.cevremdenevar.com”
resources.router.routes.mobile.chains.list.route = “:controller/:action/*”
resources.router.routes.mobile.defaults.module = “mobile”
resources.router.routes.mobile.defaults.controller = “index”
resources.router.routes.mobile.defaults.action = “index”

Efendim olay budur.Ne .htaccess iniz ile ne de bootstrap iniz in ayarları ile oynamayınız.Bu arkadaş bunu hallediyor.Yani boşa işte domain i . lardan explode edip işte onu buraya route edip falan filan bilmem ne gibi şeylerle uğraşmayınız.Değerli vaktinize yazık…

Python Notlarım (Part I)

1 Comment

Bir hevestir Python a öyle bakayım  istedim.İlk edindiğim izlenim farklı ama güzel.Öncelikle ilk edindiğim bilgileri  hatırlanabilir olması için bloguma yazmak istedim.

Şu anda Python bir geçiş dönemi yaşıyor gibi PHP 4 5 gibi python da da 2 ve 3 versiyonu var her iki versiyonu da apt-get ile kurmak çok kolay.Bunlara ek olarak Python için interactive prompt diye bir olay var ki işte öğrenirken ve denemeler yaparken bu olayı çok seviyorsunuz.Anında görüntü şov.Bunu yapabilmek için console a python komutu ile geçmek mümkün.

İlk olarak script1.py isminde bir dosyaya şunları yazdım :

#A first Python Script
import sys
print (sys.platform)
print (2 ** 5)
x = 'Spam!'
print (x * 8

Bu dosyayı  “python script1.py” şeklinde çalıştırabiliyorum.Import olayına gelince.

threenames.py adlı bir dosya oluşturup şunları yazdım.

a = 'dead'
b = 'parrot'
c = 'sketch'
print(a, b, c)
# Define three attributes
# Exported to other files
# Also used in this file

Oluşturduğunuz her py dosyası bir module oluyor. modul.attr şeklinde erişimi mümkün.

% python
>>> import threenames
dead parrot sketch
>>>
>>> threenames.b, threenames.c
('parrot', 'sketch')
>>>
>>> from threenames import a, b, c
>>> b, c
('parrot', 'sketch')

Coğrafi Lokasyon Arama

1 Comment

Bu yazımda sizlere coğrafi lokasyon aramadan bahsedeceğim.Verilen enlem ve boylam bilgisi ile bu lokasyona ait belirli bir uzaklıkta bulunan yerleri bulmak.Tabi bulunacak bu yerlerin bir yerlerde tutulduğunu düşünüyorum.Bunun için ihtiyacımız olan şeyler Mysql Sphinx ve PHP.

Mysql için şöyle basit bir tablonuz olsun

CREATE TABLE IF NOT EXISTS `location` (
 `locationId` int(11) NOT NULL AUTO_INCREMENT,
 `locationName` varchar(255) NOT NULL,
 `locationType` tinyint(4) NOT NULL,
 `locationLat` decimal(10,8) NOT NULL,
 `locationLon` decimal(10,8) NOT NULL,
 PRIMARY KEY (`locationId`),
 KEY `locationType` (`locationType`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=80908 ;

Evet tablomuzu oluşturduktan sonra gelelim sphinx olayına.Sphinx bir açık kaynaklı arama sunucusudur.Detaylı bilgi için bkz : http://sphinxsearch.com/

Ben Sphinx i Ubuntu 10.10 üzerine şöyle kurdum.

sudo apt-get install sphinxsearch

Sonrasında /etc/default/sphinxsearch te otomatik başlatma parametresini yes olarak ayarladım.Gelelim veri indexlemeye.

Bunun için /etc/sphinxsearch/sphinxsearch.conf u biraz kurcalamanız gerekir.İşte source ve indexleri ayarlamanız icab edecek.Detayları sphinx in sayfasında bulabilirsiniz.Ben conf dosyamı şu şekilde oluşturdum.


source geo
{
 type                 = mysql
 sql_host             = 127.0.0.1
 sql_user             = root
 sql_pass    = root
 sql_db        = test
 sql_port    = 3306
 sql_query_pre    = set names utf8
 sql_query_pre    = set session query_cache_type=OFF
 sql_query    = SELECT l.locationType, RADIANS(l.locationLon) AS longitude, RADIANS(l.locationLat) AS latitude FROM location l
 sql_attr_float           = longitude
 sql_attr_float          = latitude
 sql_attr_uint        = locationType
 sql_ranged_throttle      = 0
 sql_query_info           = select * from location where locationId = $id
}

index geo
{
 source                  = geo
 path                    = /etc/sphinxsearch/data/geo/geo
 docinfo                 = extern
 mlock                   = 0
 morphology              = none
 min_word_len            = 1
 charset_type            = utf-8
 charset_table           = 0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F
 ignore_chars            = U+00AD
 html_strip              = 0
 enable_star             = 0
}

indexer
{
 mem_limit            = 512M
}

searchd
{
 listen                = 127.0.0.1
 listen                = 3312
 listen                = /var/run/searchd.sock
 log                    = /var/log/sphinxsearch/searchd.log
 query_log            = /var/log/sphinxsearch/query.log
 read_timeout        = 5
 client_timeout        = 300
 max_children        = 30
 pid_file            = /var/run/searchd.pid
 max_matches            = 1000
 seamless_rotate        = 1
 preopen_indexes        = 0
 unlink_old            = 1
 mva_updates_pool    = 1M
 max_packet_size        = 8M
 max_filters            = 256
 max_filter_values    = 4096
}

bunu oluşturduktan sonra indexer ı çalıştırıyoruz ki datamız indexlensin.İlk başta hata alabilirsiniz.Sebebi indexlenecek datanın olmaması.Datanızı oluşturup

indexer –rotate geo şeklinde geo adlı kaynağı indexleyebilirsiniz.Gelelim sorgumuzu çalıştırmaya:

<?php
require_once 'sphinxapi.php';

$lat = $_GET['lat'];
$lon = $_GET['lon'];
$_radius = $_GET['r'];
 $search = new SphinxClient();
 $search->SetServer("localhost", 3312);
 $search->SetMatchMode(SPH_MATCH_ALL);
 $search->SetArrayResult(true);
 $search->SetLimits(0, 100);
 $search->SetGeoAnchor('latitude', 'longitude', (float) deg2rad($lat), (float) deg2rad($lon));
 $circle = (float) $_radius;
 $search->SetFilterFloatRange('@geodist', 0.0, $circle);

 $search->SetFilter('locationType', array(10));    
 $result = $search->Query('', 'geo');

Şeklinde kullanmanız mümkün.İndireceğiniz sphinxapi.php nin sürümüne dikkat etmeniz gerekir.Çünkü cilent ve sunucu arasında versiyon farklılığı yaşayabilirsiniz. Evet kabaca bu şekilde gerçekleştirmeniz mümkün.

Mysql Upsert Metodu (ON DUPLICATE KEY UPDATE)

No Comments

Böyle de güzel bişey var.İşte bi tablınuz var buraya standart insert ve update yapılıyor.Fakat bunu 2 farklı işlem yerine tek işlemde bitirmek istiyorsunuz.Hem duplicate entry hatalarından da kurtarmak istiyorsunuz durumu.İşte böyle durumlarda aşağıdaki gibi bir kullanım imdadınıza yetişebilir.
Bir de şöyle bakmak lazım işte kayıt var mı yok mu diye bakacaksınız yoksa insert varsa update yapacaksınız mesela.Böyle durumlarda da aşağıdaki kullanım daha performanslı.Tabii ki bunun çalışabilmesi için unique alanların belirlenmiş olması gerekiyor.

INSERT INTO commonSettings VALUES ($id, $key, $value)
ON DUPLICATE KEY UPDATE value =$value”

Nesne Yönelimli Programlama Giriş

No Comments

Ne zamandır yazmak istediğim konuların başında geliyordu.Yazma amacım çok iyi bildiğimden değil sadece pekiştirmek, unutmamak ve hatırlamak.

Nesne yönelimli programlama 4 temel prensibe dayanıyor ve bu prensipler etrafında şekillenmiş tasarım desenlerini kapsıyor.Tasarım desenlerinin çıkış sebebi ise aslında problemlere dayanıyor.Yani karşılaşılaşılan bir problem tipi var buna bir çözüm uygulanması gerekiyor.Uygulanılan çözüm her seferinde o durumu çözüyor ise işte o bir tasarım deseni oluyor.

Peki tasarım desenleri neden ihtiyaç duyuyoruz.
Tasarım desenleri, test sağlayarak kanıtlanmış kalkınma paradigmaları geliştirme sürecini hızlandırır.Kodun okunabilirliğini arttırır.En önemlisi kod kontrol altında olur ve yazmış olduğunuz kod bug fixler ile yamalanmış bohça yerine düzenli büyüyen kod haline gelir.Bunu şehir planllaması gibi düşünebiliriz aslında, eğer tasarım kalıpları kullanılırsa buna düzenli kentleşme, kullanılmaz ise buna düzsensiz kentleşme diyebiliriz. Sisteminiz ne kadar çok büyür ise bir o kadar da içinden çıkılmaz hal alır (eğer tasarım kalıpları kullanılmaz ise).

Tasarım desenlerine tekrar döneceğim.Şimdi açıklamam gereken 4 prensip

1. Encapsulation (Kapsülleme) : Oluşturacağımız sınıfların özelliklerine erişimi kısıtlama ve gizlemeyi işaret eder.Şöyle ki ihtiyaca göre  oluşturacağınız bir sınıf  belirli değerlerini verdikten sonra işlemleri kendi içinde yapmasını  ve dışarıdan bire müdahale görmemesini  isteriz.Bunun için özelliklerimizi private yapıp bunları getter ve setter metodlar yardımı ile kullanmalıyız.Basit bir örnek

class Person {
 private String name;
 private String surnname;

 public void setName(String name) {
 this.name = name;
 }
 public String getName() {
 return name;
 }
 public void setSurnname(String surnname) {
 this.surnname = surnname;
 }
 public String getSurnname() {
 return surnname;
 }

 public static void main(String[] args) {
 Person person = new Person();
 person.setName("Mustafa");
 person.setSurnname("İleri");

 System.out.println(person.getName());
 System.out.println(person.getSurnname());

 }

}

2. Abstraction (Soyutlama) : Soyutlama karmaşıklığı önlemek, nesnelerin birbirleri ile olan bağımlılığını yönetebilmek için kullanılır.Soyutlama ile miras aslında farklı şeylerdir.Soyutlamada kullanacağınız abstract class ve interface ile bir sınıfın bağımlı olduğu metodları belirleyebilirsiniz.

3.Inheritance (Miras): Nesneleri birbirlerinden türetmedir.Mesela her futbolvu bir sprocu ise futbolcu nesnesi sporcu dan türeyebilir. Miras alınan üst sınıf a parent alt sınıfa child der isek; üst sınıftaki bütün metodlar ve özellikler alt sınıfa gelir.Bir soyut sınıf değil ise üst sınıftaki metodları tekrar tanımlamak zorunda değilsiniz.Java PHP ve C# dillerinde çoklu miras alma yoktur.Yani siz bir  A sınıfı hem B den hem C den miras alsın diyemezsiniz.

4.Polymorphism (Çok Biçimlilik): Nesneler birbirlerinden farklı olabilir fakat miras ilişkisine ikisi de aynı ana sınınftan türemiş ise o sınıflara hükmedebilirsiniz. Bunu şöyle örnekleyelim. Şimdi bir soyut sınıf oluşturacağım adı Insan olan, sonra buna bağlı olan Muhendis veOgrenci sınıfları oluşturacağım. Daha sonra buna bağlı olmayan bir Makine sınıfı oluşturacağım. Sonra bunları tip olarak insan isteyen bir metod a sokacağım sonuca bakalım.

Insan.java
public abstract class Insan {
 abstract void nefesAl();
 abstract void yasa();
}
Makine.java
public class Makine {
 public void calis() {
 }
}
Muhendis.java
public class Muhendis extends Insan {

 @Override
 void nefesAl() {
 System.out.println("Muhendis nesef alıyor");
 }

 @Override
 void yasa() {
 System.out.println("Muhendis nesef yaşıyor.");
 }

}

Ogrenci.java
public class Ogrenci extends Insan {

 @Override
 void nefesAl() {
 System.out.println("Ogrenci nesef alıyor");
 }

 @Override
 void yasa() {
 System.out.println("Ogrenci nesef yaşıyor.");
 }

}
Test.java
public class Test {
 public static void main(String[] args) {
 Test test = new Test();
 Ogrenci ogrenci = new Ogrenci();
 Muhendis muhendis = new Muhendis();
 Makiine makine = new Makine();
 test.nefesAl(ogrenci);
 test.nefesAl(muhendis);
 test.nefesAl(makine);
 }

 public void nefesAl(Insan insan) {
 insan.nefesAl();
 }
}

Şimdi Test.java dosyamızı çalıştırdığımızda nefesAl metoduna sadece Insan tipinde nesne verebiliyoruz.Buraya muhendis veya orgenci verebiliyorken makineyi veremedik.Basit olarak çok biçimliliği böyle anlatabilirim.

Tasarım desenleri uygulanma şekline göre şu şekilde kategorilendiriliyor.

1. Cretional Design Patterns (Yaratılışsal Tasarım Desenleri)

  • Abstract Factory
  • Builder
  • Factory Method
  • Object Pool
  • Prototype
  • Singleton

2. Structural Design Patterns (Yapısal Tasarım Desenleri)

  • Adapter
  • Bridge
  • Composite
  • Decorator
  • Facade
  • Flyweight
  • Private Class Data
  • Proxy

3. Behavioral Design Patterns (Davranışsal Tasarım Desenleri)

  • Chain of responsibility
  • Command
  • Interpreter
  • Iterator
  • Mediator
  • Memento
  • Null Object
  • Observer
  • State
  • Strategy
  • Template method
  • Visitor

İlk yazımda bu kadar anlatabildim bundan sonraki hedefim tüm bu tasarım desenlerini örnek kodlarla anlatmak.

Firefox Addon Yazmak

No Comments

Şirkette oluşan ihtiyaç dahilinde böyle bir mevzuya da bulaşmış bulunmaktayım.Aslında zevkli sayılabilir.2 seçeneğiniz var.
1.XUL ki Firefox üzerinden direk çalışabilen ve kararlı bir yapıdır.
2. Jetpack: Sadece HTML CSS ve JS ile çok güzel şeyler yapabiliyorsunuz.Fakat henüz test aşamasıda.Mesela geliştirdiğim ufak add on ubuntu da çalışırken windows 7 de patladı.

Bu yazımda biraz XUL dan bahsedeceğim.

https://developer.mozilla.org/en/XUL_Tutorial adresinden XUL u öğrenebilirsiniz çok rahat.

Genel olarak bir addon un yapısı şöyle oluşşmalıdır.

chrome/
+content
+locale
+skin

chrome.manifest

install.rdf

şeklinde olmalıdır. XUL dosyamızı content altına yerşeltiriyoruz.mesela deneme.xul olsun.
content/deneme.xul şeklinde konumlandırılabilir.

install.rdf : Addon yüklenme ayarlarını tutar.

<?xml version=”1.0″?>

<RDF xmlns=”http://www.w3.org/1999/02/22-rdf-syntax-ns#”
xmlns:em=”http://www.mozilla.org/2004/em-rdf#”>

<Description about=”urn:mozilla:install-manifest”>

<!– Required Items –>
<em:id>dev@falanfilan.com</em:id>
<em:name>Uygulama Adı</em:name>
<em:version>1.0</em:version>

<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>1.5</em:minVersion>
<em:maxVersion>4.0.*</em:maxVersion>
</Description>
</em:targetApplication>

<!– Optional Items –>
<em:creator>Hede Hödö</em:creator>
<em:description>Açıklama işte</em:description>
<em:homepageURL>http://blog.mustafaileri.com</em:homepageURL>

</Description>
</RDF>

gibi örneklendirebiliriz.Kritik nokta id değeri ec8030f7-c20a-464f-9b0e-13a3a9e97384 sizin uygulamanız için değil firefoxa ait bir değerdir.Bu Thunderbird için daha farklıdır.Eğer yazacağınız add-on firefox için ise bu değeri değiştirmeyin.Kafanıza göre değer hiç vermeyin :)

chrome.manifest: Bir nevi uygulamanın çalışacağı ayarları tutar.

content         deneme                                 jar:chrome/paket.jar!/content/
overlay         chrome://browser/content/browser.xul         chrome://addon-adi/content/deneme.xul

Burada çalışacak uygulamanın hangi jar paketini kullanacağı ve kullanacağı XUL dosyalarını belirtebiliyoruz.Ek olarak chrome://browser/content/browser.xul kullanımı yabancı gelebilir.Add on içeriğinie böyle ulaşabiliyoruz. Mesela content altında x.png olsun. XUL dan ona chrome://addon-adi/content/x.png diye ulaşmanız mümkün.Keza JS lere de böyle ulaşabilirsiniz.

Jquery i içeri alıp baya rahat çalışabilirsiniz.

http://www.borngeek.com/firefox/toolbar-tutorial/

adresinden abilerimiz çok detaylı anlatmış.

Kolay gelsin

MySQL de IFNULL metodu

No Comments

Böyle de güzel birşey varmış.Lazım oldukça öğrenme geleneği :) Bir sorgum var, işte bu sorgu bilmem ne alanına göre groupby yapıyor ve o alanın sum ını çekiyor buraya kadar sıkıntı yok.o sum alana göre order by yaptığımızda sıkıntı çıkıyor neden mi mersiniz? Çünkü NULL gelen değerler negatif değerlerin altında kalıyor.Null yerine 0 atmak işimizi çözüyor.İşte tam bu sırada Mysql in o güzel metodu imdadımıza yetişiyor.

Sorgu ve örnek kullanımı aşağıdaki gibidir.

SELECT p.*, f.forum_id, f.forum_name, t.*, u.username, u.username_clean,
u.user_sig, u.user_sig_bbcode_uid, u.user_colour,
IFNULL(SUM( av.vote),0) as post_votes
FROM phpbb_posts p LEFT JOIN phpbb_answer_votes av ON (post_id = av.answer_id)
LEFT JOIN phpbb_topics t ON (p.topic_id = t.topic_id)
LEFT JOIN phpbb_forums f ON (p.forum_id = f.forum_id)
LEFT JOIN phpbb_users u ON (p.poster_id = u.user_id)
WHERE p.post_id IN (14, 12, 11, 10, 9, 8, 7, 6, 5)
AND p.post_approved = 1 GROUP BY (post_id) ORDER BY post_votes DESC

PHP Framework Seçimi ve Performans Sorunu

No Comments

PHP konusunda junior seviyesinin üzerine çıkmış iki kişi bir araya geldiğinde büyük bir tartışma konusudur frameworkler ve performansları.

Frameworkler kod yazarken okurken ve düzeltirken can kurtarsa da performans olarak değerlendirildiği zaman sonuç biraz hüsran oluyor ben sizler için 2 gözde framewok Codeigniter ve Zend i ayrıca bunlara ek olarak Core php yi kıyasladım. Bunun içinhttp://avnetlabs.com/php/php-framework-comparison-benchmarks adresindenden aynı işleri yapan kodları indirip lokalize ettim ve sonra bunları Apache Benchmark Tool ile test ettim.

5 concurrency ve 1000 request göndererek kendi bilgisayarımda bu testi gerçekleştirdim.

Zend için test sonuçları :

mustafa@mustafa-laptop:~/public_html/test/zend/application$ ab -n 1000 -c 5 http://localhost/test/zend/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests

Server Software:        Apache/2.2.14
Server Hostname:        localhost
Server Port:            80

Document Path:          /test/zend/
Document Length:        1375 bytes

Concurrency Level:      5
Time taken for tests:   17.165 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      1588000 bytes
HTML transferred:       1375000 bytes
Requests per second:    58.26 [#/sec] (mean)
Time per request:       85.827 [ms] (mean)
Time per request:       17.165 [ms] (mean, across all concurrent requests)
Transfer rate:          90.34 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       2
Processing:    39   86  24.3     82     191
Waiting:       39   85  24.2     82     191
Total:         39   86  24.3     82     191

Percentage of the requests served within a certain time (ms)
  50%     82
  66%     94
  75%    101
  80%    106
  90%    119
  95%    131
  98%    143
  99%    149
 100%    191 (longest request)

Codeigniter için test sonuçları :

mustafa@mustafa-laptop:~/public_html/test/zend/application$ ab -n 1000 -c 5 http://localhost/test/codeigniter/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests

Server Software:        Apache/2.2.14
Server Hostname:        localhost
Server Port:            80

Document Path:          /test/codeigniter/
Document Length:        1400 bytes

Concurrency Level:      5
Time taken for tests:   7.937 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      1613000 bytes
HTML transferred:       1400000 bytes
Requests per second:    125.99 [#/sec] (mean)
Time per request:       39.684 [ms] (mean)
Time per request:       7.937 [ms] (mean, across all concurrent requests)
Transfer rate:          198.47 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.7      0      22
Processing:    18   40  13.4     38      86
Waiting:       18   39  13.3     38      86
Total:         18   40  13.4     38      86

Percentage of the requests served within a certain time (ms)
  50%     38
  66%     46
  75%     49
  80%     52
  90%     58
  95%     63
  98%     70
  99%     72
 100%     86 (longest request)

Evet şekilde de görüldüğü gibi bu kodlar için ki bu basit işlem yapan kodlar sadece veritabanına bağlanarak 4 adet satır çekip ekrana basıyor, görmüş olduk ki Codeigniter Zendframework e göre 2 kat civarında daha hızlı gibi duruyor.Fakat bu demek değildirki Codeigniter Zend den daha iyi bir framework.Zend in zengin kütiphanesi, esnekliği ve çok biçimli obje yönelimli yapısı ile Codeigniter ın ki kıyaslanamaz bile.

Burada temel sorun şu performans mı hızlı ve anlaşılabilir kod geliştirme mi ?

Mesela aynı işi core php yazarak yaptığımızda:

mustafa@mustafa-laptop:~/public_html/test/zend/application$ ab -n 1000 -c 5 http://localhost/test/php/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests

Server Software:        Apache/2.2.14
Server Hostname:        localhost
Server Port:            80

Document Path:          /test/php/
Document Length:        157 bytes

Concurrency Level:      5
Time taken for tests:   0.359 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      369000 bytes
HTML transferred:       157000 bytes
Requests per second:    2784.41 [#/sec] (mean)
Time per request:       1.796 [ms] (mean)
Time per request:       0.359 [ms] (mean, across all concurrent requests)
Transfer rate:          1003.37 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.2      0       2
Processing:     1    2   0.6      1       6
Waiting:        0    1   0.6      1       6
Total:          1    2   0.7      2       7
WARNING: The median and mean for the processing time are not within a normal deviation
        These results are probably not that reliable.

Percentage of the requests served within a certain time (ms)
  50%      2
  66%      2
  75%      2
  80%      2
  90%      3
  95%      3
  98%      4
  99%      4
 100%      7 (longest request)
mustafa@mustafa-laptop:~/public_html/test/zend/application$

gibi inanılmaz bir sonuç ortayha çıkıyor. Framework seçerken kriterimiz performans mı yoksa hızlı geliştirme mi? Mesela paranız var ve bir proje geliştireceksiniz.Para sizin için sorun değil ise Zend framework kullanıp sunucu sayısını çoklayabilir böylece hızlı ve okunaklı kod yazılmasını sağlayabilirsiniz.Zend framework ün o süper lifecycle ından doğan problemleri sunucu sayısını çoğaltarak aşabilirsiniz.

Diğer türlü evet sunucu sayınız az olur fakat core php yazıldığını düşünürsek herkesin kafasına göre kod yazdığı bir ortamda bir önceki yazılımcının işinin başka bir yazılımcı tarafından devam ettirilmesi çok zor olacaktır.Geliştirme süreçleri uzayacak, kodda bug çıkma ihtimali inanılmaz artacaktır.

Şu da yapılabilir. Frameworklerin biraz hantallaşmış yapılarından kurtulmak ve kodun aynı zamanda kodun anlaşılabilir olması için nasıl bir yol izlenmeli?

Bunun içinde kendi MVC yapınızı yazıp onu kullanmanız bir alternatif olarak değerlendirilebilir.Ama kabul edelim ki tek başınıza geliştirdiğiniz ve belli bir süre ayırdığnız kendi framework ünüz hiçbir zaman mevcut frameworklerden daha iyi olmayacak . Karar sizin, bence framework olmadan geliştirilen kod ciddi anlamda sıkıntı :)

PHP JAVA ve C# Inheritance Yapısı

2 Comments

Şöyle bir durum var. A diye bir sınıfım var.Bu A sınıfı B den miras alıyor.Peki A objesi oluşturulduğunda hangisinin constructor ı önce çalışacak.OOP yi az buçuk bilen bir kişi önce parent(B) sonra (A) nın constructorları çalışacak diyebilir.

Şimdi 3 örnek kod inceleyelim.PHP ve Java ve ASP.NET te ne gibi tepkiler veriyor. Java

public class Sinif1 extends Sinif2 {

    public Sinif1()
    {
        System.out.println("Sınıf1 constructor çalıştı");
    }
    public static void main(String[] args) {
        Sinif1 a = new Sinif1();
    }

}

public class Sinif2 {
    public Sinif2()
    {
        System.out.println("Sinif2 constructor çalıştı");
    }
}

Ekran çıktısı şu olacaktır:

Sinif2 constructor çalıştı
Sınıf1 constructor çalıştı

.NET Örneği

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    public class Sinif2
    {
        public Sinif2()
        {
            Console.WriteLine("Base constructor çalıştı");
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
    class Sinif1 : Sinif2
    {
        public Sinif1()
        {
            Console.WriteLine("Inherited ctor çalıştı");
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Sinif1 cls = new Sinif1();
            Console.ReadLine();
        }
    }
}

Ekran Çıktısı :

Base constructor çalıştı.
Inherited ctos çalıştı.

şekinde olacaktır.

PHP örneğinde ise

<?php
  class Sinif2
  {
    function __construct()
    {
      echo "Sinif2 constructor calisti.
";
    } 

  }

  class Sinif1 extends Sinif2
  {
    function __construct()
    {

      echo "Sinif1 constructor calisti.
";
    }
  } 

  $x = new Sinif1();

Ekran çıktısı şu şekilde oluyor:

Sinif1 constructor calisti.

Eğer üst sınıftaki constructor veya destructor ı çalıştırmak istiyorsanız. Mesela ilk olarak parent constructor çalışmasını istiyorsanız

  class Sinif1 extends Sinif2
  {
    function __construct()
    {

      parent:__construct();
    }
  }

Şeklinde kullanmalısınız.

Older Entries