Blog Kategorileri

Son Eklenen Konular

autoload ve factory pattern
Resim

Bu yazımda include, require, global, new gibi komut ve metodlarını kullanmadan oluşturduğunuz sınıflarınızı o anki çalışma betiğinize, programınıza dahil etmek ve sınıflarınızı herzaman global bir kullanımda başlatıp, istediğiniz heryerden erişebilmenizi saylayabilecek bir yazı hazırlamaya çalıştım.

ilk olarak bu kullanımda  __autoload metodundan bahsetmem gerekiyor.  __autoload hakkında daha fazla bilgi ve örnekleri için php.net sitesinde bu adrese bakabilirsiniz.

Adı geçen bu metod sınıflarımızın bize lazım olduğu zaman include veya require işlemlerini kendi yapıyor olması. Bir sınıfı başlatmak için ilk önce onu çalışma anına dahil edip new komutu ile başlatıyoruz, işte autoload metodu bizi burada sadece include ve require etmekten kurtarıyor.  Bu metodu kullanırken dikkat etmemiz gereken bazı hususlar var, bunlara kısaca değineyim sonrasında örnekler vereceğim.

1. olay class adımız ile class ımızı barındıran dosya isiminin aynı olması gerekmektedir, önek veya sonek kullanırsanızda bunu autoload metodunda belirtmeniz gerekir. mesala dosyadizin isminde bir class oluşturursak dosya adımız dosyadizin.php olmalıdır.

2. olay ise oluşturduğumuz claslarımızın belirli bir dizinde olması gerekmektedir örneğin lib, class, vs... isimli bir klasör altında olması gerekir. Farklı farklı klasörler içerisinde bulunuyorsa bunuda autoload metodumuz içerisinde belirtebiliriz fakat if elseif gibi mantıksal sınama işlemleri ile dizinleri tek tek dolaşmamız gerekebilir, kalsörleri gezmek yerine hepsinin bir yerde olması hem düzen hemde php için kolaylık olucaktır.

Örnek bir autoload metodumuzu yazalım.

php

	//CLASSDIR şeklinde sabit bir değişken oluşturuyoruz bu olay o kadar önemli değil metod içerisinde direk dizin adınıda yazabilirsiniz.
	define('CLASSDIR','web/class/');

	//autoload metod
	function __autoload($name){
	    if(file_exists(CLASSDIR."{$name}.php")){
	        include_once(CLASSDIR."{$name}.php");
	    }elseif (file_exists(CLASSDIR."{$name}.inc")){
		        include_once(CLASSDIR."{$name}.inc");
		}
	}

 

Yukardaki metodumuz içerisinde CLASSDIR sabit dağişkeninin tuttğu dizin (web/class/) içerisinde php ve inc uzantılı dosyalar var ise bunların otomatik dahil olmasını istediğimizi belirtiyoruz.

çalışma dosyamızın içerisine yukardaki autoload metodumuzu ekledikten sonra web/class/dosyadizin.php  ismindeki clasımızı başlatmak için artık bu dosyayı include etmemize gerek kalmadı direk olarak $dosyadizin = new dosyadizin(); diyerek sınıfımızı başlatabiliriz.

Metodun bize sağladığı kolaylık daha öncesinden lazım olan sınıf dosyamızı dahil ettikmi etmedikmi sıkıntısından kurtarmasıdır metodu birkere tanımladıktan sonra sınıflarımızı direk olarak kullanmaya başlayabiliriz.

Yukardaki anlattıklarım kadarıyla include ve require gibi kullanımları yazmaktan kurluyoruz çünki bunu autoload metodu bizim için otomatik olarak yapıyor.

include ve require kullanımını geçtik sıra geldi new olayına

İşte burada başlıkta adı geçen factory pattern olayına, factory olayı istediğimiz sınıfları new komutu ile başlatıp bize geri döndermesidir.

Şimdi bir sınıf oluşturup  bu oluşturduğumuz sınıfın diğer sınıfları istediğimiz zaman başlatıp bizim kullanımımıza vermesini istersek buna factory pattern diyebiliriz.

