Perl ile CGI Programlama

 

BÖLÜM 2: PERL HAKKINDA


Perl ile daha ileri düzey programlar yazabilmek için Perl hakkında bazı şeyleri bilmek gerekir. Değişkenler, karar yapısı (if) ve karşılaştırma operatörleri, döngü yapısı (foreach), alt programlar vb. gibi konuları azgari düzeyde bilmek lazımdır.

Değişkenler

Bir değişken, daha sonra kullanmak üzere bir değeri geçici olarak saklayan bellek bölgesidir. Perl’de 3 tür değişken vardır: skaler değişkenler (scalars), diziler (arrays), ve özel tablolar (hashes).

Skaler Değişkenler (Scalars)

Bir skaler değişken tek bir skaler değer içerir. Perl’de skaler değişkenler ön ek olarak bir $-dolar işareti ile başlarlar. Örneğin, $x, $y, $z, $kullanici ve $url hepsi birer geçerli skaler değişken isimleridirler. Değişken isimleri rakamla başlayamaz, boşluk ve extra (standart dışı) karakterler içeremezler. Bir harfle başlamak zorundadırlar, daha sonra rakam bulundurabilirler. En fazla 32 karakter uzunluğunda olabilirler. Perl’de skaler değişkenler için sayısal, string yada mantıksal diye bir ayrım söz konusu değildir. İşte örnek birkaç değişken:

$isim = "Adem Güneş";
$yas = 27;
$mesaj1 = "$isim şu anda $yas yaşındadır.";
$mesaj2 = '$isim şu anda $yas yaşındadır.';
$pi = 3.141592;

Soru: Tek tırnak ile çift tırnak arasındaki fark nedir?
Cevap: Çift tırnak arasına alınanlar yorumlanırlar, tek tırnak arsında olanlar yorumlanmazlar, olduğu gibi ekrana yazdırılırlar. Yani,

print mesaj1; --> Adem Güneş şu anda 27 yaşındadır.
print mesaj2; --> $isim şu anda $yas yaşındadır.

Perl’de değişkenleri kullanmadan önce deklare etmek zorunda değiliz. İstediğimiz anda bir değişkeni tanımlamaksızın kullanabiliriz. (Eski GWBASIC’i hatırlayın.. Ne günlerdi ama?...) Ayrıca, Perl değişkenleri anında tür değiştirebilirler. Örneğin,

$MyVar = 23;
$MyVar = "Sihirli sayı $MyVar.";

Perl, bu konuda diğer dillerin yaptığı gibi kapris yapmayacak ve tip dönüşümü derhal kabul edecektir. Şimdi, first.pl betiğimize yeniden dönelim ve iki tane skaler değişken ekleyelim

#!/usr/bin/perl
 
$kurs = "Perl ile CGI Programlama";
print "Selam beyler. İsminizi giriniz: ";
$isim = <STDIN>;
chomp($isim);
print "Merhaba $isim. $kurs kursuna hoş geldiniz.\n"; 

Programı kaydedin ve çalıştırın. Bu kez program sizden isminizi girmenizi isteyecek. Aşağıdaki satır ile klavyeden girdiğiniz veriler $isim değişkenine aktarılmaktadır:

$isim = <STDIN>

İsmimizi yazdıktan sonra genellikle ENTER’a basarız. Salt girilen veriyi elde etmek için ENTER karakterini değişkenden ayıklamak gerekir. Bunun için aşağıdaki deyim kullanılır:

chomp($isim)

print deyimi ile de mesajları, değişkenleri ve sabitleri ekrana yazdırırız. Satır başı yapmak için C’de olduğu gibi, “\n” kullanılır.

Diziler (Arrays)

Bir dizi değişkeni, birden çok değer içeren bir listedir. Bir skaler değişkende tek bir değer saklanırken bir dizi değişkende birden çok değer tutulabilir. Perl’de dizi değişkenler ön ek olarak bir @-muşmulla işareti ile başlarlar. Örneğin;

@renkler = ("kırmızı", "yeşil", "mavi");

Perl’de dizi indisleri 0’dan başlar. Örneğin, @renkler dizisinin ilk elemanını belirtmek için @renkler[0] şeklinde ifade kullanılır. Belirtmek gerekirse, bir dizinin tek bir elemanı ile ilgileniliyorsa, @-işareti yerine $-işareti kullanılır. Hemen belirtelim ki; $-işareti tek bir değeri belirtirken @-işaretinin anlamı ise, dizinin tamamından bahsediyoruz, demektir.

Dizideki elemanları ele alırken tek tek erişebileceğimiz gibi bir döngü değişkeni ile de ele alabiliriz. Aşağıdaki iki örneği inceleyin:

#!/usr/bin/perl
# Bu satır açıklama satırıdır...
# #-diyez işareti ile başlayan satırlar açıklama olarak kabul edilir.
 
