NuSOAP ile Kolayca Web Servis Sunucu ve İstemcileri Kodlamak

Web hizmeti genel olarak “ağ üzerinden erişilebilen ve istenen hizmeti sunan makinede çalıştırılan bir API” olarak tanımlanabilir.

Web hizmetlerini kabaca ikiye ayırmak olası:

  1. Simple Object Access Protocol (SOAP) kullanan geleneksel yöntem.
  2. REpresentational State Transfer (REST) kullanan görece yeni yöntem.

RESTful web hizmetlerini başka bir yazıya bırakarak, bu yazıda SOAP kullanarak basit birer web hizmet sunucusu ve istemcisi geliştirmeyi inceleyeceğiz. Yapacağımız iş, sunucuya e-posta adresi gönderip, sunucudan o e-posta adresiyle kayıtlı kullanıcıyı almaktan ibaret.

SOAP bir çok PHP prorgramcısının “öcü” gibi gördüğü bir protokol. Öyle ki, pek çok deneyimli ve gözüpek programcının bile “SOAP” adını duyunca irkildiklerine, hatta iş uygulamaya geldiğinde bazı durumlarda düpedüz “beceremediklerine” çok tanık oldum. Gerçekten de, bazı gereksiz işletim sistemleri üstünde çalışan bazı web hizmetlerinden GNU/Linux – PHP ikilisiyle hizmet almak, WSDL dosyalarını düzgün oluşturmak her zaman o kadar kolay olmayabiliyor.

Ancak tüm bu dertler sizin için bu yazıyı okuduktan sonra geçmişte kalmış olacak, sayın okur!

Öncelikle buradan NuSOAP kütüphanesini indiriyoruz. NuSOAP, bizim için WSDL oluşturma dahil hemen her işi halledecek.

İndirdiğimiz zip dosyasından iki klasör çıkıyor: lib ve samples. Bizim samples’a ihtiyacımız olmayacak, ancak örnekleri incelemenizde fayda var. Basit uygulamamız için webrootumuz altına yeni bir dizin oluşturup (örneğin Ubuntu ile “/var/www/soapTest”) lib’i bu dizine kopyalıyoruz.

/var/www/soapTest dizini altında üç dosya oluşturacağız:

  1. config.php : ayar dosyası
  2. service.php: SOAP sunucusu
  3. client.php: SOAP istemcisi

Ayrıca uygulamamız büsbütün yavan olmasın diye bir de veri çekeceğimiz MySQL veritabanı bağlantımız olacak. Benim veritabanımın adı “yazboz” ve bu veritabanında “users” isimli örnek basit bir tablom var.

Yapı ve tek satırlık kullanıcı verisi şöyle:

1
2
3
4
5
6
7
8
9
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`email` varchar(100) COLLATE utf8_turkish_ci NOT NULL,
`name` varchar(100) COLLATE utf8_turkish_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_turkish_ci AUTO_INCREMENT=2 ;

INSERT INTO `users` (`id`, `email`, `name`) VALUES
(1, 'test@mailinator.com', 'Georges Moustaki');

Yukarıdaki kodu konsol ya da phpMyAdmin marifetiyle veritabanımıza aktardıktan sonra ayar dosyamızı oluşturalım ve “config.php” ismiyle kaydedelim:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

class Config
{
    public $wwwroot , $host , $db , $username , $password;
   
    public function __construct()
    {
        //URL
        $this->wwwroot = 'http://localhost/nusoap';
       
        //MySQL sunucusu
        $this->host = 'localhost';
       
        //veritabanı
        $this->db = 'yazboz';
       
        //MySQL kullanıcı adı
        $this->username = 'root';
       
        //MySQL şifresi
        $this->password = 'sifre';
    }
}

Yeni bir dosya daha oluşturalım ve “service.php” adı ile config.php ile aynı dizine kaydedelim.
Sonra, yeni service.php dosyamızda config sınıfını çağırıp veritabanı bağlantısını yapalım:

