Perl ile CGI Programlama

 

 

BÖLÜM 5: İLERİ DÜZEY FORM İŞLEME


Bir önceki bölümde formlardan gelen verilerin nasıl çözülüp ayrıştırılacağını ve nasıl form-mail göndereceğimizi öğrendik. Ancak, bir problemi gözardı ettik: hata kontrolü yok ve verileri kendimize özel işleme yeteneği yok. Boş form almak istemezsiniz yada formdaki belli alanların kesinlikle doldurulmasını isteyebilirsiniz. Yada verilen cevaplara göre farklı farklı davranan yeni sayfalar gönderebilirsiniz kullanıcıya. Bütün bunlar için biraz daha ileri 

Formdan gelen verileri işlerken, gelen verilere göre farklı işlemler yapabilmek için şartlı işletimi kullanmak zorundayız. Bunun için if-else yapısı kullanılır:

if ($degisken1 eq "string_değer1") {
  ... bu test doğru ise işletilecek kodlar
}
elsif ($degisken2 eq "string_değer2"){
  ... bu test doğru ise işletilecek kodlar
}
else {
  ... aksi hallerde işletilecek kodlar
}

Bu yapıdaki elsif ve else blokları seçimliktir, eğer sadece bir değişkenin belirli bir durumu test edilecekse tek if bloğu kullanmak yeterlidir, biliyorsunuz. 

if ($age > 27) {
  print "Benden daha yaşlısın dostum.\n";
}

Perl'de, test edilecek değişkenin string veya sayı olmasına göre farklı test operatörleri vardır. Bunlar aşağıdaki tabloda verilmiştir.

 

Test

Sayılar 

String'ler

 $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 veya eşit $y

  $x >= $y

  $x ge $y

 $x küçüktür $y

  $x < $y

  $x lt $y

 $x küçük veya eşit $y

  $x <= $y

  $x le $y

Temel olarak, eğer test string testi ise (eq, ne, lt vb.) harf operatörler, sayısal test ise (==, !=, > vb.) semboller kullanılır. Çoğu zaman formdan gelen veriler string olarak ele alınırlar. Şimdi, mail.cgi programında biraz değişiklik yapalım ve kullanıcının boş veri göndermesi durumunda onu uyaralım. 

if ($FORM{'username'} eq "") {
  &dienice("Lütfen isminizi girmeyi unutmayınız...");
}

Burada daha önceden yazmış olduğumuz "dienice" altprogramını çağırıyoruz. Şimdi, eğer kullanıcıdan boş form alanı gönderilirse, kullanıcı yukarıdaki hata mesajını alacaktır. 

Bu testi sadece username için değil, diğer bütün alanlar için uygulayabiliriz.

if ($FORM{'username'} eq "" or $FORM{'email'} eq "" or $FORM{'age'} eq "") {
  &dienice("Lütfen isminizi, email adresinizi ve yaşınızı giriniz...");
}

Yukarıdaki kodda testler "or" operatörü ("||" şeklinde de yazılabilir) ile birleştirilmiştir. Eğer testlerden herhangi biri "doğru" ise sonuç "doğru" olur ve test sağlanmış olur.

İşaretleme Kutucukları

Kullanıcıya seçeneklerden bir veya birkaçını seçebilmesi için formunuza işaretleme kutucukları (checkboxes) koyabilirsiniz. Bu yolla da kullanıcıdan veri girmesini sağlayabilirsiniz. Fakat bunu CGI programında nasıl çözeceğiz?

Eğer işaretleme kutucukları ile girilen verileri email olarak almak isterseniz, her birine farklı bir isim vermelisiniz. Şimdi yeni bir HTML dosyası açın ve colors.html olarak kaydedin. Dosyaya aşağıdaki formu girin.

<html><head><title>Renkler</title></head> 
<body> 
<form action="colors.cgi" method="POST"> 
 