@renkler = ("kırmızı","yeşil","mavi");
print "$renkler[0]\n";
print "$renkler[1]\n";
print "$renkler[2]\n";

Aynı programı foreach yapısını kullanarak yazalım.

#!/usr/bin/perl
 
@renkler = ("kırmızı","yeşil","mavi");
foreach $r (@renkler) {
    print "$r\n";
} 

Yukarıda bir foreach döngüsü görülmektedir. Her iterasyonda $r değişkenine sırasıyla @renkler dizisindeki elemanların değerleri atanır. Yaylı parantezler ise döngünün başlangıç ve bitiş noktalarını belirtmektedir. $r’ye döngü değişkeni denir.

foreach döngüsünün genel yapısı şöyledir:

foreach $degisken (@dizi) {
    ... burada döngü deyimleri yer alır
} 

Dizi Fonksiyonları

Perl’de dizilere eleman eklemek, elaman silmek, iki diziyi birleştirmek, dizideki elemanların sıralarını kaydırmak vb. işlemleri gerçekleştirmek için bir takım hazır fonksiyonlar vardır. Bunlara dizi fonksiyonları denilmektedir. Aşağıdaki örneği inceleyelim:

@renkler=("kırmızı","yeşil","mavi","ciyan","magenta","siyah","sarı"); 
$renk = pop(@renkler);    # dizideki son elamanı, "sarı"yı, verir.
$renk = shift(@renkler);  # dizideki ilk elamanı, "kırmızı"yı, verir. 

Bu örneklerde, dönen değeri $renk adlı değişkende tuttuk, ancak tutmadan da doğrudan kullanmak mümkündür. Her iki deyim, pop ve shift, diziden ilgili elemanları silmek yok etmek için kullanılır. Diziye elaman eklemek için push komutu kullanılır.

push(@renkler, "turuncu");    # @renkler dizisinin sonuna “turuncu”
                                eklenir
@ilaverenkler = ("mor", "koyuyeşil", "kirlibeyaz");
push(@renkler, @ilaverenkler); # @ilaverenkler dizisini @renkler
                                dizisinin sonuna ekler 

Dizilerle ilgili çok kullanılan bazı fonksiyonlar şunlardır:

sort(@renkler)       # Dizideki elamanları alfabetik olarak sıralar
reverse(@renkler)    # Dizideki elemanları tersinden yer değiştirir
$#renkler            # renkler dizisinin uzunluğu (eleman_sayısı - 1)
join(", ", @renkler) # Dizideki elemanların aralarına virgül koyarak
                       bir string olarak birleştirir

Tablolar (Hashes)

Tablolar, dizilerin özel bir hali olup her bir eleman; “anahtar - değer” şeklindeki iklili gruplardan oluşur. Perl’de tablo isimleri %-yüzde işareti ile başlarlar. Örneğin;

 Tablo adı        Anahtar  Değer
%websayfalari = ( "adem",  "http://alaeddin.cc.selcuk.edu.tr/~adem/",
                  "emre",  "http://alaeddin.cc.selcuk.edu.tr /~emre/",
                  "canan", "http://alaeddin.cc.selcuk.edu.tr /~canan/" ); 

Yada aynı tablo aşağıdaki gibi de tanımlanabilir:

%websayfalar = ( "adem" =>  "http://alaeddin.cc.selcuk.edu.tr/~adem/",
                 "emre" =>  "http://alaeddin.cc.selcuk.edu.tr/~emre/",
                 "canan" => "http://alaeddin.cc.selcuk.edu.tr/~canan/" ); 

Bu örnekte tablodaki her bir eleman, bir kullanıcı ismi ve ona ait web sayfasından oluşmaktadır. Tıpkı dizilerde olduğu gibi, tablolarda da her bir elemanı bir skaler gibi düşünmek mümkündür. Örneğin, aşağıdaki deyim, “adem”e ait URL’yi ekrana yazacaktır.

print "$websayfalari{'adem'}\n";

Bir tablodaki tüm elemanlarını (anahtarlarını ve karşılık gelen değerlerini) ekrana yazdırmak için aşağıdaki gibi bir foreach yapısı kullanılır:

foreach $kisi (keys %websayfalari) {
    print "$kisi ve web sayfası : $websayfalari{$kisi}\n";
}

Bu örnekte, tablodaki anahtarları bir dizi olarak veren keys adlı bir fonksiyon kullanılmıştır. Burada bir hususa dikkat etmek gerekir: “keys %tabloadi” şeklindeki bir kullanımda dönen değerler tablodaki doğal sıraya yada alfabetik sıraya göre değil rastgele bir sıraya göre olmaktadır. 

keys fonksiyonu kullanmak yerine biz kendimiz de değerler belirtebiliriz:

foreach $kisi ("emre", "adem", "canan") {
    print "$kisi ve web sayfası : $websayfalari{$kisi}\n";
}

