![]() |
![]() |
![]() |
![]() |
Bölüm 4: Form İşlemePOST metodunda bilgiler URL ile birlikte gönderilmediği GET metodundan daha güvenlidir. POST metodunun GET metoduna bir diğer üstünlüğü de daha fazla bilgi gönderebilmesidir. Ayrıca, GET metodu ile gönderilen bilgiler web browser, web server ya da proxy server'ın kaşe belleğinde (cache) saklanabilir fakat POST metodu ile bilgiler her defasında yeniden gönderilir. Dezavantajı ise POST ile gönderilen bilgiler daha karmaşık olacağından dolayı bu bilgileri çözmek için daha biraz daha karmaşık bir kod yazmamız gerekir. Web server, form bilgilerini CGI programına kodlayarak gönderir. Alfanumerik karakterler olduğu gibi gönderilir; boşluklar artı (+) işaretine çevrilir; tab, çift tırnak (") gibi özel işaretler de "%HH" şeklinde kodlanır. Burada "HH" karakterin ASCII karşılığının hexadesimal (16'lık sistemdeki) değeridir. Bu kodlama işlemine "URL kodlama" denir. Aşağıdaki tabloda sık kullanılan bazı karakterlerin kodlanmış karşılıklarını görebilirsiniz.
Gönderilen bilgiyle işe yarar şeyler yapabilmek için CGI bu kodlanmış bilgiyi çözmelidir. Neyse ki Perl'de substitute ve translate komutlarıyla bunu yapmak oldukça kolaydır. Perl, karakter içerisinde arama yapma ve değiştirme konusunda oldukça yeteneklidir. substitute komutunun temel yazılış biçimi aşağıdaki gibidir.
Bu örnek $yazi scalar değişkeninde aranan kelimesinin yerine yerinekonan kelimesini koyar. Araya konan operatör =~ (eşittir ve yanında tilde) işaretidir. Daha iyi anlaşılacağını düşündüğüm başka bir örnek:
$selamlama =~ s/xnamex/Sinan/; print $selamlama; Yukarıdaki örnek "Merhaba. Benim adım Sinan." yazdıracaktır. $selamlama değişkeninde "xisimx"in yerini "Sinan"ın aldığına dikkat edin. Buna yakın fakat bir parça farklı bir komut da translate komutudur.
Bu komut "arananlistesi"ndeki bütün karakterleri "yerinekonan" listesindekilerle değiştirir. İşte bir örnek:
Bu örnek bütün yazıyı küçük harfe çevirir. [A-Z]'deki parantezler karşılaştırılacak karakter sınıfını belirtir. Şimdi tekrar formlara dönelim. Formla gönderilen bilginin kodunu çözmeniz için bilgide iki değişiklik yapmalısınız:
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; İlk satırda + işaretleri boşluğa çevrilir. İkinci satırda ise pack() fonksiyonu kullanılarak %HH hex çiftleri ASCII karşılıklarına çevrilir. Şimdi "post.cgi" adında yeni bir CGI hazırlayalım.
print "Content-type:text/html\n\n"; read(STDIN, $tampon, $ENV{'CONTENT_LENGTH'}); @ciftler = split(/&/, $tampon); foreach $cift (@ciftler) { ($isim, $deger) = split(/=/, $cift); $deger =~ tr/+/ /; $deger =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $FORM{$isim} = $deger; } print "<html><head><title>Form Bilgileri</title></head><body>"; print "<h2>Formla gönderilen bilgiler:</h2>\n"; foreach $anahtar (keys(%FORM)) { print "$anahtar = $FORM{$anahtar}<br>"; } print "</body></html>"; Şimdi yukarıdaki kodları açıklayalım. Form ile gönderilen bilgi önce $tampon scalar değişkenine okunuyor. Sonra & işaretlerinden ayrılarak elde edilen "formdegiskeni=deger" şeklindeki form alanı bilgileri @ciftler dizisine yerleştiriliyor. Sonra foreach döngüsünde herbir form alanı bilgisi = işaretinden ayrılıyor ve URL kodu çözülerek %FORM Hash değişkenine atanıyor. %FORM değişkenindeki anahtar adları form alanının adıdır. Mesela <input type="text" name="ad" size=30> HTML kodunda koyu yazılan "ad" değeri form alanının adıdır. Formunuzda "ad" ve "soyad" isimli iki form alanı varsa scriptinizde bu değerleri $FORM{'ad'} ve $FORM{'soyad'} şeklinde kullanabilirsiniz. Aşağıdaki örneği inceleyerek split fonksiyonunun nasıl çalıştığını hatırlayalım.
@renkler = split(/&/,$yazi); @renkler değişkeninin yeni değeri ("sari","kirmizi","yesil") olur. Şimdi de scriptimizi denemeye geldi sıra. Form için aşağıdaki kodları kullanarak bir HTML dosyası oluşturun ve "post.html" adıyla kaydedin.
<pre> Adınız: <input type="text" name="ad" size=30><br> Soyadınız: <input type="text" name="soyad" size=30><br> </pre> <input type="submit" value="Gönder"> <input type="reset" value="Tümünü Sil"> </form> İsterseniz scriptimizi biraz daha geliştirelim. Scriptimiz form bilgilerini mail adresimize göndersin. İlk önce sistemimizde sendmail programının nerede olduğunu bulalım. Bunu öğrenmek için which sendmail ya da whereis sendmail komutunu kullanabilirsiniz. (benim kullandığım serverda bu programın yeri /usr/sbin/sendmail olduğundan örneklerimizde bu şekilde kullanacağız. Eğer sizin server'ınızda farklı bir yerde ise kendi server'ınızdaki yerini yazmanız gerekir.) Not: @ işaretini çift tırnak arasında ya da print <<HTMLSonu bloğunda kullanırken önüne "silyas\@esentepe.sau.edu.tr" örneğindeki gibi \ işareti koymalısınız. Tek tırnak arasında 'silyas@esentepe.sau.edu.tr' örneğinde olduğu gibi \ işareti koymadan güvenle kullanabilirsiniz.
print "Content-type:text/html\n\n"; read(STDIN, $tampon, $ENV{'CONTENT_LENGTH'}); @ciftler = split(/&/, $tampon); foreach $cift (@ciftler) { ($isim, $deger) = split(/=/, $cift); $deger =~ tr/+/ /; $deger =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $FORM{$isim} = $deger; } $mailprog = '/usr/sbin/sendmail'; # bunu kendi mail adresinizle değiştirin $gonderilen = 'silyas@esentepe.sau.edu.tr'; # burada maili göndermek üzere sendmail programı açılıyor # eğer sendmail programı bulunamazsa hata alt programı (en altta) # işletilerek programın bulunamadığı yazıyor open (MAIL, "|$mailprog -t") or &hata("$mailprog bulunamadı!\n"); # sendmail programına mailin kime gönderileceği bildiriliyor print MAIL "To: $gonderilen\n"; # sendmail programına ziyaretçinin email adresi bildiriliyor. # bu "Yanıtla" tuşuna bastığınızda işe yarar # kullanmak zorunda değilsiniz # formunuzda 'email' ve 'isim' kutularının bulunduğu varsayılmıştır. print MAIL "Reply-to: $FORM{'email'} ($FORM{'isim'})\n"; # sendmail programına mailin konusu gönderiliyor # konudan sonra iki tane \n olduğuna dikkat edin print MAIL "Subject: Form Bilgileri\n\n"; # sendmail programına form bilgileri gönderiliyor foreach $anahtar (keys(%FORM)) { print MAIL "$anahtar = $FORM{$anahtar}\n"; } # bilgiler gönderildikten sonra sendmail programını kapatmayı unutmayın close(MAIL); # teşekkür sayfası oluşturuluyor print <<HTMLSonu; <html><head><title>Teşekkürler</title></head><body> <h2>Teşekkürler</h2> Mailiniz gönderildi. Formu gönderdiğiniz için teşekkürler<p> </body></html> HTMLSonu ; # hata alt programı sub hata { ($hatamesaji) = @_; print "<html><head><title>Hata!</title></head><body>" print "<h2>Hata</h2>\n"; print "$hatamesaji<p>\n"; print "</body></html>\n"; exit; } Yukarıdaki scriptte yeni bir yapı kullandık: hata isimli bir "alt program". Alt programlar programların sadece çağırıldıkları zaman işletilen komutlarıdır diyebiliriz. Örneğimizde hata alt programı sadece sendmail programı bulunamazsa çalıştırılır. Programınızın bu durumda size bir server hatası vermesi yerine neyin yanlış gittiğine dair bilgi vermesini istersiniz. hata alt programıyla bu yapılıyor. sendmail programının bulunmadığını bildiren bir web sayfası gösteriyor ve Perl'den çıkıyor. Perl'de alt programlar &altprogramadi ya da &atlprogramadi (argümanlar) şeklinde çağrılır. Argümanlar alt programa gönderilen değerlerdir. Şimdi aşağıdaki kodlarla bir form oluşturun ve scripti deneyin.
<pre> Adınız: <input type="text" name="isim" size=30> E-mail adresiniz: <input type="text" name="email" size=30> Web sayfanız: <input type="text" name="web_sayfasi" size=30> Yaşınız: <input type="text" name="yas" size=3> </pre> <input type="submit" value="Gönder"> <input type="reset" value="Tümünü Sil"> </form> Eğer herşey yolunda giderse birkaç dakika sonra form bilgileri e-mail adresine gelecektir. Eğer form bilgilerini birkaç adrese birden göndermek istiyorsanız adresleri aşağıdaki gibi aralarına virgül koyarak yazabilirsiniz.
Bölüm 5: İleri Seviye FormlarBir önceki bölümde form bilgilerinin kodlarının nasıl çözülecegini ve mail olarak gönderileceğini gördük. Fakat yazdığımız scriptte bir eksiklik vardı: Hata kontrolü. Eğer boş formlar almak istemiyorsanız ya da belli alanların mutlaka doldurulmasını istiyorsanız, hatta bir anket yapıyor ve verilen cevaba göre scriptinizin farklı işler yapmasını istiyorsanız şimdi yazacaklarımı dikkatlice okuyun. Belli bir şartın doğru olup olmadığını kontrol etmek için if blokunu kullanırız.
# koşul doğruysa işletilecek komutlar } elsif ($degiskenadi eq "baskaseyler") { # bu koşul doğruysa işletilecek komutlar } else { # yukarıdaki koşulların hiçbiri doğru değilse işletilecek komutlar } elsif ve else bloklarının konulması şart değildir. Sadece tek bir şartın doğruluğunu kontrol edecekseniz şu şekilde kullanabilirsiniz:
# $sayi 23'ten büyükse işletilecek komutlar } Perl'de değişkenin sayı ya da yazı oluşuna göre değişik karşılaştırma operatörleri vardır.
Farkettiğiniz gibi, yazıların karşılaştırılmasında karakter operatörler (eq, ne, vs.), sayıların karşılaştırılmasında işaret operatörler (==, !=, vs.) kullanılır. Şimdi "mail.cgi" isimli scriptimizi açıp sendmail programını açan satırın (open (MAIL, "|$mailprog -t") or &hata("$mailprog bulunamadı!\n");) hemen öncesine şu kodları yerleştirin ve scripti "mail2.cgi" adıyla kaydedin.
&hata("Lütfen isminizi yazın"); } Hata mesajının yazdırılmasında hata alt programından faydalanılıyor. Scriptimize bu kodu eklemekle formunuzdaki isim alanının doldurulmasını zorunlu kılmış olduk. Aşağıdaki gibi birden fazla alanı da kontrol edebilirdik.
&hata("Lütfen isminizi, e-mail adresinizi ve yaşınızı yazın"); } Yukarıdaki kod "isim", "email" ya da "yas" isimli alanların herhangi biri boş bırakıldığı takdirde hata mesajının yazdırılmasını sağlayacaktır. Koşullar or operatörü ile ayrılmışlardır. (or yerine || da kullanılabilir.) Onay KutularıFormdaki onay kutularının nasıl yazdırıldığını bir örnekle açıklayalım. İlk önce aşağıdaki kodlarla bir sayfa oluşturun ve "renk.html" adıyla kaydedin.
<form action="http://hammer.prohosting.com/~sinan/cgi-bin/ornek/renk.cgi" method="POST"> <h3>Sevdiğiniz renkleri işaretleyin</h3> <input type="checkbox" name="kirmizi" value=1> Kırmızı<br> <input type="checkbox" name="sari" value=1> Sarı<br> <input type="checkbox" name="yesil" value=1> Yeşil<br> <input type="checkbox" name="mavi" value=1> Mavi<p> <input type="submit" value="Gönder"> </form> </body></html> Burada value sıfatına istediğiniz değeri verebilirsiniz. Yukarıda CGI programında daha kısa kod yazabilmek için "1" değeri verilmiştir. Şimdi de bu formun kodunu çözecek CGI programını yazalım.
print "Content-type:text/html\n\n"; read(STDIN, $tampon, $ENV{'CONTENT_LENGTH'}); @ciftler = split(/&/, $tampon); foreach $cift (@ciftler) { ($isim, $deger) = split(/=/, $cift); $deger =~ tr/+/ /; $deger =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $FORM{$isim} = $deger; } print "<html><head><title>Sonuçlar</title></head>\n"; print "<body>\n"; print "<h2>Sonuçlar</h2>\n"; @renkler = ("kirmizi","sari","yesil","mavi"); foreach $renk (@renkler) { if ($FORM{$renk} == 1) { print "$renk rengini işaretlediniz<br>\n"; } } print "</body></html>\n"; Radyo DüğmeleriRadyo düğmeleri onay kutularından biraz farklıdır. Form hazırlarken radyo düğmelerinin hepsinin name sıfatına aynı değer atandığı için yazdırılması daha kolaydır. Bir örnek vererek bunu açıklayalım.Aşağıdaki kodlarla bir sayfa hazırlayın ve "renk2.html" adıyla kaydedin.
<title>En Sevdiğiniz Renk</title> </head> <body> <form action="http://hammer.prohosting.com/~sinan/cgi-bin/ornek/renk2.cgi" method="POST"> <h3>İçlerinde en sevdiğiniz renk hangisi?</h3> <input type="radio" name="renk" value="kirmizi"> Kırmızı<br> <input type="radio" name="renk" value="sari"> Sarı<br> <input type="radio" name="renk" value="yesil"> Yeşil<br> <input type="radio" name="renk" value="mavi"> Mavi<p> <input type="submit" value="Gönder"> </form> </body> </html> Şimdi de aşağıdaki kodları yazın ve "renk2.cgi" adıyla kaydedin. ("renk.cgi"den tek farkının foreach döngüsünün yerine konan print "En sevdiğiniz renk: $FORM{'renk'}\n"; satırı olduğuna dikkat edin.)
print "Content-type:text/html\n\n"; read(STDIN, $tampon, $ENV{'CONTENT_LENGTH'}); @ciftler = split(/&/, $tampon); foreach $cift (@ciftler) { ($isim, $deger) = split(/=/, $cift); $deger =~ tr/+/ /; $deger =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $FORM{$isim} = $deger; } print "<html><head><title>Sonuçlar</title></head>\n"; print "<body>\n"; print "<h2>Sonuçlar</h2>\n"; print "En sevdiğiniz renk: $FORM{'renk'}\n"; print "</body></html>\n"; Scriptimizi bir adım daha geliştirerek ziyaretçiye sadece seçtiği rengi söylemekle kalmayıp aynı zamanda fon rengini seçilen renk yapacak şekilde değiştirelim.
print "Content-type:text/html\n\n"; read(STDIN, $tampon, $ENV{'CONTENT_LENGTH'}); @ciftler = split(/&/, $tampon); foreach $cift (@ciftler) { ($isim, $deger) = split(/=/, $cift); $deger =~ tr/+/ /; $deger =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $FORM{$isim} = $deger; } %renkler = ("kirmizi" => "red", "sari" => "yellow", "yesil" => "green", "mavi" => "blue"); print "<html><head><title>En Sevdiğiniz Renk</title></head>\n"; print "<body bgcolor=$renkler{$FORM{'renk'}}>\n"; print "<h2>En sevdiğiniz renk: $FORM{'renk'}</h2><br>\n"; print "</body></html>"; Seçim KutularıSeçim kutularının kodunun çözülmesi hemen hemen radyo butonları gibidir. Yine konunun daha iyi anlaşılması bakımından bir örnek verelim.Aşağıdaki kod ile formu oluşturun ve sayfayı "renk3.html" adıyla kaydedin.
<select name="renk"> <option value="kirmizi"> Kırmızı <option value="sari"> Sarı <option value="yesil"> Yeşil <option value="mavi"> Mavi </select><p> <input type="submit" value="Gönder"> </form> Seçim kutularının değerlendirilmesi radyo botonları ile aynı olduğundan yeni bir script yazmamıza gerek yok. Formumuzu "renk2a.cgi" scriptine gönderebiliriz. Şu ana kadar öğrendiğimiz bilgilerle onay kutuları, radyo düğmeleri ve seçim kutuları içeren form bilgilerini web sayfasına yazan bir CGI scripti hazırlayabiliriz. O zaman ne duruyoruz? :) Hemen işe koyulalım. Aşağıdaki kodlarla yeni bir HTML dosyası oluşturun ve "form.html" adıyla kaydedin.
<body> <form action="http://hammer.prohosting.com/~sinan/cgi-bin/ornek/form.cgi" method="POST"> İsminiz: <input type="text" name="isim" size=30><p> E-mail adresiniz: <input type="text" name="email" size=30><p> Bu siteye nasıl ulaştınız? <select name="nasilulasti"> <option value=0 selected>Seçim yapın... <option value=1>Direk adresini yazdım <option value=2>Siteyi bookmark etmiştim <option value=3>Arama motorundan buldum <option value=4>Başka bir siteden <option value=5>Adresi bir kitaptan aldım <option value=6>Diğer </select><p> Siteye 5 üzerinden kaç verirsiniz?<br> <input type="radio" name="puan" value=1> 1 <input type="radio" name="puan" value=2> 2 <input type="radio" name="puan" value=3> 3 <input type="radio" name="puan" value=4> 4 <input type="radio" name="puan" value=5> 5<p> Aşağıdakilerden hangileriyle ilgilenirsiniz?<br> <input type="checkbox" name="wds" value=1> Web Design<br> <input type="checkbox" name="wsy" value=1> Web Server Yöneticiliği<br> <input type="checkbox" name="tic" value=1> Elektronik Ticaret<br> <input type="checkbox" name="als" value=1> İnternetten Alışveriş<br> <input type="checkbox" name="egt" value=1> İnternet Aracılığıyla Eğitim<br> <p> Sayfa hakkında yorumlarınız:<br> <textarea name="yorum" rows=5 cols=70 wrap="virtual"> </textarea> <p> <input type="submit" value="Gönder"> <input type="reset" value="Tümünü Sil"> </form> </body></html> Şimdi de "form.cgi" programını yazalım.
print "Content-type:text/html\n\n"; read(STDIN, $tampon, $ENV{'CONTENT_LENGTH'}); @ciftler = split(/&/, $tampon); foreach $cift (@ciftler) { ($isim, $deger) = split(/=/, $cift); $deger =~ tr/+/ /; $deger =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $FORM{$isim} = $deger; } # "Bu siteye nasıl ulaştınız?" sorusunun cevabı # numara olarak gönderildiği için bunu çevirebilmek # için bir hash değişkene ihtiyacımız var %nasilulasti = ( 0 => "", 1 => "Direk adresini yazdım", 2 => "Siteyi bookmark etmiştim", 3 => "Arama motorundan buldum", 4 => "Başka bir siteden", 5 => "Adresi bir kitaptan aldım", 6 => "Diğer" ); print <<HTMLBas; <html><head><title>Sonuçlar</title></head> <body> <h2>Sonuçlar</h2> Formla gönderdiğiniz bilgiler aşağıdaki şekildedir:<p> İsminiz: $FORM{'isim'}<p> E-mail adresiniz: $FORM{'email'}<p> Siteye nasıl ulaştığınız: $nasilulasti{$FORM{'nasilulasti'}}<p> Siteye verdiğiniz puan: $FORM{'puan'}<p> HTMLBas ; %secim = ("wds" => "Web Design", "wsy" => "Web Server Yöneticiliği", "tic" => "Elektronik Ticaret", "als" => "İnternetten Alışveriş", "egt" => "İnternet Aracılığıyla Eğitim" ); print "Aşağıdaki konularla ilgileniyorsunuz:<br>\n"; foreach $anahtar (keys %secim) { if ($FORM{$anahtar} == 1) { print "$secim{$anahtar}<br>\n"; } } print <<HTMLSon; <p> Sayfa hakkında yorumlarınız:<br> $FORM{'yorum'} <p> </body></html> HTMLSon ; |
![]() |
![]() |
![]() |