<h3>En çok sevdiğiniz renk nedir ?</h3> 
<input type="checkbox" name="kirmizi" value=1> Kırmızı<br> 
<input type="checkbox" name="yesil" value=1> Yeşil<br> 
<input type="checkbox" name="mavi" value=1> Mavi<br> 
<input type="checkbox" name="altın" value=1> Altın<br> 
 
<input type="submit" value="Gönder"> 
 
</form> 
</body></html>

http://alaeddin.cc.selcuk.edu.tr/~adem/colors.html

Bu örnekte kullanıcı, bir yada daha çok rengi seçebilir. Kullanıcının kutucuğu işaretlemesi durumunda karşı tarafa value ile belirtilen değer (bu örnekte value=1 denildiği için 1 değeri) gönderilir. Formu işlerken işaretleme kutucuğu, bu değere göre teste tabi tutulur. İşlemede kolaylık olsun diye tüm işaretleme kutucuklarının value'lerine aynı değer verilir. Bu formu işleyen colors.cgi programı aşağıda verilmiştir.

#!/usr/bin/perl
 
print "Content-type:text/html\n\n";
 
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
  ($name, $value) = split(/=/, $pair);
  $value =~ tr/+/ /;
  $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
  $FORM{$name} = $value;
}
 
print "<html><head><title>Renkler</title></head>\n";
print "<body>\n";
print "<h2>Sonuçlar</h2>\n";
 
@renkler = ("kirmizi","yesil","mavi","altin");
print "Seçtiğiniz renkler:\n<hr>\n";
foreach $x (@renkler) {
  if ($FORM{$x} == 1) {
         print "$x<br>";
  }
}
 
print "</body></html>\n";

http://alaeddin.cc.selcuk.edu.tr/~adem/colors.cgi.txt

NOT: Eğer form içerisinde value=1 değil de value="1" şeklinde yazarsanız, CGI içerisinde test ederken if ($FORM{$x} == 1) ifadesindeki == operatörü yerine string'lerde karşılaştırma için kullanılan eq operatörünü kullanmak zorundasınız. Değilse programınız doğru çalışmayabilir.

Radyo Butonları

Radyo butonları, form içerisinde aynı alan ismi ve farklı value değerleri ile kullanılarak birkaç seçenek arasından kullanıcının sadece bir tanesini seçebilmesi için kullanılır. 

Şimdi colors.html dosyasını colors2.html olarak kopyalayalım ve işaretleme kutucukları yerine radyo butonlarını kullanalım.

<h3>En çok sevdiğiniz renk nedir ?</h3> 
<input type="radio" name="color" value="Kırmızı"> Kırmızı<br> 
<input type="radio" name="color" value="Yeşil"> Yeşil<br> 
<input type="radio" name="color" value="Mavi"> Mavi<br> 
<input type="radio" name="color" value="Altın"> Altın<br> 

http://alaeddin.cc.selcuk.edu.tr/~adem/colors2.html

Bu formu işlerken, işaretleme kutucuklarının kullanıldığı formu işlerken yaptıklarımızı yapacağız, ancak, aşağıdaki değişikliği yapmamız gerekir.

print "Seçtiğiniz renk :\n<hr>\n $FORM{'color'}\n";

Burada tek bir değişkenin -color- değerine bakıyoruz. Şimdi bir adım daha ileri gidelim ve sonuçların gösterildiği sayfanın zemin rengi, kullanıcının seçtiği renkte olsun isteyelim. Bunun için colors2.cgi dosyası içerisinde değişiklik yapalım ve aşağıdaki kodları ekleyelim.

%renkler = ("Kırmızı" => "FF0000",
      "Yeşil"   => "00FF00",
      "Mavi"    => "0000FF",
      "Turuncu" => "FFcc00");
 
print "<html><head><title>Renkler</title></head>\n";
print "<body bgcolor=$renkler{$FORM{'color'}}>\n";

http://alaeddin.cc.selcuk.edu.tr/~adem/colors2a.html