1
2
3
4
5
6
<?php

require 'config.php';
$config = new Config();

$conn = new mysqli($config->host , $config->username , $config->password , $config->db);

Artık e-posta adresinden kullanıcı adını döndüren fonksiyonu yazabiliriz:

1
2
3
4
5
6
7
8
9
10
11
function getUserNameByEmail($email)
{
    global $conn;
    $userNameQuery = $conn->query("SELECT name
                                FROM users
                                WHERE `email` = '$email' LIMIT 1"
);

    $fetch = $userNameQuery->fetch_array();
    if(!is_array($fetch)) return 'böyle bir kullanıcı yok';
    return $fetch['name'];
}

Gördüğünüz gibi normalden farklı hiç bir şey yapmıyoruz. Sıradaki iş SOAP server’ı içeri alıp ilklendirmek. Bu da çok basit ve sıradan:

1
2
3
4
5
6
7
8
9
require('lib/nusoap.php');

$server = new soap_server();

//aşağıdaki iki satır Türkçe karakter için gerekli
$server->soap_defencoding = 'UTF-8';
$server->decode_utf8 = false;

$server->configureWSDL('testnamespace', 'urn:testnamespace');

Son olarak yukarıda tanımladığımız fonksiyonu sunucuya kaydedip sunucuyu çalıştıracağız:

1
2
3
4
5
6
7
8
9
10
11
//string olarak email gönderip, sonucu yine string döndüreceğiz.
$server->register("getUserNameByEmail",
                array('email' => 'xsd:string'),
                array('return' => 'xsd:string'),
                'urn:testnamespace',
                'urn:testnamespace#getUserNameByEmail');

// aşağıdaki satır $HTTP_RAW_POST_DATA verisi ile aynı işi görür
$postData = file_get_contents("php://input");

$server->service($postData);

Sunucuyu kodlamayı bitirdik bile!
Sunucu kodumuzun tamamı:

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
<?php

require 'config.php';
$config = new Config();

$conn = new mysqli($config->host , $config->username , $config->password , $config->db);

function getUserNameByEmail($email)
{
    global $conn;
    $userNameQuery = $conn->query("SELECT name
                                FROM users
                                WHERE `email` = '$email' LIMIT 1"
);

    $fetch = $userNameQuery->fetch_array();
    if(!is_array($fetch)) return 'böyle bir kullanıcı yok';
    return $fetch['name'];
   
}

require('lib/nusoap.php');

$server = new soap_server();

//aşağıdaki iki satır Türkçe karakter için gerekli
$server->soap_defencoding = 'UTF-8';
$server->decode_utf8 = false;

$server->configureWSDL('testnamespace', 'urn:testnamespace');

//string olarak email gönderip, sonucu yine string döndüreceğiz.
$server->register("getUserNameByEmail",
                array('email' => 'xsd:string'),
                array('return' => 'xsd:string'),
                'urn:testnamespace',
                'urn:testnamespace#getUserNameByEmail');

// aşağıdaki satır $HTTP_RAW_POST_DATA verisi ile aynı işi görür
$postData = file_get_contents("php://input");

$server->service($postData);

