Adım adım bir PHP guestbook yazalım.
Bu yazımızda PHP ile ilk uygulamalarını geliştiren kişileri hedef kitlesi seçtik. Pek çok yerde yer alan MySQL' e giriş, PHP' ye giriş gibi dokümanları referans almış ziyaretçilerimizin en sık karşılaştığı, "peki bütün bunları bir araya nasıl koyacağız?" sorusunun cevabı olmayı amaçlayan yazımızdaki adımları teker teker izlediğiniz vakit mükemmel olmasa da geliştirmeye oldukça açık bir guestbook(misafir defteri) uygulamasına sahip olacaksınız.



Gereksinimler



Bu yazıda yer alan örnekleri uygulamak için :


  • MySQL sunucusu

  • PHP ve Apache gibi bir web sunucu

  • MySQL üzerinde veritabanı yaratabilme ve kullanıcı tanımlayabilme hakları

  • Herhangi bir metin editörü. (Örnek : glimmer, notepad, wordpad, gedit, kedit, phped)


gereklidir. Eğer yukarıdaki kavramlar size yabancı geliyorsa Yeni başlayanlar için MySQL ve PHP öğrenmek istiyorum, nasıl başlarım? başlıklı dokümanlarımıza bakınız.



Yazılımın tasarlanması aşaması


İyi bir yazılım geliştirme süreci uzun, tasarım, araştırma süreçlerini içerir. Süreç çok basit olarak, projenin küçük parçalara ayrılması, gereksinimlerin belirlenmesi, modüllerin teker teker hazırlanması, kodun yazılması, kodun test edilmesi, uygulamanın kullanıma açılması olarak özetlenebilir. Biz de uygulamamız çok basit olmasına rağmen, benzer bir yol izleyeceğiz.





Projenin küçük parçalara ayrılması :



Projemiz tabanda bir veritabanı, üzerinde de PHP scriptlerinden oluşacak. Bu bir guestbook uygulaması olduğu için iki adet temel fonksiyonu olması beklenir. Birincisi, siteye giren kullanıcının yeni metin girebildiği bir ekran, ki burada ziyaretçiden isim, e-mail, homepage ve yorum metinlerini girmesini bekleyeceğiz. İkinci script ise hali hazırda girilmiş olan yorumların hepsini alt alta listeleyen bir yapıda olacaktır. Bu yazıda temel amacımız PHP, HTML ve MySQL birleşiminden nasıl yararlanabiliriz sorusunun cevabını aramak olduğu için, site yönetimi, yorumları sayfalara bölmek gibi kodu yoğunlaştırıcı detaylara girilmeyecektir.



Gereksinimlerin belirlenmesi :


Projemiz son derece basit ve detayları açık olduğu için, çok da fazla gereksinimimiz yok aslında. İlk olarak bir MySQL veritabanı şeması hazırlayıp, ardından MySQL sisteminde veritabanımızı yaratacağız. Ardından da kodu yazmaya başlayıp, Apache sunucumuzda yazılımımızı test edeceğiz.



Modüllerin teker teker hazırlanması



Veritabanı şemasının hazırlanması... Veritabanı hazırlamada uzmanlık zaman içinde, uygulama yazdıkça gelişen bir yetenektir. Uygulamamızın bilgi girilen alanları genelde veritabanında bir alana karşılık gelmelidir. Eğer istersek kullanıcının IP adresi, kullandığı browser, mesajı gönderdiği tarih zaman vb... detayları da saklayabiliriz. Her bir bilgi girilen alan için veritabanımızdaki tabloda bir sütun ayrırdığımızı düşünürsek aşağıdaki veritabanı şeması ortaya çıkar.



mysql-db.sql dosyası


CREATE DATABASE guestbook;
CREATE TABLE yorumlar (
mesaj_id int(10) unsigned NOT NULL auto_increment,
isim_soyisim varchar(100),
email varchar(75),
homepage varchar(100),
yorum blob,
PRIMARY KEY (mesaj_id),
UNIQUE mesaj_id (mesaj_id),
KEY mesaj_id_2 (mesaj_id)
);