Şimdi benim oluşturduğum sınıfı inceleyelim

php

    class factory{
            
        private static $_instances = array();
        
        public static function loads( $sinif, array $param = array() ){   
            $p = false;
            $toplamParametre = count($param);
            
            if($toplamParametre >= 1){
                $func = create_function('&$val', 'return (string) $val;');
                $param = array_map($func, $param); 
                $paramS = array_fill(0,$toplamParametre,'%s'); 
                $olusacakParametre = implode(',',$paramS);
                $p = true;
            }
            
            if (array_key_exists($sinif, self::$_instances)) {
                 if($p){
                     if(method_exists(self::$_instances[$sinif], "__construct")){
                         call_user_func_array(array(self::$_instances[$sinif], "__construct"), $param);
                         return self::$_instances[$sinif];
                     }elseif(method_exists(self::$_instances[$sinif], $sinif)){
                         call_user_func_array(array(self::$_instances[$sinif], $sinif), $param);
                         return self::$_instances[$sinif];
                     }else{
                         return self::$_instances[$sinif];
                     }
                 }else{ 
                    return self::$_instances[$sinif];
                 }
            } 
            
            if($p == true){
                $string = '$start = new $sinif('.vsprintf($olusacakParametre,$param).');';
                @eval($string);
            }else{
                $start = new $sinif();
            }
            
            self::$_instances[$sinif] = $start;
            return $start;
        }
    }

 

İlk önce yukardaki factory sınıfım tam olarak şu işlemleri yapmaktadır.
İstediğim bir sınıfı başlatıror ve geri dönderiyor, sınıfı başlatırken kendi içerisinde bulunan static $_instance dizi değişkenimin içerisine dahil ediyor, bunun amacı başlattığım bir sınıfı tekrar başlatmadan bana tekrar daha önceden başlattığım sınıfı döndermesini istemiş olmam.

Bu kullanım sayesinde aynı sınıfı tekrar tekrar başlatmıyor ve bellekte sürekli yer işgal etmesini engellemiş oluyorum.

Şimdi bana lazım olan sınıfları şu şekilde başlatabilirim

php

    //$factory =& factory::loads('factory'); //sinifin kendine ihtiyacim olursa onuda gene ayni sekilde baslatabilirim
    $dom =& factory::loads('DOMDocument');// DOMDocument sınıfı veya php içerisinde olan diğer sınıflarıda başlatabilirim
    $dosyaDizin =& factory::loads('dosyadizin'); //konu içerisinde süekli adı geçen ama kendi görünmeyen dosyadizin sınıfımıda 

Dikkatinizi =& bu eşitleme çekti ise şu google araması sonuçlarını inceleyebilirsiniz.  Bu eşitlemedeki amaç aynısını oluşturmak yerine bir öncekinin ramde bulunduğu değerine eşitlemek. Kullanım adı pointer.

Şimdi yukardaki factory sınıfım ile __construct yani kurucu metodu parametreli ve veya parametreleri ile başlatmak istenirse.

php

$dosyaDizin =& factory::loads('dosyadizin',array('dizin','jpg')); //konu içerisinde süekli adı geçen ama kendi görünmeyen dosyadizin sınıfımıda 


Şeklinde 1. parametre dizin değeri, 2. parametre jpg değerinde başlatmasını istediğimizi belirtiyoruz.

Tam olarak şu işlemi yapıyor $dosyadizin = new dosyadizin('dizin','jpg'); şeklinde.


new komutunu geçtik sıra geldi global tanımına

Normalde değişkenlerimizi oluşturduğumuzda ve bu değişkenimizi bir metod içerisinde kullanmak istediğimizde, metod içerisinde global $degisken; şeklinde tanımlama yapmamız gerekir.

db sınıfımızı $db = new dbsinif(); değimizde bunu metod içerisinde  global tanımlamamız lazım fakat static metodları kullanırsak global tanımını kullanmamıza gerek kalmaz.

dbsinif için kullanım örneği

php

    function sonveriler(){
        $db =& factory::loads('dbsinif');
        $db->veriCek();
    }

 

comments powered by Disqus