Hepsi bu kadar. service.php dosyasını çağırdığınızda (örneğimizde http://localhost/nusoap/service.php) sizin için küçük bir belgelendirmeyi bile otomatik olarak oluşturduğunu göreceksiniz.
Kodu http://localhost/nusoap/service.php?wsdl şeklinde çağırdığınızda da WSDL dosyanız hazır!

Tamam, sunucuyu kodlamak gerçekten kolaymış. İstemci kısmı nasıl olacak pekiyi? Çok daha kısa ve basit olacak!
Boş bir dosya daha açalım ve onu da “client.php” ismiyle, aynı dizine kaydedelim. Ardından sunucu için yaptığımız şekilde config dosyasını çağırıp config nesnesini ilklendirelim:

1
2
3
4
ini_set("soap.wsdl_cache_enabled", "0"); //WSDL cache devre dışı kalsın
require_once 'lib/nusoap.php';
require 'config.php';
$config = new Config();

Bundan sonra yapmamız gereken tek şey, SOAP sınıfını ilklendirip, service.php’de tanımladığımız metodu çağırmak:

1
2
3
4
5
6
$soapClient = new SoapClient($config->wwwroot . '/service.php?wsdl' , array(
    "trace"      => 1,
    "exceptions" => 0));

$name = $soapClient->getUserNameByEmail('test@mailinator.com');
echo $name;

Hepsi bu! İstemci kodunun tamamı:

1
2
3
4
5
6
7
8
9
10
11
<?php
ini_set("soap.wsdl_cache_enabled", "0"); //WSDL cache devre dışı kalsın
require_once 'lib/nusoap.php';
require 'config.php';
$config = new Config();
$soapClient = new SoapClient($config->wwwroot . '/service.php?wsdl' , array(
    "trace"      => 1,
    "exceptions" => 0));

$name = $soapClient->getUserNameByEmail('test@mailinator.com');
echo $name;

http://localhost/nusoap/client.php kodunu çağırdığımızda “Georges Moustaki” yazısını görüyorsak işimiz bitmiş demektir.

Böylece NuSOAP kullanarak bir SOAP sunucusu ve bir de SOAP istemcisi yazmış olduk.
Kolay gelsin!

Paylaş:
  • Print
  • FriendFeed
  • Twitter
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Blogplay
  • DZone
  • LinkedIn
  • MySpace
  • Ping.fm
  • Reddit
  • StumbleUpon
  • Technorati

Etiketler: , ,

  1. Barbaros TOMAR’s avatar

    Çok faydalı bir yazı olmuş soapla dost olmalıyız artık, deneyeceğim. Teşekkürler.

  2. omer’s avatar

    Rest daha pratik değilmi ? Soap in artisi nedir tam olarak ?

  3. Can’s avatar

    @ömer: Bir artısı olduğunu düşünmüyorum. Yalnız şu var: SOAP görece eski olduğundan, hala bir çok hizmet SOAP ile çalışıyor. REST’i de başka bir yazıda ele alacağım.

  4. Yaşar’s avatar

    getUserNameByEmail fonksiyonuna birden fazla parametre nası gönderirim hocam

  5. Ali’s avatar

    Faydalı kaynak… Teşekkürler..

  6. Furkan Tunalı’s avatar

    ubuntu ve php kullanan vede bunlardan anlayan birileri kaldığını gördüğüm için (türkiye de) çok sevindim blogunu görünce. Bir .net furyasıdır gidiyor canımı sıkan.

    Can, ben nusoap’ı yeni deniyorum. PHP nin kendi içinde birde pecl/pear extension olarak yükleyebileceğin soapclient ve soapserver classları var. Bunları denedin mi? Ben denedim aynen yazında yazdığın gibi hem pek başarılı olamadım (bazen doğru yapsanda karşı taraftaki server çok anlamsız hatalar geri döndürebiliyor çözülmesi çok zor olan) hem de native olarak aktif gelmediği için shared hostingte problem çıkıyor.

    Eğer kullandıysan avantaj dezavantajlarını soracaktım, pratiklik, buglar vs. bakımından.

  7. Savaş’s avatar

    Anti Micropsoft :)

    Teşekkür Ederim Bu Güzel Yazı dizin için.

  8. Emre YILMAZ’s avatar

    Uzun zamandır soap’ın ne olduğunu ne işe yaradığını merak edip dururdum. Alaylı olduğumdan ihtiyaç sebebiyle öğreniyorum yeni teknolojileri. Ve soap ihtiyacım hiç olmadı. Ama sayende soap nedir ne işe yarar hakkında fikir edinmiş oldum. Ki zaten olay budur bence. Yoksa kod kısmında pek bir ahkam yok. Klasik OOP.
    Anlattığın için teşekkürler.