yukarıdaki metni mysql-db.sql adlı bir dosyaya kaydettikten sonra sırası ile bu komutları işletip veritabanımızı yaratmamız gereklidir. Bunun için aşağıdaki komutu çalıştırmanız yeterli olacaktır.




umut@orion:~$ mysql -u root -p < mysql-db.sql


"-p" parametresi eğer root kullanıcısının şifresi varsa size şifreyi sormasını sağlayacaktır. Eğer şifresi yoksa da bir an önce koymalısınız.





Ardından yarattığımız veritabanını kullanması için yeni bir kullanıcı tanımlıyor ve ona bir şifre atıyoruz. Bu işlemleri yapmak için aşağıdaki adımları izlemeniz yeterlidir.




umut@orion:~$ mysql -u root -p guestbook
Enter password:
....
mysql> grant usage on guestbook.* to hebelek@localhost;
Query OK, 0 rows affected (0.01 sec)

mysql> grant select, insert, delete, update on guestbook.* to hebelek@localhost;
Query OK, 0 rows affected (0.00 sec)

mysql> exit;
umut@orion:~$ su -c "mysqladmin -u hebelek password BEN_BIR_SIFREYIM"


Yukaridaki komutta sorulan şifrede Linux sisteminizin root kullanıcısının şifresini girmeniz istenmektedir.



guestbook giriş sayfasının hazırlanması Bu bir guestbook olduğu için tabiatı gereği web sayfanız içerisinde bir yerlerden buraya basit bir link gereklidir. Biz de basit ama işini gören bir giriş sayfası hazırlıyoruz.




<b><i>index.html</i></b><br>

<html><head><title>GuestBook</title></head>
<body>
<h2>Guestbook Uygulaması</h2><p>
<a href="yorumekle.html">Yeni yorum ekle</a><br>
<a href="yorumoku.php">Yorumları oku</a><br>
</body>
</html>




Ziyaretçinin yeni yorum eklediği sayfanın hazırlanması : Dikkat ettiyseniz, sayfanın hazırlanması diyoruz. Çünkü bu sayfa aslında standart bir HTML web sayfası. İçerisinde bir adet form mevcut ve formda da metin girdi alanı olarak isim-soyisim, e-mail adresi, homepage adresi ve çok satırlı metin girdisi olarak da yorum alanları mevcut. Aşağıdaki basit HTML kodu bu gereksinimi karşılayacaktır.



yorumekle.html




<html><head><title>GuestBook</title></head>
<body>
<form action="yorumekle_islem.php">
İsminiz & Soyisminiz: <input type="text" name="isim"><br>
E-mail Adresiniz : <input type="text" name="email"><br>
Homepage adresiniz : <input type="text" name="homepage"><br>
<textarea name="yorum" rows="5" cols="50">yorumunuz....</textarea>
<input type="submit" name="Kaydet">
</form>
</body>
</html>



Yukarıdaki HTML kodunun uzantısının php veya html olması çok büyük bir fark yapmaz, ama yine de nanosaniyelik bir kazanç dahi olsa uzantıyı html yapmak daha mantıklıdır, çünkü kodun içinde hiç PHP kodu gereksinimiz olmadı.



Yorum eklemek için gerekli formu hazırladığımıza göre artık bu formun arka planında çalışacak ve veritabanı ile iletişim kurup gerekli sütunları dolduracak PHP kodunu yazmaya sıra geldi. Korkmayın... Happy bu işlem sandığınızdan çok daha kolay.



