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

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.

26 Mar

PHP-GTK örnek uygulama

Kodlarda yeteri kadar açıklama mevcut diye düşünerekten ayrıca bir açıklama yazmayacağım.
Bu kodların sadece linuxda çalışabileceğini de ekleyeyim.

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
/**
 * @author Ersin DOĞAN http ://www.ersindogan.com
 * Gmail posta kontrolü yapan basit bir servis
 */

class GmailServis {
   /**
    * gmail kullanıcı adı
    *
    * @var string
    */

   protected $_kullanici = null;
   /**
    * gmail şifre
    *
    * @var string
    */

   protected $_sifre = null;
   /**
    * gmail feed adresi , öntanımlı olan yeterli şimdilik
    *
    * @var string
    */

   protected $_servis_url = null;
   /**
    * Objenin kurucu metodu
    *
    * @param string $kullanici
    * @param string $sifre
    * @param string $servis_url
    */

   public function __construct($kullanici, $sifre, $servis_url = 'https://mail.google.com/mail/feed/atom') {
      $this->_kullanici = $kullanici;
      $this->_sifre = $sifre;
      $this->_servis_url = $servis_url;
      if (empty ( $this->_kullanici ) || empty ( $this->_sifre ) || empty ( $this->_servis_url )) {
         throw new Exception ( "Kullanıcı adı , şifre veya servis adreslerinden birini eksik girdiniz" );
      }
   }
   /**
    * Posta kutusunu kontrol eder
    *
    * @return SimplXMLElement
    */

   public function kontrol_et() {
      $_c = curl_init ( $this->_servis_url );
     
      curl_setopt ( $_c, CURLOPT_USERPWD, $this->_kullanici . ':' . $this->_sifre );
      curl_setopt ( $_c, CURLOPT_HTTPAUTH, CURLAUTH_ANY );
      curl_setopt ( $_c, CURLOPT_SSL_VERIFYPEER, 0 );
      curl_setopt ( $_c, CURLOPT_RETURNTRANSFER, 1 );
     
      return simplexml_load_string ( curl_exec ( $_c ) );
   
   }
}


class GmailKontrol extends GtkWindow
{
   /**
    *
    *
    * @var GtkVBox
    */

   protected $kutu;
   /**
    *
    *
    * @var integer
    */

   protected $durum;
   /**
    *
    *
    * @var GtkLabel
    */

   protected $eposta_durum;
   /**
    *
    * @var GtkStatusIcon
    */

   protected $status_icon;
   /**
    *
    * @var GmailServis
    */

   protected $servis;
   
    function __construct()
    {
        parent::__construct();

        $this->set_default_size(200,200);
        $this->set_position(Gtk::WIN_POS_CENTER_ALWAYS);
        $this->set_title('.::Gmail E-Posta Kontrol::.');
        $this->connect_simple('destroy', array('gtk', 'main_quit'));
        $this->add($this->__create_box());
        $this->hide_all();
    }
   /**
    * arayüzü oluşturuyoruz
    *
    * @return GtkVBox
    */

    protected function __create_box()
    {
      $this->kutu = new GtkVBox ( );
      $this->eposta_durum = new GtkLabel ( "GKontrol - Gmail Eposta Kontrol Aracı" );
      $this->kutu->pack_start ( $this->eposta_durum );
      $this->status_icon = new GtkStatusIcon ( );
      $this->status_icon->set_from_stock ( Gtk::STOCK_NO );
      $this->status_icon->set_tooltip_text ( 'Gmail E-Posta Kontrol' );
      $this->status_icon->connect ( 'activate', array ($this, 'on_activate' ) );
      $this->durum = 0;
      return $this->kutu;
    }
   
    /**
     * mailleri kontrol ederek
     * mail geldiğinde bizi uyarıyor.
     *
     */

   public function mail_kontrol(){
      $durum=$this->servis->kontrol_et();
      if($durum->fullcount>0){
         $this->bildirim('GPosta','Okunmammış '.$durum->fullcount.' epostanız mevcut');
         $this->status_icon->set_from_stock(Gtk::STOCK_YES);
         $this->status_icon->set_blinking(true);
      }else {
         $this->bildirim('GPosta','yeni eposta yok');
      }
   }
   /**
    * notification iconuna tıklandığında
    * çalışan metotdur
    *
    * @param  $statusicon
    */