http://alaeddin.cc.selcuk.edu.tr/~adem/colors2a.cgi.txt

Yukarıdaki örnekte kullanıcının seçtiği renk zemin rengi olarak kullanılmaktadır. Burada %renkler adında bir tablo kullanılarak kullanıcının seçtiği rengin hexadesimal karşılığı tablodan bulunmakta ve bulunan bu değer sayfanın bgcolor=... özelliğine atanmaktadır.

Menülerle Çalışmak (SELECT)

Select alanları, kullanım olarak radio butonları ile aynıdır, ancak bu alanlar HTML sayfasında aşağı-çekmeli menüler (pull -down menu) şeklinde görünürler:

http://alaeddin.cc.selcuk.edu.tr/~adem/colors2b.html

Burada da, radyo butonlarında olduğu gibi, kullanıcının tercihi aşağıdaki gibi öğrenilir.

print "Seçtiğiniz renk :\n<hr>\n $FORM{'color'}\n";

Bu tür bir menüden sadece bir seçenek seçilebilir. Eğer birden çok seçime imkan vereceksek CGI.pm modulünü kullanmamız gerekir. Ancak biz burada aşağıdaki gibi basit bir örnek verebiliriz:

<html>
<head><title>Renkler</title>
</head> 
<body> 
<form name="renk" action="colors2c.cgi" method="POST"> 
İsminiz: <input name="isim" type="text" value="Adem" size=25><br>
En çok sevdiğiniz renk nedir ? <br> 
<SELECT multiple size=10 name="color">
      <OPTION value="hicbiri">(Hiçbiri)</OPTION>
      <OPTION selected value="kirmizi">Kırmızı</OPTION>
      <OPTION selected value="yesil">Yeşil</OPTION>
      <OPTION value="mavi">Mavi</OPTION>
      <OPTION value="turuncu">Turuncu</OPTION>
      <OPTION value="sari">Sarı</OPTION>
</SELECT>
<input type="submit" value="Gönder"> 
</form> 
 
</body></html>
 
http://alaeddin.cc.selcuk.edu.tr/~adem/colors2c.html

Şimdi de bu formu işleyen CGI kodlarına bakalım.

#!/usr/bin/perl
 
print "Content-type:text/html\n\n";
 
@secilenler = ();
 
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
    ($name, $value) = split(/=/, $pair);
    $value =~ tr/+/ /;
    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
    $FORM{$name} = $value;
    if ($name eq "color"){
  push(@secilenler, $value);
    } 
}
 
%renkler = ("kirmizi", "red", 
            "yesil", "green",
            "mavi", "blue",
            "turuncu", "orange",
            "sari", "yellow");
 
print "<html><head><title>Renkler</title></head>\n";
print "<body>\n";
print "<h2>Sonuçlar</h2>\n";
 
print "Seçtiğiniz renkler:\n<hr><b>\n";
 
foreach $x (@secilenler) {
  if ($renkler{$x}) {
         print "<font color=$renkler{$x} > $x -> [$FORM{'isim'}]<br>";
  }
}
 
print "</body></html>\n";

http://alaeddin.cc.selcuk.edu.tr/~adem/colors2c.cgi.txt

Anket Formları ve CGI

Şimdiye kadar öğrendiklerimizi içeren komple bir örnek üzerinde çalışalım. Bu bir anket formu ve bunu değerlendiren bir CGI modülü olsun. Sitenize böyle bir anket formu eklerseniz, ziyaretçileriniz hakkında çeşitli bilgiler öğrenebilirsiniz.

Şimdi bir HTML dosyası açalım ve aşağıdaki bilgileri girelim:

<html>
<head>
  <title>Anket Formu</title>