Şart olmamakla birlikte PHP programcıları genellikle veritabanına bağlantı için kullandıkları şifre, kullanıcı adı gibi bilgileri farklı bir dosya içerisinde saklamayı tercih ederler. Bunun pek çok mantıklı nedeni vardır. Kısaca, veritabanına bağlantı bilgileri başka bir sunucuya kod taşıma gibi nedenlerle değiştiğinde bütün kodu değiştirmek yerine tek bir dosya üzerinde oynama yapmak ve sadece bu dosyanın güvenliğini sağlayarak bütün kodun güvenliğinin sağlanması olarak özetlenebilir. Biz bu dosyamıza db-inc.php adını vereceğiz. Diğer PHP dosyalarımızda da bu dosyayı include ederek kullanacağız.





db-inc.php


<?
$database_host = "localhost";
$database_user = "hebelek";
$database_user_pass = "BEN_BIR_SIFREYIM";
$database_name = "guestbook";

$myConn = mysql_pconnect($database_host, $database_user, $database_user_pass)
or die("<div align='center'> <p>
<font color='red'>veritabanına bağlanılamadı</font> <p></div>");
mysql_select_db($database_name, $myConn);
?>




yorumekle_islem.php


<?
include("db-inc.php");
$result = mysql_query("insert into yorumlar
values(NULL,'$isim','$email','$homepage','$yorum')");
echo "Kaydınız başarı ile alınmıştır, teşekkür ederiz<p>";
echo "Yorumları okumak için <a href="yorumoku.php"> buraya </a> tıklayınız.<p>";
?>



İster inanın ister inanmayın yukarıdaki kod, formda girilmiş olan metnin veritabanına kaydedilmesi için yeterlidir. veritabanına bağlantı sağlamak için db-inc.php dosyasındaki satırlar kullanmış, ardından da mysql_query ile SQL sorgusu sayesinde bilgi veritabanına kaydedilmiştir. Kullanılan NULL değerinin karşılığı olan mesaj_id veritabanında auto_increment olduğu için otomatik olarak ID numarasının bir artırılmasını sağlamaktadır. Bu iş bu kadar basit....





Yorum Okuma Sayfası Hazırlanması : Bu yine bir PHP scripti olacak ve içeriği MySQL veritabanından okutularak HTML şablon içerisinde çıktı verilecek. Aşağıdaki kodu inceleyiniz.



yorumoku.php


<html><head><title>GuestBook</title></head>
<body>
<?
include("db-inc.php");
$result = mysql_query("select * from mesajlar yorumlar by mesaj_id desc");
if (mysql_num_rows($result) > 0) {
if($result) {
while ($r = mysql_fetch_array($result)) {
$isim = $r["isim_soyisim"];
$email = $r["email"];
$homepage = $r["homepage"];
$yorum = $r["yorum"];

echo "<hr size=1>";
echo "<b>İsim - Soyisim : </b>" . $isim . "<br>";
echo "<b>E-mail : </b>" . $email . "<br>";
echo "<b>Homepage : </b>" . $homepage . "<br> <br>";
echo nl2br(htmlspecialchars($yorum));
}
}
}
?>
<hr size=1><p>
<a href="index.html">Giriş Sayfası </a>
</body>
</html>
<p>

Şimdi yukarıdaki kodu açıklamaya çalışalım.





İlk <? işaretine kadar olan kısım standart HTML kodu ile sayfanın giriş, başlık vb... kısımlarını hazırlamak için kullanıldı.


include yazan satırda veritabanına bağlantı için dosya çağırıldı. Bu dosyada bir adet persistent bağlantı açılmış halde bize hazır sunuluyor.


Ardından SQL komutumuzu gönderdik ve if ile acaba 0 dan fazla bir sonuç gönderdi mi diye baktık. Eğer birden fazla ise ve bir sonuç var ise her bir sonuç satırını işlemeye başladık. while statement içerisinde satırın içeriği okunup bir arraye atılma işlemi yapılmaktadır. Ardından bu array içeriği ilgili değişkenlere konulup gerekli işlem yapılmıştır.



İlgi çekici satırlardan birisi echo nl2br(htmlspecialchars($yorum)); olabilir. Burada $yorum değişkeninin içeriğinde olması muhtemel HTML kodunun otomatik olarak çıktı alınabiilr hale getirilmesi sağlanıyor. Örneğin < (küçüktür işareti) bu komutun sonucunda &lt; şekline dönüştürülür. nl2br ise yorum eklerken ziyaretçinin girmiş olması muhtemel ENTER karakterlerinin de işlem görmesini sağlayacaktır.



Programın test edilmesi ve çalıştırılması



Bu dokümanda verilmiş olan bütün kodlar test edilmiş ve çalıştırılmıştır. Siz de birebir copy & paste yöntemi ile makinanızda bu dosyaları kaydettikten sonra web browserınız ile uygulamayı çalıştırabilirsiniz. Eğer Apache kullanıyor ve dosyaları nereye yerleştireceğinizi bilmiyorsanız, Apache' nin kurulu olduğu dizinin altındaki htdocs dizinini deneyiniz. Hatta daha da güzeli bu dizinin altına guestbook adında bir dizin yaratıp browserınızda adres olarak http://localhost/guestbook yazınız.



Makinenizde Apache nerede kurulu bilmiyorsanız, /home/httpd, /var/www dizinlerine bakmanızı öneririm.



Kolay Gelsin...



Bu yazı http://www.php.org.tr adresinde yayınlanmıştır.

Gelin beraber bir webmail yazalım
Web tabanlı e-mail sistemleri son yıllarda oldukça popüler olmuştur. Webmail sistemler bir Internet Cafe' den veya arkadaşınızın bilgisayarından posta kutunuza erişim sağlamak için güvenli, zahmetsiz ve hızlı bir çözümdür. Bu yazımızda aynen Hotmail gibi ama tabii ki çok daha basit, ilkel bir webmail programının nasıl hazırlanabileceğini, daha sonra hangi adımları takip etmemiz gerektiğini inceleyeceğiz.



Bir webmail programı en azından 5 bileşenden oluşur.


  • Kullanıcının gerçekten kim olduğunu anlamamıza yarayan kullanıcı adı ve şifrenin alındığı ve onaylandığı bölüm. Buradan alınan şifre ve kullanıcı adı normal şartlarda kullanıcının pop3 veya imap şifresi olmalıdır.

  • e-mailların IMAP veya POP3 sunucudan alınması.

  • Posta kutusu(folder) yönetimi. Kullanıcının e-maillarını hazırda varolan dizinlerde saklayabilmesi veya yeni dizinler yaratabilmesi, modifiye edebilmesi.

  • Yeni e-mail yaratma ve gönderme modülü.

  • Attachment(Eklenti) yönetimi.



Bir webmail programının temel işlevini yerine getirmesi için en basitinden e-mailları sunucudan çekip, gösterebilmesi ve yeni mail atabilmesi yeterlidir. Bu yazımızda da güvenlik, eklentiler, dizin vb... ayrıntılara girmeden mesajlarımızı sunucu üzerinden okuyabilmemiz için gerekli bir arayüz hazırlamak temel amacımızdır.



PHP' nin hazırlanması gerekli modüllerin kontrol edilmesi.

PHP ile birlikte bir sunucudaki imap veya pop3 sunucuya bağlanıp üzerinde işlem yapabilmek için hazır fonksiyonlar gelmektedir. PHP manualinde IMAP functions başlığı altındaki fonksiyonları kullanmak için PHP' nin --with-imap desteği ile derlenmiş olması gereklidir. Değişik durumlara göre gereksinimler şöyle özetlenebilir.


  • Kaynak koddan derleyen kişiler : ilk olarak c-client paketini indirip kurmalıdırlar. Kurulum biraz zahmetlidir. Ayrıntılı kurulum bilgilerine paketle birlikte gelen dokümanlardan ulaşabilirsiniz. Doğru kurulum yapılmadığı takdirde PHP, --with-imap parametresi ile derlenmede sorun çıkaracaktır.

  • Red Hat tabanlı Linux kullanıcıları : sadece php-imap paketini kurarak ve php.ini dosyalarında "extension=imap.so" yazan yerin başındaki ; (noktalı virgül) ü kaldırarak kurulumu tamamalayabilirler.

  • Debian GNU/Linux kullanıcıları : "apt-get install php-imap" komutunu vererek gerekli işlemleri tamamlayabilirler.

  • Windows kullanıcıları : makinelerinde php_imap.dll dosyasının olduğundan emin olduktan sonra php.ini dosyasında
    ";extension=php_imap.dll" yazan satırın başındaki ; (noktalı virgül) işaretin kaldırarak kurulumu tamamlarlar. Bu dosya mevcut değilse netten bulabilirsiniz.


PHP' ye IMAP fonksiyonlarının yüklü olup olmadığını bir php scriptine sadece aşağıdaki kodu yazarak test edebilirsiniz.




<?php
phpinfo();
?>


Bu php scriptinin çıktısında imap yazan tabloyu arayınız. Tablo mevcutsa kurulum tamamlanmıştır.



Kullanıcının login olması ve gerekli bilgilerinin alınması

Bu iş için hazırladığımız script kullanıcıdan username ve password bilgisini alacaktır. Ardından girilen bilgiler doğru mu kontrol edilecek, doğru ise sunucu üzerindeki mailları listelenmek üzere INBOX' a yönlendiriliecektir. Kullanıcı bilgilerini almak için PHP authentication kullanıyoruz.




login.php dosyası


<?
error_reporting(32);
if (!$PHP_AUTH_USER) {
Header("WWW-authenticate: basic realm="MAIL KONTROL"");
Header("HTTP/1.0 401 Unauthorized");
} else {
Header("Location:inbox.php");
}
?>


Yukarıdaki basit scriptte kullanıcıdan gerekli bilgileri alıp inbox.php scriptine yani sunucudaki mailların listelendiği scripte yönlendirme yapıyoruz.



webmail programı kimi kullanıcıların sandığının aksine hiç bir şekilde ana sunucudaki mailları başka bir makineye çekmez. inbox listelendiği vakit dahi, sadece ana makinedeki mailların başlık bilgileri istenir ve bunlar çoğu zaman bir array' de bekletilir veya direk print out olarak ekrana yazdırılır. Biz ilk olarak headers adlı bir arrayde mesaj başlıklarını toplayıp ardından ekrana yazdıracağız.



inbox.php


<?
error_reporting(32);
$SUNUCU = "{operamail.com/pop3}";
$link= imap_open($SUNUCU, $PHP_AUTH_USER, $PHP_AUTH_PW);
$headers = imap_headers($link);
echo "<h1>INBOX</h1><br>";
echo "<b>Posta kutunuzda " . count($headers) . " mesaj var.</b><p>";

for ($x = 1; $x <= count($headers) ; $x++) {
$idx = ($x -1);
echo "<a href="mesajoku.php?num=$x">$headers[$idx]</a><br>";
}
?>


inbox.php scripti ilk olarak sunucuya bir pop3 bağlantısı yaratır. Dikkat ettiyseniz pop3 bağlatısı diyorum ama pop3 olarak bağlanıyorum. PHP, imap ve pop3 arasındaki benzerliklere dikkat çekerek ikisini birbirinden ayırmamıştır. yukarıdaki kodun $SUNUCU = ... yazan kısmındaki pop3' ü imap olarak değiştirirseniz sunucudaki 110 nolu pop3 portu yerine 143 nolu imap portundan iletişim sağlarsınız hepsi bu kadar. IMAP ile pop3 arasındaki asıl farklılık dizin yönetiminde karşımıza çıkacaktır ki bu konu yazımızın amacını oldukça aşar.



imap_headers() fonksiyonu açık olan pop3 bağlantısından girilmiş olan kullanıcı adı ve şifreye ait kullanıcının mesajlarının başlıklarını otomatik olarak alan bir fonksiyondur. Çıktısı bir arraydir ve biz de bu array' i headers adlı değişkene atıyoruz. Ardından da bir for döngüsü içerisinde arrayin içeriğini teker teker ekrana yazdırıyor ve mesajoku.php' ye bir link yaratıyoruz.



Kullanıcı inbox.php' den bir mesaja tıkladığında artık o mesajı okumak istediğini belirtmiştir. Bizim yapmamız gereken bu mesajın artık tamamını sunucudan çekerek kullanıcıya okuması amaçlı sunmaktır. En temel bilgiler olan header(başlık) bilgileri yani Subject, From, To, Date gibi bilgileri de yine PHP' nin bize sunduğu olanaklardan faydalanarak elde edeceğiz. Olanak derken, PHP' nin imap_header() fonksiyonundan bahsediyoruz.



mesajoku.php


<?
error_reporting(32);
$SUNUCU = "{operamail.com/pop3}";
$link = imap_open($SUNUCU, $PHP_AUTH_USER, $PHP_AUTH_PW);
$header = imap_header($link,$num);

echo "Kimden : " . $header->fromaddress . "<br>";
echo "Kime : " . $header->toaddress . "<br>";
echo "Tarih : " . $header->Date . "<br>";
echo "Baslik : " . $header->Subject . "<p><hr><p>";
echo nl2br(imap_body($link,$num));

echo "<p><a href="inbox.php"> INBOX</a>";
?>


Yukarıdaki kısa script gerçekten de sunucudan e-mailın çekilmesi, başlık bilgilerinin gösterilmesi ve mesajın okunması için yeterli işlevi yerine getirebilmektedir. Yine ilk satırlarda gerekli pop3 bağlantısını yaratıyoruz ve ardından da imap_header fonksiyonu yardımıyla mesajın başlık bilgilerini $header adlı bir array içerisine atıyoruz. hangi mesajın sunucudan çekileceğini ise $num adlı değişkenden elde ediyoruz. Bu değişken inbox.php' den bize bir URL referans değişkeni olarak gönderilmişti.



echo ile bağlayan satırlar kendi kendisini açıklar derecede basit ve anlaşılırdır. Burada dikkat çekilmesi gereken nokta ise imap_body fonksiyonudur. Bu fonksiyon mesajın başlık bilgisinin haricinde mesajın body kısmını oluşturan metni geri döndürür ve çıktısı string' dir. Bunu hiç bir değişkene atamadan direk ekrana yazdırarak webmail programımızın en temel işlevlerini tamamlamış oluyoruz.



Yukarıdaki kodları bir araya koyarak bir yazılım ortaya çıkardığınızda ve gündelik hayatınızda kullanmaya başladığınızda bazen garip karakterlerle dolu ve okunması pek mümkün görünmeyen mesajlar alacaksınız. Bu tür mesajlar MIME mesajlardır ve okunması için ekstra işlemlerden geçirilmesi gereklidir. Eğer kendiniz test etmek istiyorsanız sunucu makinedeki hesabınıza bir attachmentlı e-mail gönderin ve attachment' ın nasıl göründüğüne bir bakın. Bu tür mailların okunması işlemi yukarıda yazılanlardan çok daha kompleks işlemlerdir.



Yazılımı geliştirmek isteyen kullanıcılar, ilk olarak MIME hakkında ayrıntılı bigiye sahip olmalı, ardından PHP' nin imap fonksiyonlarını manual' dan incelemelidir. IMAP ve pop3' ün standartları hakkında bilgi sahibi olduktan sonra imap üzeirnde folder kavramlarına yönelmelidirler. Son olarak da MIME mesaj göndermeyi tamamladığınızda Hotmail benzeri bir yazılım üretmemeniz için hiç bir sebep yoktur.



Yazılımı üretirken Postaci Webmail, BasiliX gibi Türk üretimi webmail paketlerin kodlarının incelenmesini öneriyorum.



Bu yazı http://www.php.org.tr adresinde yayınlanmıştır.