Tablolar, CGI programlamada özellikle bir form’dan gelen verileri ayrıştırmak için oldukça kullanışlıdırlar. Örneğin, $FORM{'soyad'} şeklindeki bir kullanım ile kullanıcının form’daki ‘soyad’ alanına girdiği veriyi öğrenmekteyiz.

Şimdi, tablolar ve foreach döngüsü konularında öğrendiklerimizi bir örnek vererek pekiştirelim:

#!/usr/bin/perl
 
# #-işareti Perl'de açıklama anlamına gelir. Unutmayın...
%websayfalari = ( "adem" =>  "http://alaeddin.cc.selcuk.edu.tr/~adem",
                  "emre" =>  "http://alaeddin.cc.selcuk.edu.tr/~emre",
                  "canan" => "http://alaeddin.cc.selcuk.edu.tr/~canan" );
 
print "Content-type:text/html\n\n";
print <<EndHdr;
  <html><head><title>URL Listesi</title></head>
  <body bgcolor="#ffffff">
  <p>
  <h2>URL Listesi</h2>
  <ul>
EndHdr;
  foreach $kisi (keys %websayfalari) {
      print "<li><a href=\"$websayfalari{$kisi}\">$kisi</a>\n";
  }
  print <<EndFooter;
  </ul>
  <p>
  </body>
  </html>
EndFooter; 

http://alaeddin.cc.selcuk.edu.tr/~adem/cgi-kitap/cgi-bin/urllist.cgi

Yukarıdaki kodları, urllist.cgi adında bir dosya olarak kaydedin, erişim haklarını değiştirerek çalıştırılabilir yapın. Web tarayıcınızdan çağırarak sonucu görün.

Karar Yapısı, if deyimi

if deyimi diğer dillerde olduğu gibi Perl programcılığının da temelini oluşturur, bazı şeyleri test etmek için kullanılır. Test sonucunun doğru yada yanlış olması durumuna göre farkı deyimler işletilir. Örneğin, siz bir sisteme login olmak istediniz, eğer şifreniz doğru ise sizi kabul eden, aksi halde şifrenizin hatalı olduğunu söyleyen bir programda böyle bir yapı kullanmak zaruridir. Bu söylediğimize benzer bir örnek verelim.

#!/usr/bin/perl
print "Content-type:text/html\n\n";
 
$MyName = "Adem";
$YourName = "$ENV{'QUERY_STRING'}";
 
@values = split(/\&/, $ENV{'QUERY_STRING'});
foreach $i (@values) {
        ($varname, $YourName) = split(/=/, $i);
}
 
if ($MyName eq $YourName){
    print "İsimlerimiz aynı. Biz adaşız...\n";
    print "<br>Biliyorsun \"Adem\" yaratılan ilk insanın ismidir.\n"
}
else {
    print "İsimlerimiz aynı değil. Biz adaş değiliz...\n";
} 

Yukarıdaki kodları ask.cgi adında bir dosyaya kaydedelim ve bu betiği çağıran aşağıdaki gibi bir form dosyası (form3.html) hazırlayalım ve deneyelim.

<form action="env.cgi" method="GET">
      İsminizi giriniz: <input type="text" name="isim" size="20">
      <p>
</form> 

http://alaeddin.cc.selcuk.edu.tr/~adem/cgi-kitap/cgi-bin/ask.html

Bu örnekte henüz bilmediğimiz çok şey var: formlar, formlarıin işlenmesi ve ortam değişkenleri vb konular. Bu konular sonraki bölümlerde ayrıtılı olarak ele alınacaktır. Lütfen, panik yapmayın...

Bir if deyiminin genel yapısı şöyledir:

if (test1) {
    test1 sonucu ‘true’ iken çalışacak deyimler;
...
}
elsif (test2) {
       test2 sonucu ‘true’ iken çalışacak deyimler;
...
}
else {
      test2 sonucu ‘false’ iken çalışacak deyimler;
...
} 

else ve elsif blokları şeçimliktir; gerektiğinde kullanılır, gerekmediğinde kullanılmazlar. Bu örnekte $MyName değişkeni ile $YourName değişkenlerinin eşit olup olmadıkları test edilmiştir. Eşitlik testi için ‘eq’ operatorü kullanılmıştır. Perl’de test ettiğimiz değişkenin string veya sayı olmasına göre farklı karşılaştırma operatörleri mevcuttur.

Test

Sayılar için

String’ler için

$x eşittir $y

$x == $y

$x eq $y

$x eşit değildir $y

$x != $y

$x ne $y

$x büyüktür $y

$x > $y

$x gt $y

$x büyük eşittir $y

$x >= $y

$x ge $y

$x küçüktür $y

$x < $y

$x lt $y

$x küçük eşittir $y

$x <= $y

$x le $y

(Bu bölümde bazı eksik konular var: Mesela, döngüler, alt programlar (function), hata yakalama vb.)

Bölüm 3’te ortam değişkenlerine değineceğiz ve GET metodunu kullanarak formların postalanması konusunda lüzumlu laflar edeceğiz.