</head>
<body>
<h2>Anket Formu</h2>
<font face="courier" size="-1">
<form action="survey.cgi" method="POST">
İsminiz          : <input type="text" name="isim" size=30><br>
E-mail adresiniz : <input type="text" name="email" size=30><br>
Bu siteyi nereden keşfettiniz ? 
<select name="howreach">
<option value=0 selected>Birini seçiniz...
<option value=1>Dergilerden
<option value=2>Önceden imlenen sitelerden
<option value=3>Bir arama motorundan
<option value=4>Bir başka sitedeki linkten
<option value=5>Bir kitaptan
<option value=6>Diğer
</select>
<br>
Değerlendirmede bu siteye 5 üzerinden kaç verirsiniz?<br>
Berbat 
<input type="radio" name="rating" value=1> 1
<input type="radio" name="rating" value=2> 2
<input type="radio" name="rating" value=3> 3
<input type="radio" name="rating" value=4> 4
<input type="radio" name="rating" value=5> 5 Mükemmel
<br>
Şu sıralar uğraştığınız alan nedir? (uyanları seçiniz):<br>
<input type="checkbox" name="des" value=1> Web sitesi hazırlama<br>
<input type="checkbox" name="svr" value=1> Web sunucusu adminliği<br>
<input type="checkbox" name="com" value=1> Elektronik ticaret<br>
<input type="checkbox" name="mkt" value=1> Web Marketing<br>
<input type="checkbox" name="edu" value=1> Web eğitimi<br>
Varsa, diğer yorumlarınız...?<br>
<textarea name="comments" rows=5 cols=70 wrap="VIRTUAL">
</textarea>
<br>
<input type="submit" value="Gönder">
</form>
 
</body></html>

http://alaeddin.cc.selcuk.edu.tr/~adem/survey.html

Şimdi de bu formdan gelen bilgileri işleyen survey.cgi modülünü yazalım.

#!/usr/bin/perl
print "Content-type:text/html\n\n";
 
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
    ($name, $value) = split(/=/, $pair);
    $value =~ tr/+/ /;
    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
    $FORM{$name} = $value;
}
 
%howreach = (
  1 => "Dergilerden",
  2 => "Önceden imlenen sitelerden",
  3 => "Bir arama motorundan",
  4 => "Bir başka sitedeki linkten",
  5 => "Bir kitaptan",
  6 => "Diğer");
 
print <<EndHTML;
<html><head><title>Sonuçlar</title></head>
<body>
<h2>Sonuçlar</h2>
 
<b>Girdiğiniz Bilgiler:<br></b>
İsminiz: $FORM{'isim'}<br>
E-mail adresiniz : $FORM{'email'}<br>
Nereden keşfettiniz : $howreach{$FORM{'howreach'}}<br>
Verdiğniz not (1-berbat, 5-mükemmel) : $FORM{'rating'}
<br>
EndHTML
;
%boxes=("des" => "Web sitesi hazırlama",
  "svr" => "Web sunucusu adminliği",
  "com" => "Elektronik ticaret",
  "mkt" => "Web Marketing",
  "edu" => "Web eğitimi");
print "Uğraştığınız iş(ler):<br>\n";
foreach $key (keys %boxes) {
    if ($FORM{$key} == 1) {
  print "- $boxes{$key}<br>\n";
    }
}
print <<EndFoot;
Yorumlarınız:<br>
$FORM{'comments'}
<p>
</body></html>
EndFoot
;

http://alaeddin.cc.selcuk.edu.tr/~adem/survey.cgi.txt

Bu örnekte kullanıcının girdiği bilgiler bir sonuç sayfasına HTML olarak yazdırılmaktadır. Fakat, sonuçlar bir e-mail olarak da gönderilebilir. Bun yapmak için, Bölüm 4'te de anlatıldığı üzere, <<EndHTML deyimlerini MAIL kanalına yönlendirmek gerekir.

print MAIL <<EndHTML;

Bu deyim, standart çıktı (ekran) yerine mesajları bir MAIL kanalına yazacaktır.

Bir sonraki bölümde bu tür formlardan gelen verileri, e-mail yerine özel bir veri dosyasına kaydedip sonra incelemeyi öğreneceğiz.


Bölüm 4Bölüm 6