   public function on_activate($statusicon) {
      if ($this->durum) {
         
         $this->hide_all ();
         
         $this->durum = 0;
     
      } else {
         
         $this->show_all ();
         $this->status_icon->set_from_stock(Gtk::STOCK_NO);
         $this->status_icon->set_blinking(false);
         $this->durum = 1;
     
      }
   
   }
   /**
    * bildirim başlığı
    *
    * @param string $baslik
    * @param string $bildirim
    */

   public function bildirim($baslik,$bildirim){
         // notify-send bir linux aracıdır ve bunu sisteminizde yoksa kurmalısınız
         // sudo apt-get install libnotify-bin
         // komutu ile
      $komut=sprintf('notify-send "%s" "%s" -t 1',$baslik,$bildirim);
      system($komut);
   }
   
   public function servisAyarla(GmailServis $servis){
      $this->servis=$servis;
   }
}

$gKontrol=new GmailKontrol();

$gServis=new GmailServis ( 'kullanıcı-adı', 'şifre' );

$gKontrol->servisAyarla($gServis);
/**
 * Gtk::timeout_add metodu, zamanlayıcı özelliği ile
 * bize, belirli aralıklarda gmail
 * posta kutusunu yoklama şansını veriyor
 */

Gtk::timeout_add(2000, array($gKontrol,'mail_kontrol'));
Gtk::main();
25 Feb

PHP ile barkod oluşturma

Evet bir yanlışlık yok, php ile barkod oluşturabilirsiniz. Üstelik bunun için phpde olmayan bir eklentiye de ihtiyaç duymuyoruz (GD kütüphanesi yeterli).
Yalnız bir kötülüğü var, o da barkodun yazdırılmasında PHP nin fonksiyonu kalmıyor ve bu da bazı sıkıntılara yol açabilir (barkodun yerleşimi vs ). Şahsen php ile barkod oluşturup okutmayı hiç denemedim, daha doğrusu deneme şansım olmadı. Önceden uğraştığım,yarım kalan bir projede C# ile barkod oluşturma işi ile uğraşmıştım.
Neyse, dönelim konumuza. PHP ile bunu yapabilmenin iki yolu var. Biri PEAR kütüphanesinde bulunan bir paket, burda buna değinmeyeceğim. Bunun birinci ve en önemli nedeni, artık bu paketin geliştirilmiyor olması. İkinci sebep ise PHP5 uyumluluğunun bulunmaması (en son böyleydi)
İkinci ve burda ele alacağımız yöntem ise ZendFramework 1.10 ile yeni gelen Zend_Barcode sınıfı aracılığı ile.
ZendFramework’un güzel özellilerinden biri, MVC (Model-View-Controller) yapısını kullanarak siteler geliştirebildiğimiz gibi, bünyesinde barındırdığı sınıfları web uygulamalarımız içerisinde de kullanabilmemizdir.
Biz de burada ZF’nin MVC özelliğini bir kenara bırakarak barkod oluşturma işlemimize geçelim. Kendi yerel web sunucumuzda test için kullanacağımız bir klasör oluşturalım.
Şurdaki linkten minimal paketi indirerek uygun bir klasöre açalım. Açtığımız dosyalar içerisindeki “library” klasöründeki “Zend” klasörünü web sunucumuzda test için oluşturduğumuz bir klasöre kopyalayalım.
Daha sonra yine aynı klasörde index.php dosyası oluşturalım ve şu kodları yazalım :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
require_once 'Zend/Barcode.php';
# text parametresi barkod üzerine yazılacak
# yazıyı temsil etmektedir
$barcodeOpsiyonlari = array('text' => 'ERSIN-DOGAN');
#

#
// zoeunlu olmayan opsiyonlar
#
$rendererOpsiyonlari = array();
#
$renderer = Zend_Barcode::factory(
#
   'code39', 'image', $barcodeOpsiyonlari, $rendererOpsiyonlari
#
);
$renderer->render();

Bu kodları çalıştırdığımızda karşımıza Code39 biçiminde barkod çıktısı verecektir.

Yukarıdaki kodları açıklamaya çalışalım. Zend_Barcode sınıfı barkod oluşturmak için factory metodunu kullanır ve şu parametreleri alır
-Barkod tipi
desteklenen tipler:
Code25
Code25interleaved
Code39
Ean2
Ean5
Ean8
Ean13
….
-render tipi (image,pdf veya sizin kendi oluşturacağınız bir render metodu)
-barkod opsiyonları
-render (render için uygun bir Türkçe karşılık bulamadım) opsiyonları.

Daha ayrıntılı bilgiye ZF’nin kendi sitesinden ulaşabilirsiniz.