contoh klien sabun php. Menulis aplikasi client-server SOAP di PHP

Saya perlu terhubung ke satu layanan web dan hanya ini yang saya miliki:

    Contoh panggilan:

    nama pengguna Kata sandi

    Saya tahu fungsi ini mengembalikan string;

Inilah yang telah saya lakukan sejauh ini:

    Membuat Referensi Layanan hanya menambahkan alamat WSDL yang ditentukan dalam poin 1.

    Membuat instance layanan web dan memanggil fungsi dengan semua parameter yang diperlukan tetapi tidak ada pengguna dan kata sandi untuk header.

Bagaimana saya bisa melanjutkan? Terima kasih sebelumnya.

1 jawaban

Ini mungkin tempat yang baik untuk memulai jika Anda perlu menambahkan kredensial Anda; saya pikir Anda mungkin harus melakukannya karena Anda mendapatkannya entah bagaimana. Bagian di mana Anda menambahkan kredensial Anda tercantum di bawah ini:

UsernameToken userToken = new UsernameToken(namapengguna, kata sandi, PasswordOption.SendHashed); Service1 serviceProxy = baru Service1(); SoapContext requestContext = serviceProxy.RequestSoapContext; requestContext.Security.Tokens.Add(userToken);

  1. Tambahkan kredensial Anda dengan memasukkannya ke dalam token tertentu - jenis yang termasuk dalam namespace Microsoft.Web.Services2.Security.Tokens
  2. Buat proxy untuk layanan Anda (dalam contoh di atas, serviceProxy)
  3. Akses header permintaan Anda melalui layanan RequestSoapContext Anda
  4. Tambahkan token ke permintaan

Juga, saya pikir Anda dapat melewati bagian "?wsdl" dari alamat karena mengacu pada spesifikasi layanan web. Setelah selesai, Anda dapat mencoba memanggil fungsi dan melihat bagaimana semuanya berjalan: jika fungsi harus mengembalikan sesuatu, periksa apa yang Anda harapkan.

Saya terbiasa menulis kode PHP, tetapi tidak banyak menggunakan pengkodean berorientasi objek. Sekarang saya perlu berinteraksi dengan SOAP (sebagai klien) dan sepertinya saya tidak bisa mendapatkan sintaks yang benar. Saya memiliki file WSDL yang memungkinkan saya mengatur koneksi baru dengan benar menggunakan kelas SoapClient. Namun, saya tidak dapat melakukan panggilan yang benar dan mendapatkan data kembali. Saya perlu mengirim data berikut (yang disederhanakan):

  • ID kontak
  • nama Kontak
  • gambaran umum
  • Jumlah

Ada dua fungsi dalam dokumen WSDL, tetapi saya hanya membutuhkan satu ("Fungsi Pertama" di bawah). Berikut adalah skrip yang saya jalankan untuk mendapatkan informasi tentang fungsi dan tipe yang tersedia:

$klien = new SoapClient("http://example.com/webservices?wsdl"); var_dump($klien->__getFunctions()); var_dump($klien->__getTypes());

Dan inilah output yang dihasilkannya:

Array( => "Fungsi Fungsi Pertama1(Fungsi Pertama $parameter)", => "Fungsi Kedua Fungsi2(Fungsi Kedua $parameter)",); array( => struct Kontak ( id id; nama nama; ) => string "deskripsi string" => string "jumlah int" )

Misalkan saya ingin memanggil FirstFunction dengan data:

  • Nomor Kontak: 100
  • Kontak person: John
  • Deskripsi Umum: Barel Minyak
  • Jumlah: 500

Apa sintaks yang benar? Saya sudah mencoba berbagai macam variasi, tetapi struktur sabun tampaknya cukup fleksibel, jadi ada banyak cara untuk melakukannya. Tidak bisa mengetahuinya dari manual ...

PEMBARUAN 1: Mencoba sampel dari MMK:

$klien = new SoapClient("http://example.com/webservices?wsdl"); $params = array("id" => 100, "name" => "John", "description" => "Barrel of Oil", "jumlah" => 500,); $respons = $client->__soapCall("Function1", array($params));

Tapi saya mendapatkan respons ini: Object has no "Contact" property . Seperti yang Anda lihat di output getTypes() , ada struct bernama Contact , jadi saya rasa saya perlu mengklarifikasi bahwa parameter saya menyertakan data Contact, tetapi pertanyaannya adalah: bagaimana caranya?

PEMBARUAN 2: Saya juga mencoba struktur ini, kesalahan yang sama.

$params = array(array("id" => 100, "name" => "John",), "Barrel Minyak", 500,);

Sebaik:

$params = array("Kontak" => array("id" => 100, "nama" => "John",), "deskripsi" => "Barel Minyak", "jumlah" => 500,);

Kesalahan dalam kedua kasus: Objek tidak memiliki properti "Kontak"

8 tanggapan

Ini adalah hal yang perlu kamu lakukan.

Hanya untuk mengetahui, saya mencoba untuk menciptakan situasi Anda ...

  • Dalam contoh ini, saya telah membuat layanan web .NET menggunakan WebMethod bernama Function1 dan ini adalah parameternya:

Fungsi1 (pin kontak, deskripsi string, jumlah int)

    Di mana Kontak hanyalah kelas kacang yang memiliki getter dan setter untuk id dan name , seperti dalam kasus Anda.

    Anda dapat mengunduh layanan web .NET ini dengan:

Kode.

Inilah yang perlu Anda lakukan di samping PHP:

(Diuji dan bekerja)

id = $id; $ini->nama = $nama; ) ) /* Inisialisasi layanan web dengan WSDL Anda */ $client = new SoapClient("http://localhost:10139/Service1.asmx?wsdl"); /* Isi Objek Kontak Anda */ $contact = new Contact(100, "John"); /* Tetapkan parameter Anda untuk permintaan */ $params = array("Contact" => $contact, "description" => "Barrel of Oil", "amount" => 500,); /* Panggil metode layanan web dengan parameter Anda, dalam hal ini: Function1 */ $response = $client->__soapCall("Function1", array($params)); /* Mencetak respons layanan web */ var_dump($response); ?>

Bagaimana saya tahu itu bekerja?

  • Jika Anda melakukan print_r($params); , Anda akan melihat output ini seperti yang diharapkan oleh layanan web Anda:

Array ([Kontak] => Objek kontak ( => 100 => John) [deskripsi] => Minyak barel [jumlah] => 500)

  • Ketika saya men-debug sampel .NET webservice saya mendapatkan yang berikut:

(Seperti yang Anda lihat, objek Kontak bukan null, begitu juga parameter lainnya, yang berarti bahwa permintaan Anda berhasil diselesaikan dari sisi PHP).

  • Respons dari layanan web .NET seperti yang diharapkan dan ditampilkan di sisi PHP:

objek (stdClass) public "Function1Result" => string "Detail untuk permintaan Anda! id: 100, nama: John, deskripsi: Barel minyak, jumlah: 500" (panjang = 98)

Semoga ini membantu :-)

Anda juga dapat menggunakan layanan SOAP:

"Spanyol", "Nama Kota" => "Alicante"); $respons = $soapclient->getWeather($params); var_dump($respon); // Dapatkan Kota Berdasarkan Negara $param = array("NamaNegara" => "Spanyol"); $respons = $soapclient->getCitiesByCountry($param); var_dump($respon);

Ini adalah contoh dengan layanan nyata dan berfungsi.

Semoga ini membantu.

Pertama, inisialisasi layanan web:

$klien = new SoapClient("http://example.com/webservices?wsdl");

Kemudian atur dan berikan parameter:

$params = array ("arg0" => $contactid, "arg1" => $desc, "arg2" => $contactname); $respons = $client->__soapCall("nama metode", array($params));

Perhatikan bahwa nama metode tersedia di WSDL sebagai nama operasi, misalnya:

Saya tidak tahu mengapa layanan web saya memiliki struktur yang sama dengan milik Anda, tetapi tidak memerlukan kelas untuk parameter, hanya sebuah array.

Misalnya:- WSDL saya:

5390a7006cee11e0ae3e0800200c9a66 831f8c1ad25e1dc89cf2d8f23d2af...fa85155f5c67627 VITS-STAELENS Zoethout kamu 0.100 10K24 2012-12-31 Gladys Roldan de Moras

Calle General Oraá 26 (edisi 4) 28006 Madrid ES
[dilindungi email] es

Var_dump($klien->getFunctions()); var_dump($client->getTypes());

Inilah hasilnya:

Array 0 => string "OrderConfirmation createOrder(OrderRequest $createOrder)" (length=56) array 0 => string "struct OrderRequest ( Identifikasi identifikasi; Pengiriman pengiriman; Parcel parcel; Penerima penerima; referensi string; )" (panjang=130) 1 => string "Identifikasi struct ( pengirim string; hash string; pencetus string; )" (panjang=75) 2 => string "Pengiriman struct ( Node dari; Node ke; )" (panjang=41) 3 => string " struct Node ( negara string; string node; )" (panjang=46) 4 => string "struct Parcel (deskripsi string; bobot desimal; string orderNumber; tanggal orderDate; )" (panjang=93) 5 => string "struct Receiver ( string firstName; string nama keluarga; Alamat alamat; string email; bahasa string; )" (panjang=106) 6 => string "Alamat struct ( string line1; string line2; string kode pos; string kota; negara string; )" (panjang =99) 7 => string "struct OrderConfirmation ( string trackingNumber; referensi string; )" (panjang=71) 8 => string "str uctOrderServiceException(kode string; Info kesalahan OrderServiceException; pesan string; )" (panjang=97)

Jadi dalam kode saya:

$client = new SoapClient("http://packandship-ws.kiala.com/psws/order?wsdl"); $params = array("reference" => $orderId, "identification" => array("sender" => param("kiala", "sender_id"), "hash" => hash("sha512", $orderId . param("kiala", "sender_id") .param("kiala", "password")), "originator" => null,), "delivery" => array("from" => array("country" = > "es", "simpul" => "",), "ke" => array("negara" => "es", "simpul" => "0299")),), "parcel" => array ( "deskripsi" => "Deskripsi", "berat" => 0.200, "orderNumber" => $orderId, "orderDate" => date("Ymd")), "receiver" => array("firstName" => " Nama Depan Pelanggan", "nama keluarga" => "Nama Sur Pelanggan", "alamat" => array("baris1" => "Alamat Baris 1", "baris2" => "Alamat Baris 2", "Kodepos" = > 28006, "kota" => "Madrid", "negara" => "es",), "email" => " [dilindungi email]", "bahasa" => "es")); $result = $client->createOrder($params); var_dump($result);

tapi dia sukses!

Ini adalah contoh yang baik untuk fungsi SOAP "__call". Namun, itu sudah ketinggalan zaman.

Envio Internacional: "; $vem = $cliente->__call("CustoEMSInternacional",array($int_zona, $int_peso)); print $vem; print "

"; ?>

SOAP (Simple Object Access Protocol) adalah protokol berbasis XML untuk bertukar informasi terstruktur antara aplikasi terdistribusi melalui protokol web yang ada seperti HTTP. Spesifikasi SOAP mendefinisikan format yang digunakan oleh pesan XML, bagaimana mereka harus ditangani oleh seperangkat aturan pengkodean untuk standar, tipe data, dan konvensi untuk panggilan prosedur jarak jauh dan respons panggilan.

Layanan web adalah teknologi yang trendi dan modern. Daftar teknologi yang terkait dengan layanan web bertambah hampir setiap hari, tetapi SOAP mungkin yang paling penting dari semuanya. Ini dengan cepat menjadi protokol standar untuk mengakses layanan web. Ini menggunakan pesan XML untuk bertukar informasi antara titik akhir sambil memberikan beberapa manfaat dari protokol biner. Dukungan untuk RPC (Remote Procedure Calls) pada awalnya adalah salah satu fitur minor dari protokol SOAP, tetapi sekarang telah menjadi salah satu fitur yang paling banyak digunakan.

Ekstensi SOAP untuk PHP 5 adalah upaya pertama untuk mengimplementasikan dukungan SOAP di PHP di C. Ini memiliki beberapa keunggulan dibandingkan implementasi SOAP yang ada yang ditulis dalam PHP, yang paling penting adalah kecepatan. Saat ini, ekstensi dianggap eksperimental, tetapi secara bertahap akan menjadi lebih andal dan stabil.

Ekstensi SOAP mengimplementasikan subset besar dari spesifikasi SOAP 1.1, SOAP 1.2, dan WSDL 1.1. Tujuan utamanya adalah untuk memaksimalkan kemampuan RPC SOAP. Jika memungkinkan, WSDL digunakan untuk mempermudah implementasi layanan web.

Klien SOAP pertama

Untuk mendemonstrasikan cara membuat klien SOAP sederhana, kami menggunakan layanan demo "Penawaran Saham Tertunda" dari situs XMethods. Sebelum kita mulai menulis kode PHP, kita perlu mengumpulkan informasi berikut tentang layanan khusus ini:

  • Nama metode
  • URL tempat layanan ini berada
  • Nilai header metode SOAPAction
  • Ruang nama metode
  • Nama dan jenis parameter input dan output metode

Untungnya, semua informasi ini tersedia di situs web XMethods di http://www.xmethods.com/ dari profil RPC layanan:

Nama metode dapatkan Kutipan
URL layanan http://66.28.98.121:9090/soap
SOAPAaction urn:xmethods-delayed-quotes#getQuote
Ruang nama metode guci:xmethods-delayed-quotes
Parameter masukan Simbol (Tali)
parameter keluaran hasil (mengambang)

Contoh 1 (client1.php)

$klien = baru SoapClient(NULL ,
Himpunan(
"lokasi" => "http://66.28.98.121:9090/soap",
"uri" =>
"gaya" => SOAP_RPC ,
"gunakan" => SOAP_ENCODED
));

Cetak($klien -> __panggilan(
/* Nama metode SOAP */
"dapatkan Kutipan",
/* Parameter */
Himpunan(
SabunParam baru(
/* Nilai parameter */
"ibm",
/* Nama parameter */
"simbol"
)),
/* Pilihan */
Himpunan(
/* Ruang nama metode SOAP */
"uri" => "urn:xmethods-delayed-quotes" ,
/* Header HTTP SOAPAction untuk metode SOAP */
"aksi sabun" => "urn:xmethods-delayed-quotes#getQuote"
)). "\n");
?>

Seperti yang Anda lihat, memecahkan masalah sederhana ini membutuhkan banyak usaha.

Untungnya, layanan web dapat menggambarkan diri mereka sendiri kepada klien menggunakan WSDL, yang umumnya cukup nyaman. WSDL untuk layanan "Penawaran Saham Tertunda" tersedia di halaman infonya di xmethods.com - http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl .

Berikut adalah versi klien yang sama yang ditulis ulang untuk bekerja dengan dokumen WSDL ini. Di sini kita tidak perlu lagi menentukan URI server, namespace, header SOAPAction, metode encoding, dan tipe parameter. Semua informasi ini diambil dari file WSDL.

Contoh 2 (client2.php)

$klien = baru
klien sabun(
"http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl"
);

Cetak($klien -> getQuote("ibm" ));
?>

Itu sedikit lebih mudah, bukan?

Masalah apa yang muncul saat menggunakan WSDL? Satu-satunya argumen yang menentang penggunaannya adalah bahwa klien harus membaca WSDL dari server sebelum prosedur apa pun dapat dipanggil, yang dapat memakan waktu cukup lama di web. Untuk mempercepat, ekstensi SOAP menyediakan opsi konfigurasi berikut: soap.wsdl_cache_enabled, soap.wsdl_cache_dir dan soap.wsdl_cache_ttl. Mereka dapat diatur dalam file php.ini atau dengan ini_set() (lihat Contoh 4). Secara default, caching WSDL diaktifkan dan file WSDL di-cache selama 1 hari.

Berikut adalah bagian SOAP dari file php.ini dengan nilai default. Anda dapat menyalinnya ke php.ini Anda.

[sabun mandi]

sabun mandi. wsdl_cache_enabled = "1"
; aktifkan atau nonaktifkan caching WSDL

sabun mandi. wsdl_cache_dir = "/tmp"
; menentukan nama direktori di mana SOAP- ekstensi akan menyimpan file yang di-cache

sabun mandi. wsdl_cache_ttl="86400"
; (seumur hidup ) mengatur waktu(dalam detik) file mana dari cache yang dapat digunakan

Server SOAP Pertama

Mari kita coba menulis layanan web SOAP kita sendiri yang akan melakukan hal yang sama seperti layanan "Penawaran Saham Tertunda" dengan XMethods.

Hal pertama yang harus dilakukan adalah membuat dokumen WSDL yang menjelaskan layanan kami dalam format yang dapat dipahami klien. Untuk melakukan ini, Anda perlu sedikit memodifikasi dokumen asli yang diambil dari situs web Xmethods, jadi kita akan mulai dengan melihatnya lebih detail.

Bagian pesan mendefinisikan dua pesan. Yang pertama adalah getQuoteRequest , yang mengirimkan pesan ke getQuote dan mengambil parameter string tunggal bernama simbol. Pesan kedua adalah getQuoteResponse, respons terhadap permintaan getQuote, melewati nilai float tunggal bernama Result.

Bagian portType mendefinisikan operasi getQuote tunggal yang menentukan pesan mana yang dijelaskan di bagian pesan yang akan digunakan untuk permintaan dan mana untuk respons.

Bagian pengikatan mendefinisikan bagaimana pesan dikodekan dan ditransmisikan. Dalam hal ini, dikatakan bahwa kami akan mengirim permintaan RPC melalui HTTP menggunakan pengkodean SOAP. Ini juga mendefinisikan namespace dan nilai header SOAPAction untuk metode getQuote.

Terakhir, bagian layanan menentukan URL tempat layanan berada.

Contoh 3 (stockquote.wsdl)


targetNamespace="http://example.org/StockQuote"
xmlns:tns="http://example.org/StockQuote"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns="http://schemas.xmlsoap.org/wsdl/">












transport="http://schemas.xmlsoap.org/soap/http"/>



encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>


encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>








Catatan: Caching WSDL diaktifkan secara default. Saat mengembangkan dan men-debug WSDL Anda, caching sebaiknya dinonaktifkan.

Sekarang saatnya untuk mulai membuat server kita.

Pertama-tama, kita akan mengembangkan fungsi getQuote() yang akan memproses permintaan yang masuk dari web. Selanjutnya, kita akan membuat objek dari kelas SoapServer dan melampirkan fungsi kita padanya menggunakan metode SoapServer::addFunction(). Seperti yang akan Anda lihat nanti, konstruktor SoapServer() hanya memiliki satu parameter - jalur ke dokumen WSDL yang menjelaskan layanan.

Contoh 4 (server1.php)

$kutipan = array(
"ibm" => 98.42
);


global $kutipan;
return $quotes [ $simbol ];
}

ini_set("soap.wsdl_cache_enabled" , "0" ); // nonaktifkan cache WSDL
$server = new SoapServer("stockquote1.wsdl" );
$server -> addFunction("getQuote");
$server -> menangani();
?>

SoapServer dapat bekerja tanpa WSDL, seperti halnya klien, tetapi opsi ini tidak memiliki kelebihan yang membuatnya layak digunakan. Jika Anda masih ingin bekerja dengan cara ini, Anda harus memastikan bahwa nilai yang dikembalikan adalah objek dari kelas SoapParam dan SoapVar (seperti pada contoh pertama.

Berikut adalah klien untuk mengakses server SOAP kami. Dibandingkan dengan contoh sebelumnya, hanya tautan ke lokasi WSDL yang ditambahkan. File "stockquote1.wsdl" seharusnya berada di direktori yang sama dengan server SOAP.

Contoh 5 (client3.php)

$klien = new SoapClient("stockquote1.wsdl" );
print($klien -> getQuote("ibm" ));
?>

Apa masalah utama di klien dan server kami?

Sebagai permulaan, mereka tidak menangani kesalahan. Apa yang terjadi ketika server tidak menemukan hasil yang sesuai untuk nilai simbol yang diteruskan ke sana? SOAP memiliki format pesan khusus untuk pesan kesalahan, SoapFault. Untuk menghasilkan pesan seperti itu, server harus melempar pengecualian menggunakan objek SoapFault. Parameter pertama dari konstruktor SoapFault() adalah string dengan kode kesalahan, yang kedua adalah string dengan deskripsi kesalahan. Klien harus ditulis untuk menangani pengecualian SoapFault.

Kedua, fungsionalitas layanan web paling baik dienkapsulasi dalam kelas PHP. Dalam hal ini, kita tidak perlu menggunakan variabel global dan menambahkan setiap metode SOAP ke server secara terpisah. Sebagai gantinya, kita dapat menambahkan seluruh kelas, dan semua metodenya akan tersedia melalui SOAP. Berikut adalah versi klien dan server yang dimodifikasi.

Contoh 6 (server2.php)

Layanan Kutipan kelas (
private $quotes = array("ibm" => 98.42 );

Fungsi getQuote ($simbol ) (
if (isset($this -> quotes [ $symbol ])) (
kembalikan $ini -> tanda kutip [ $simbol ];
) kalau tidak (
lempar baru
SoapFault("Server", "Simbol Tidak Diketahui "$simbol"." );
}
}
}

$server = new SoapServer("stockquote2.wsdl" );
$server -> setClass("Layanan Kutipan");
$server -> menangani();
?>

Seperti yang Anda lihat, saya menggunakan metode SoapServer::setClass() untuk menghubungkan objek SoapServer ke kelas QuoteService.

Contoh 7 (client4.php)

$klien = new SoapClient("stockquote2.wsdl");
mencoba(
gema "

\n" ; 
print($klien -> getQuote("ibm" ));
gema "\n";
print($klien -> getQuote("microsoft" ));
gema "\n
\n" ;
) catch (SoapFault $exception ) (
echo $pengecualian;
}
?>

Apa yang ada di dalam?

Jika Anda ingin memahami format pesan SOAP, atau ingin men-debug sendiri klien SOAP, maka bagian ini cocok untuk Anda.

Seperti yang Anda lihat pada contoh pertama, konstruktor SoapClient() mengambil array asosiatif sebagai parameter kedua. Dengan array ini, kita dapat memanggil berbagai opsi di server.

Mari kita lihat dua di antaranya:

  • trace - memungkinkan klien untuk menyimpan permintaan dan respons SOAP (dinonaktifkan secara default).
  • pengecualian - memungkinkan klien untuk mengontrol mekanisme pengecualian (diaktifkan secara default).

Mari kita lihat contoh klien SOAP berikut. Ini adalah klien yang dimodifikasi dari Contoh 5, menunjukkan dengan tepat apa yang dilewatkan antara klien dan server. Untuk mendapatkan informasi ini, metode __getLastRequest() dan __getLastResponse() digunakan.

Contoh 8 (client5.php)

$klien = new SoapClient("stockquote1.wsdl" ,array(
"jejak" => 1 ,
"pengecualian" => 0 ));
$klien -> getQuote("ibm" );
mencetak"

\n" ; 
cetak "Permintaan:\n" . htmlspecialchars ($client -> __getLastRequest()) . "\n" ;
cetak "Jawaban:\n" . htmlspecialchars($client -> __getLastResponse()). "\n" ;
mencetak"
" ;
?>

Berikut adalah output dari skrip. Ada sedikit modifikasi agar lebih mudah dipahami.

Pertanyaan:



xmlns:xsd="http://www.w3.org/2001/XMLSchema"

SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">


ibm


Menjawab:


xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="urn:xmethods-delayed-quotes"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">


98.42


Implementasi SOAP lainnya untuk PHP

Semuanya ditulis dalam PHP, bukan C.

Ringkasan

Pada artikel ini, saya hanya menjelaskan fitur utama dari ekstensi SOAP. Sebenarnya, ia dapat melakukan lebih banyak lagi, tetapi tidak mungkin untuk menunjukkan semua kemampuannya dalam kerangka satu artikel pendek. Berikut adalah daftar yang utama:

  1. Dukungan untuk tipe data yang kompleks (array, objek)
  2. Dukungan untuk SOAP - header
  3. Dukungan dinamis untuk SOAP 1.1 dan SOAP 1.2

Mungkin akan dibahas lebih detail di artikel selanjutnya.

Dokumentasi rinci untuk ekstensi SOAP ada di http://www.php.net/manual/en/ref.soap.php .

Pengembangan ekstensi ini masih dalam tahap awal, jadi umpan balik Anda akan membantu membuatnya lebih stabil, andal, ramah pengguna, dan lebih cepat. Silakan laporkan masalah yang Anda temui saat menggunakannya di http://bugs.php.net/ .

Tautan

tentang Penulis

Untuk membuat layanan web SOAP di PHP, Anda harus terlebih dahulu menginstal dan mengkonfigurasi PHP, serta server HTTP lokal. Dalam proyek ini, paket XAMP digunakan, yang memungkinkan penginstalan cepat server HTTP Apache dan PHP.

Secara terpisah, Anda perlu membuat perubahan pada file konfigurasi Apache dan PHP.

Dalam file konfigurasi server HTTP Apache httpd.conf, Anda perlu menemukan potongan kode berikut:

Untuk menjalankan skrip PHP di server lokal, Anda harus menyimpannya di direktori root server Apache, secara default, folder htdocs di folder root Apache.

Untuk mengubah direktori root situs, Anda perlu membuat perubahan pada file httpd.conf pada baris di bawah ini:

Untuk mengaktifkan dukungan PHP, baris berikut harus ditambahkan ke file httpd.conf:


Untuk memulai server HTTP Apache, Anda dapat menggunakan perintah konsol, atau panel kontrol XAMMP, yang memungkinkan Anda mengelola status Apache, serta mengonfigurasinya.

Tampilan utilitas ini ditunjukkan pada Gambar 2.

Gambar 2. - Utilitas Panel Kontrol XAMMP:


Untuk membuat layanan web SOAP, Anda perlu menulis dokumen PHP yang mengimplementasikan sisi klien dan server aplikasi, serta halaman WSDL untuk mendeskripsikan layanan web.

Mari kita buat layanan web yang menyediakan layanan web tunggal yang mengembalikan ke klien hasil melakukan operasi aritmatika pada dua angka. Elemen input adalah dua angka yang ditentukan oleh klien, serta variabel karakter yang mendefinisikan operasi aritmatika.

Sisi klien diimplementasikan oleh dua dokumen PHP. Dalam file form.php menggunakan elemen

bentuk di mana pengguna memasukkan data dijelaskan. Properti formulir memiliki metode POST yang digunakan untuk mengekstrak informasi dari formulir dan meneruskannya ke file PHP. Dalam hal ini, data yang dimasukkan oleh pengguna ditransfer ke afqk code.php. Elemen menjelaskan bidang teks untuk memasukkan data dan tombol, ketika ditekan, data ditransfer ke file code.php.

Cuplikan kode yang mengimplementasikan file form.php ditunjukkan di bawah ini:


Dalam file code.php, sebuah instance dari kelas klien dibuat dan data yang dimasukkan oleh pengguna diterima dan dikirim dalam pesan SOAP ke server. Fragmen kode yang mengimplementasikan pembuatan instance dari kelas klien ditunjukkan di bawah ini:

Cuplikan ini membuat instance $client dari kelas SoapClient yang mengeksekusi pesan SOAP sesuai dengan file konfigurasi cacl.wsdl.

Dalam file code.php, variabel $a, $b, $action juga diberikan nilai dari anggota array asosiatif $_POST, yang menyimpan data yang diterima dari form.php.

Fragmen kode yang mengimplementasikan operasi ini ditunjukkan di bawah ini:

Di mana getCalcEntry() adalah operasi yang dijelaskan dalam file WSDL.

Dalam layanan web ini, peran bagian server dimainkan oleh file calc-server.php.

Dalam file ini, fungsi getCalcEntry dideklarasikan dan dipanggil.

Fungsi ini memeriksa nilai variabel $action, dan sesuai dengan itu, melakukan operasi pada variabel $a dan $b, menulis hasilnya ke variabel $c. Dalam fragmen ini, metode addFunction() menyediakan akses ke fungsi getCalcentry ke klien jarak jauh. Metode handle() akan memproses permintaan SOAP, memanggil fungsi yang diperlukan, dan mengirim respons SOAP. Cuplikan kode yang mengimplementasikan fungsi ini ditunjukkan di bawah ini:


File deskripsi calc.wsdl memainkan peran penting dalam pengoperasian layanan web SOAP ini.

File ini mendefinisikan parameter dasar pesan SOAP. Cuplikan kode yang bertanggung jawab untuk menerapkan ini diberikan di bawah ini:


Dalam fragmen ini, elemen getCalcRequest dan getCalcResponse masing-masing adalah permintaan SOAP dan respons SOAP. Di bersarang di Elemen mendefinisikan nama variabel yang diteruskan dan tipenya. Perlu dicatat bahwa adalah mungkin untuk melewatkan string (tipe string) yang akan dikonversi ke angka secara implisit, berkat pengetikan dinamis di PHP. Juga elemen penting dari file WSDL adalah deskripsi antarmuka layanan web yang dilakukan oleh elemen

Dalam fragmen ini, elemen menjelaskan layanan getCalcEntry tertentu yang terdiri dari dua tindakan:

  • - tindakan pertama getCalcRequest adalah mengirim pesan;
  • - tindakan kedua dari getCalcResponse adalah menerima tanggapan.

Untuk keberhasilan pengoperasian layanan web di server lokal, Anda harus:

  • 1) Buat direktori terpisah untuk aplikasi terdistribusi di direktori root server Apache. Masukkan file form.php, code.php, calc-server.php dan calc.wsdl ke dalamnya;
  • 2) Mulai Apache menggunakan konsol atau panel kontrol XAMMP;
  • 3) Di bilah alamat browser, masukkan alamat klien layanan web;
  • 4) Masukkan data di bidang teks dan klik tombol Hitung;
  • 5) Akibatnya, halaman PHP dengan hasil perhitungan yang ditampilkan akan terbuka di tab browser.

Gambar 3. - Hasil modifikasi web service:


Untuk mempertimbangkan pekerjaan SOAP secara lebih rinci, kami memodifikasi kode file code.php sedemikian rupa sehingga daftar pesan SOAP terbaru - permintaan dan tanggapan - akan ditampilkan di browser bersama dengan hasil dari perhitungan.

Fragmen kode yang melakukan fungsi-fungsi ini ditunjukkan di bawah ini:


pemrograman server web

Fragmen ini berisi metode kelas sistem standar:

Mengembalikan teks pesan SOAP. Saat mempertimbangkan pesan SOAP yang diterima dengan cara ini, pertukaran data antara klien dan server terlihat jelas. Dalam kasus kueri, data terkandung dalam cuplikan kode di bawah ini. Fragmen ini berisi badan amplop SOAP, di mana elemen tersebut bersarang A yang menjelaskan layanan web.


Ini berisi elemen bersarang yang menyimpan nilai variabel yang diteruskan dan tipe datanya. Nilai angka 5 dan 3 diteruskan ke server, serta simbol operasi pengurangan yang dilakukan pada mereka.

Cuplikan kode serupa untuk jawabannya ada di bawah ini:


Dalam fragmen kode ini, Anda dapat melihat nilai hasil pengurangan yang diteruskan ke klien - 2.

Halo semuanya!
Kebetulan baru-baru ini saya terlibat dalam pengembangan layanan web. Tapi hari ini topiknya bukan tentang saya, tapi tentang bagaimana kita bisa menulis XML Web Service kita sendiri berdasarkan protokol SOAP 1.2.

Saya berharap setelah membaca topik ini, Anda dapat:

  • tulis implementasi server Anda sendiri dari aplikasi web;
  • tulis implementasi klien Anda sendiri dari aplikasi web;
  • tulis deskripsi layanan web Anda sendiri (WSDL);
  • mengirim array dengan tipe data yang sama ke server oleh klien.

Seperti yang Anda duga, semua keajaiban akan dilakukan menggunakan PHP dan kelas SoapClient dan SoapServer bawaan. Sebagai kelinci, kami akan memiliki layanan untuk mengirim pesan sms.

1 Pernyataan masalah

1.1 Perbatasan

Pada awalnya, saya mengusulkan untuk menangani hasil yang akan kita capai di akhir topik. Seperti yang diumumkan di atas, kami akan menulis layanan untuk mengirim pesan sms, dan lebih tepatnya, kami akan menerima pesan dari berbagai sumber menggunakan protokol SOAP. Setelah itu, kami akan mempertimbangkan dalam bentuk apa mereka datang ke server. Sayangnya, proses antrian pesan untuk penyedia selanjutnya berada di luar cakupan posting ini karena berbagai alasan.

1.2 Data apa yang akan diubah?

Baiklah, kita punya batasan! Langkah selanjutnya yang perlu dilakukan adalah memutuskan data apa yang akan kita tukarkan antara server dan klien. Pada topik ini, saya mengusulkan untuk tidak menjadi lebih bijaksana untuk waktu yang lama dan segera menjawab pertanyaan utama untuk diri sendiri:

  • Berapa data minimum yang harus dikirim ke server untuk mengirim pesan SMS ke pelanggan?
  • Berapa jumlah minimum data yang harus dikirim dari server untuk memenuhi kebutuhan klien?

Sesuatu memberi tahu saya bahwa untuk ini perlu mengirim yang berikut:

  • nomor ponsel, dan
  • teks SMS.

Pada prinsipnya, dua karakteristik ini cukup untuk dikirim, tetapi bagi saya tampaknya segera ada sms dengan ucapan selamat ulang tahun kepada Anda pada jam 3 pagi, atau 4! Pada saat ini, saya akan sangat berterima kasih kepada semua orang karena tidak melupakan saya! Oleh karena itu, kami juga akan mengirim ke server dan

  • tanggal pesan SMS dikirim.

Hal berikutnya yang ingin saya kirim ke server adalah

  • Jenis pesan.

Parameter ini tidak wajib, tetapi bisa sangat berguna bagi kami jika kami dengan cepat perlu memberi tahu bos berapa banyak klien kami yang "senang" dengan berita kami, dan juga menggambar beberapa statistik indah tentang masalah ini.

Namun, saya lupa sesuatu! Jika kita renungkan lebih jauh, perlu dicatat bahwa klien dapat mengirim satu pesan SMS ke server pada satu waktu, atau sejumlah tertentu. Dengan kata lain, dalam satu paket data bisa ada dari satu pesan hingga tak terhingga.

Hasilnya, kami mendapatkan bahwa untuk mengirim pesan SMS, kami memerlukan data berikut:

  • Nomor ponsel,
  • teks sms,
  • waktu pengiriman pesan SMS ke pelanggan,
  • jenis pesan.

Kami menjawab pertanyaan pertama, sekarang perlu menjawab pertanyaan kedua. Dan mungkin saya akan membiarkan diri saya sedikit curang. Oleh karena itu, dari server kami hanya akan mengirimkan data boolean yang nilainya memiliki arti sebagai berikut:

  • BENAR - paket telah berhasil mencapai server, lolos otentikasi dan antri untuk dikirim ke penyedia sms
  • SALAH - dalam semua kasus lain

Ini menyimpulkan deskripsi dari pernyataan masalah! Dan akhirnya, mari kita ke bagian yang paling menarik - kita akan mencari tahu jenis binatang aneh apa SOAP ini!

2 Apa itu SABUN?

Secara umum, awalnya saya tidak berencana untuk menulis apa pun tentang apa itu SOAP dan ingin membatasi diri pada tautan ke situs w3.org dengan spesifikasi yang diperlukan, serta tautan ke Wikipedia. Tetapi pada akhirnya saya memutuskan untuk menulis referensi singkat tentang protokol ini.

Dan saya akan memulai cerita saya dengan fakta bahwa protokol pertukaran data ini termasuk dalam subset protokol berdasarkan apa yang disebut paradigma RPC (Remote Procedure Call), antipodenya adalah REST (Representational State Transfer, representative state transfer) . Anda dapat membaca lebih lanjut tentang ini di Wikipedia, tautan ke artikel ada di akhir topik. Dari artikel ini, kita perlu memahami hal berikut: “Pendekatan RPC memungkinkan Anda untuk menggunakan sejumlah kecil sumber daya jaringan dengan sejumlah besar metode dan protokol yang kompleks. Dengan pendekatan REST, jumlah metode dan kompleksitas protokol sangat terbatas, yang dapat menyebabkan sejumlah besar sumber daya individu.” Artinya, dalam kaitannya dengan kami, ini berarti bahwa dalam kasus pendekatan RPC, situs akan selalu memiliki satu input (tautan) ke layanan dan prosedur mana yang dipanggil untuk memproses data masuk yang kami sampaikan bersama data tersebut, sedangkan dengan pendekatan REST di Situs kami memiliki banyak input (tautan), yang masing-masing hanya menerima dan memproses data tertentu. Jika seseorang yang membaca tahu bagaimana menjelaskan perbedaan dalam pendekatan ini dengan lebih mudah, pastikan untuk menulis di komentar!

Hal berikutnya yang perlu kita ketahui tentang SOAP adalah bahwa protokol ini menggunakan XML yang sama sebagai transport, yang, di satu sisi, sangat baik, karena. gudang senjata kami segera menyertakan kekuatan penuh dari tumpukan teknologi berdasarkan bahasa markup ini, yaitu XML-Schema - bahasa untuk menggambarkan struktur dokumen XML (terima kasih kepada Wikipedia!), yang memungkinkan validasi otomatis data yang tiba di server dari klien.

Jadi, sekarang kita tahu bahwa SOAP adalah protokol yang digunakan untuk mengimplementasikan panggilan prosedur jarak jauh dan menggunakan XML sebagai transportasi! Jika Anda membaca artikel di Wikipedia, maka dari sana Anda juga dapat mengetahui bahwa itu dapat digunakan di atas protokol lapisan aplikasi apa pun, dan tidak hanya dipasangkan dengan HTTP (sayangnya, dalam topik ini kami hanya akan mempertimbangkan SOAP melalui HTTP). Dan Anda tahu apa yang paling saya sukai dari semua ini? Jika tidak ada tebakan, maka saya akan memberi Anda petunjuk - SOAP!… Lagipula tidak ada tebakan?… Apakah Anda benar-benar membaca artikel di Wikipedia?… Secara umum, saya tidak akan menyiksa Anda lebih jauh. Oleh karena itu, saya akan segera beralih ke jawaban: “SOAP (dari bahasa Inggris. Simple Object Access Protocol - a simple .) protokol akses ke objek; hingga spesifikasi 1.2)". Sorotan baris ini dicetak miring! Saya tidak tahu kesimpulan apa yang Anda ambil dari semua ini, tetapi saya melihat yang berikut - karena protokol ini sama sekali tidak dapat disebut "sederhana" (dan tampaknya bahkan w3 setuju dengan ini), maka sejak versi 1.2 tidak lagi didekripsi sama sekali! Dan itu dikenal sebagai SOAP, hanya SOAP dan titik.

Yah, oke, maaf, dibawa sedikit ke samping. Seperti yang saya tulis sebelumnya, XML digunakan sebagai transportasi, dan paket yang berjalan antara klien dan server disebut amplop SOAP. Jika kami mempertimbangkan struktur umum amplop, maka itu akan tampak sangat akrab bagi Anda, karena menyerupai markup halaman HTML. Ini memiliki bagian utama - Menyelimuti, yang mencakup bagian tajuk dan Tubuh, atau Kesalahan. V Tubuh data ditransmisikan dan itu adalah bagian wajib dari amplop, sementara tajuk adalah opsional. V tajuk otorisasi dapat ditransmisikan, atau data lain yang tidak terkait langsung dengan data input dari prosedur layanan web. Pro Kesalahan tidak ada yang istimewa untuk diceritakan, kecuali bahwa itu datang ke klien dari server jika terjadi kesalahan.

Di sinilah cerita ikhtisar saya tentang protokol SOAP berakhir (kita akan melihat amplop itu sendiri dan strukturnya secara lebih rinci ketika klien dan server kami akhirnya belajar bagaimana menjalankannya satu sama lain) dan yang baru dimulai - tentang pendamping SOAP ditelepon WSDL(Bahasa Deskripsi Layanan Web). Ya, ya, ini adalah hal yang paling menakutkan dari kita dari upaya untuk mengambil dan mengimplementasikan API kita sendiri pada protokol ini. Akibatnya, kami biasanya menemukan kembali roda kami dengan JSON sebagai transportasi. Jadi, apa itu WSDL? WSDL adalah bahasa untuk mendeskripsikan layanan web dan mengaksesnya, berdasarkan bahasa Wikipedia XML (c). Jika dari definisi ini seluruh makna suci dari teknologi ini tidak menjadi jelas bagi Anda, maka saya akan mencoba menggambarkannya dengan kata-kata saya sendiri!

WSDL dirancang untuk memungkinkan klien kami berkomunikasi secara normal dengan server. Untuk melakukannya, informasi berikut dijelaskan dalam file dengan ekstensi “*.wsdl”:

  • Namespace apa yang digunakan,
  • Skema data apa yang digunakan,
  • Jenis pesan apa yang diharapkan layanan web dari klien,
  • Data mana yang termasuk prosedur layanan web mana,
  • Prosedur apa yang terkandung dalam layanan web,
  • Bagaimana seharusnya klien memanggil prosedur layanan web,
  • Ke alamat mana panggilan klien harus dikirim.

Seperti yang Anda lihat, file ini adalah seluruh layanan web. Dengan menentukan alamat file WSDL di klien, kita akan tahu segalanya tentang layanan web apa pun! Akibatnya, kita tidak perlu tahu apa-apa tentang di mana layanan web itu sendiri berada. Cukup mengetahui lokasi file WSDL-nya! Segera kita akan mengetahui bahwa SOAP tidak seseram yang dilukis (c) pepatah Rusia.

3 Pengantar Skema XML

Sekarang kami tahu banyak tentang apa itu SOAP, apa yang ada di dalamnya, dan kami memiliki gambaran umum tentang tumpukan teknologi apa yang mengelilinginya. Karena, pertama-tama, SOAP adalah metode interaksi antara klien dan server, dan bahasa markup XML digunakan sebagai transportasi untuk itu, di bagian ini kita akan memahami sedikit bagaimana validasi data otomatis terjadi melalui skema XML.

Tugas utama skema adalah menggambarkan struktur data yang akan kita proses. Semua data dalam skema XML dibagi menjadi: sederhana(skalar) dan kompleks(struktur) jenis. Jenis sederhana termasuk jenis seperti:

  • garis,
  • nomor,
  • boolean,
  • tanggal.

Sesuatu yang sangat sederhana yang tidak memiliki ekstensi di dalamnya. Antipode mereka adalah tipe kompleks yang kompleks. Contoh paling sederhana dari tipe kompleks yang muncul di benak setiap orang adalah objek. Misalnya, sebuah buku. Buku ini terdiri dari properti: Pengarang, judul, harga, nomor ISBN dll. Dan sifat-sifat ini, pada gilirannya, dapat berupa tipe sederhana dan kompleks. Dan tugas skema XML adalah mendeskripsikannya.

Saya mengusulkan untuk tidak pergi jauh dan menulis skema XML untuk pesan sms kami! Di bawah ini adalah deskripsi xml dari pesan sms:

71239876543 Pesan tes 2013-07-20T12:00:00 12

Skema tipe kompleks kami akan terlihat seperti ini:

Entri ini berbunyi sebagai berikut: kami memiliki variabel " pesan" Tipe " pesan" dan ada tipe kompleks bernama " pesan", yang terdiri dari serangkaian elemen berurutan " telepon" Tipe rangkaian, « teks" Tipe rangkaian, « tanggal" Tipe tanggal Waktu, « Tipe" Tipe desimal. Jenis ini sederhana dan sudah didefinisikan dalam definisi skema. Selamat! Kami baru saja menulis Skema XML pertama kami!

Saya berpikir bahwa arti dari unsur-unsur " elemen" dan " tipe kompleks» Semuanya menjadi lebih atau kurang jelas bagi Anda, jadi kami tidak akan fokus pada mereka lagi dan segera beralih ke elemen komposer « urutan". Saat kita menggunakan elemen penyusun " urutan» kami informasikan bahwa elemen yang termasuk di dalamnya harus selalu dalam urutan yang ditentukan dalam skema, dan juga semuanya wajib. Tapi jangan putus asa! Ada dua elemen penyusun lagi dalam Skema XML: pilihan" dan " semua". Komposer pilihan" menunjukkan bahwa harus ada salah satu elemen yang tercantum di dalamnya, dan komposer " semua» – kombinasi apa pun dari elemen yang terdaftar.

Seperti yang Anda ingat, di bagian pertama topik, kami sepakat bahwa paket dapat dikirim dari satu pesan sms hingga tak terbatas. Oleh karena itu, saya mengusulkan untuk memahami bagaimana data tersebut dideklarasikan dalam skema XML. Struktur paket umum mungkin terlihat seperti ini:

71239876543 Pesan tes 1 2013-07-20T12:00:00 12 71239876543 Pesan tes N 2013-07-20T12:00:00 12

Skema untuk tipe yang kompleks akan terlihat seperti ini:

Blok pertama berisi deklarasi familiar dari tipe kompleks “ pesan". Jika Anda perhatikan, maka di setiap tipe sederhana termasuk dalam " pesan”, atribut kualifikasi baru telah ditambahkan” minTerjadi" dan " max Terjadi". Karena tidak sulit menebak dari namanya, yang pertama ( minTerjadi) menunjukkan bahwa urutan yang diberikan harus mengandung setidaknya satu elemen bertipe " telepon», « teks», « tanggal" dan " Tipe”, sedangkan selanjutnya ( max Terjadi) atribut menyatakan kepada kita bahwa paling banyak ada satu elemen seperti itu dalam urutan kita. Akibatnya, ketika kami menulis skema kami untuk data apa pun, kami diberi pilihan terluas tentang cara mengonfigurasinya!

Blok kedua dari skema mendeklarasikan elemen " daftar pesan" Tipe " Daftar Pesan". Sudah jelas itu" Daftar Pesan' adalah tipe kompleks yang mencakup setidaknya satu elemen ' pesan”, tetapi jumlah maksimum elemen tersebut tidak terbatas!

4 Menulis WSDL Anda

Apakah Anda ingat bahwa WSDL adalah layanan web kami? Semoga Anda ingat! Saat kami menulisnya, layanan web kecil kami akan mengapung di atasnya. Jadi saya sarankan Anda tidak menipu.

Secara umum, agar semuanya berfungsi dengan benar untuk kami, kami perlu mentransfer file WSDL dengan tipe MIME yang benar ke klien. Untuk melakukan ini, Anda perlu mengonfigurasi server web Anda, yaitu, atur jenis MIME untuk file dengan ekstensi *.wsdl ke baris berikut:

Aplikasi/wsdl+xml

Tapi dalam prakteknya, saya biasanya mengirimkan header HTTP melalui PHP " teks/xml»:

Header("Jenis Konten: teks/xml; charset=utf-8");

dan semuanya bekerja dengan baik!

Saya ingin memperingatkan Anda segera, layanan web sederhana kami akan memiliki deskripsi yang agak mengesankan, jadi jangan khawatir, karena. sebagian besar teks adalah air wajib dan setelah ditulis dapat terus disalin dari satu layanan web ke layanan web lainnya!

Karena WSDL adalah XML, maka di baris pertama Anda harus menulisnya secara langsung. Elemen root dari sebuah file harus selalu diberi nama " definisi»:

Biasanya, WSDL terdiri dari 4-5 blok utama. Blok pertama adalah definisi layanan web, atau dengan kata lain, titik masuk.

Dikatakan di sini bahwa kami memiliki layanan yang disebut - " Layanan SMS". Pada prinsipnya, semua nama dalam file WSDL dapat Anda ubah sesuai keinginan Anda, karena mereka sama sekali tidak memainkan peran.

Setelah itu, kami menyatakan bahwa dalam layanan web kami " Layanan SMS" ada titik masuk ("port"), yang disebut " SmsServicePort". Ke titik masuk inilah semua permintaan dari klien ke server akan dikirim. Dan kami tentukan di elemen " alamat» link ke file handler yang akan menerima permintaan.

Setelah kami mendefinisikan layanan web dan menentukan titik masuk untuknya, kami perlu mengikat prosedur yang didukung padanya:

Untuk melakukan ini, daftar operasi mana dan dalam bentuk apa y akan dipanggil. Itu. untuk pelabuhan SmsServicePort» sebuah ikatan bernama « Pengikatan Layanan SMS", yang memiliki jenis panggilan " rpc” dan HTTP digunakan sebagai protokol transfer (transportasi). Jadi, kami telah menunjukkan di sini bahwa kami akan membuat panggilan RPC melalui HTTP. Setelah itu, kami menjelaskan prosedur mana ( operasi) didukung dalam layanan web. Kami hanya akan mendukung satu prosedur - " Kirim SMS". Melalui prosedur ini, pesan indah kami akan dikirim ke server! Setelah prosedur dideklarasikan, perlu ditunjukkan dalam bentuk apa data akan ditransmisikan. Dalam hal ini, ditentukan bahwa amplop SOAP standar akan digunakan.

Setelah itu, kita perlu mengikat prosedur ke pesan:

Untuk melakukan ini, kami menetapkan bahwa pengikatan kami ("pengikatan") bertipe " SmsServicePortType" dan dalam elemen " portType» dengan nama jenis yang sama, tentukan pengikatan prosedur ke pesan. Jadi, pesan yang masuk (dari klien ke server) akan disebut " kirimSmsRequest", dan keluar (dari server ke klien)" kirimSmsRespons". Seperti semua nama di WSDL, nama pesan masuk dan keluar bersifat arbitrer.

Sekarang kita perlu mendeskripsikan pesan itu sendiri, mis. masuk dan keluar:

Untuk melakukan ini, kami menambahkan elemen " pesan» dengan nama « kirimSmsRequest" dan " kirimSmsRespons" masing-masing. Di dalamnya, kami menunjukkan bahwa sebuah amplop harus masuk ke input, yang strukturnya sesuai dengan tipe data " Meminta". Setelah itu, amplop yang berisi tipe data dikembalikan dari server - " Tanggapan».

Sekarang kita perlu melakukan sedikit - tambahkan deskripsi jenis ini ke file WSDL kita! Dan bagaimana menurut Anda WSDL menggambarkan data yang masuk dan keluar? Saya pikir Anda telah memahami segalanya untuk waktu yang lama dan mengatakan kepada diri sendiri bahwa dengan bantuan skema XML! Dan Anda akan benar sekali!

Anda dapat memberi selamat kepada kami! WSDL pertama kami telah ditulis! Dan kami selangkah lebih dekat untuk mencapai tujuan kami.
Selanjutnya, kita akan membahas apa yang disediakan PHP untuk mengembangkan aplikasi terdistribusi kita sendiri.

5 Server SOAP pertama kami

Sebelumnya, saya menulis bahwa untuk membuat server SOAP di PHP, kita akan menggunakan kelas SoapServer bawaan. Agar semua tindakan selanjutnya terjadi dengan cara yang sama seperti saya, Anda perlu sedikit mengubah PHP Anda. Untuk lebih tepatnya, Anda perlu memastikan bahwa Anda telah menginstal ekstensi "php-soap". Cara memasangnya di server web Anda sebaiknya dibaca di situs web resmi PHP (lihat referensi).

Setelah semuanya terinstal dan dikonfigurasi, kita perlu membuat file di folder root hosting Anda " smsservice.php» dengan isi sebagai berikut:

setClass("SoapSmsGateWay"); //Memulai server $server->handle();

Yang di atas garis dengan fungsi “ini_set”, saya harap tidak perlu dijelaskan. Karena itu mendefinisikan header HTTP mana yang akan kami kirim dari server ke klien dan mengonfigurasi lingkungan. Di baris "ini_set", kami menonaktifkan caching file WSDL sehingga perubahan kami segera berlaku pada klien.

Sekarang kita datang ke server! Seperti yang Anda lihat, seluruh server SOAP hanya memiliki tiga baris! Di baris pertama, kami membuat instance baru dari objek SoapServer dan meneruskan alamat deskripsi layanan web WSDL kami ke konstruktornya. Sekarang kita tahu bahwa itu akan ditempatkan di root hosting dalam file dengan nama yang memberi tahu " smsservice.wsdl.php". Di baris kedua, kami memberi tahu server SOAP kelas mana yang harus ditarik untuk memproses amplop yang diterima dari klien dan mengembalikan amplop dengan tanggapan. Seperti yang mungkin sudah Anda duga, di kelas inilah satu-satunya metode kami yang akan dijelaskan. Kirim SMS. Di baris ketiga kita memulai server! Semuanya, server kami sudah siap! Dengan itu saya mengucapkan selamat kepada kita semua!

Sekarang kita perlu membuat file WSDL. Untuk melakukan ini, Anda dapat dengan mudah menyalin isinya dari bagian sebelumnya, atau mengambil kebebasan dan "template" sedikit:

"; ?> /" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http:// schemas.xmlsoap.org/wsdl/http/" name="SmsWsdl" xmlns="http://schemas.xmlsoap.org/wsdl/"> /"> /smsservice.php" />

Pada tahap ini, server yang dihasilkan harus sesuai dengan kita sepenuhnya, karena. kita dapat mencatat amplop yang datang ke sana dan kemudian dengan tenang menganalisis data yang masuk. Agar kami menerima apa pun di server, kami membutuhkan klien. Jadi mari kita lanjutkan dengan mereka!

6 klien SOAP sedang dalam perjalanan

Pertama-tama, kita perlu membuat file di mana kita akan menulis klien. Seperti biasa, kita akan membuatnya di root host dan menyebutnya " klien.php”, dan di dalamnya kami menulis sebagai berikut:

daftarpesan = DaftarPesan baru(); $req->messageList->message = new Message(); $req->messageList->message->telepon = "79871234567"; $req->messageList->message->text = "Uji pesan 1"; $req->messageList->message->date = "2013-07-21T15:00:00.26"; $req->messageList->message->type = 15; $client = new SoapClient("http://($_SERVER["HTTP_HOST"])/smsservice.wsdl.php", array("soap_version" => SOAP_1_2)); var_dump($klien->sendSms($req));

Mari kita deskripsikan objek kita. Ketika kami menulis WSDL, tiga entitas dijelaskan di dalamnya untuk amplop yang memasuki server: Meminta, Daftar Pesan dan pesan. Dengan demikian, kelas Meminta, Daftar Pesan dan pesan adalah refleksi dari entitas ini dalam skrip PHP kami.

Setelah kita mendefinisikan objek, kita perlu membuat objek ( $req), yang akan dikirim ke server. Kemudian datang dua baris yang paling dihargai untuk kita! Klien SOAP kami! Percaya atau tidak, tetapi ini sudah cukup bagi server kami untuk mulai menuangkan pesan dari klien, serta server kami berhasil menerima dan memprosesnya! Yang pertama, kami membuat instance kelas SoapClient dan meneruskan alamat lokasi file WSDL ke konstruktornya, dan secara eksplisit menunjukkan dalam parameter bahwa kami akan bekerja menggunakan protokol SOAP versi 1.2. Pada baris berikutnya kita memanggil metode Kirim SMS obyek $klien dan langsung tampilkan hasilnya di browser.
Mari kita jalankan dan lihat apa yang akhirnya kita dapatkan!

Saya menerima objek berikut dari server:

Object(stdClass) publik "status" => boolean benar

Dan ini luar biasa, karena. sekarang kami tahu pasti bahwa server kami berfungsi dan tidak hanya berfungsi, tetapi juga dapat mengembalikan beberapa nilai ke klien!

Sekarang mari kita lihat log yang kita simpan dengan hati-hati di sisi server! Di bagian pertama, kita melihat data mentah yang masuk ke server:

79871234567 Pesan tes 1 21-07-2013T15:00:00.26 15

Ini amplopnya. Sekarang Anda tahu seperti apa bentuknya! Tapi sepertinya kita tidak tertarik untuk terus mengaguminya, jadi mari kita deserialize objek dari file log dan lihat apakah semuanya baik-baik saja dengan kita:

Objek(stdClass) publik "messageList" => objek(stdClass) publik "pesan" => objek(stdClass) publik "telepon" => string "79871234567" (panjang=11) publik "teks" => string "Uji pesan 1 " (panjang=37) publik "tanggal" => string "2013-07-21T15:00:00.26" (panjang=22) publik "tipe" => string "15" (panjang=2)

Seperti yang Anda lihat, objek itu dideserialisasi dengan benar, yang dengannya saya ingin mengucapkan selamat kepada kita semua! Selanjutnya, sesuatu yang lebih menarik menanti kita! Yaitu, kami akan mengirim oleh klien ke server bukan satu pesan sms, tetapi satu paket (lebih tepatnya, tiga utuh)!

7 Mengirim Objek Kompleks

Mari kita pikirkan bagaimana kita dapat mengirim sejumlah besar pesan ke server dalam satu paket? Mungkin cara termudah adalah dengan mengatur array di dalam elemen messageList! Ayo lakukan:

// buat objek untuk dikirim ke server $req = new Request(); $req->messageList = new MessageList(); $msg1 = Pesan baru(); $msg1->telepon = "79871234567"; $msg1->text = "Uji pesan 1"; $msg1->date = "2013-07-21T15:00:00.26"; $msg1->tipe = 15; $msg2 = Pesan baru(); $msg2->telepon = "79871234567"; $msg2->text = "Uji pesan 2"; $msg2->tanggal = "2014-08-22T16:01:10"; $msg2->tipe = 16; $msg3 = Pesan baru(); $msg3->telepon = "79871234567"; $msg3->text = "Uji pesan 3"; $msg3->tanggal = "2014-08-22T16:01:10"; $msg3->tipe = 17; $req->messageList->message = $msg1; $req->messageList->message = $msg2; $req->messageList->message = $msg3;

Log kami menunjukkan bahwa paket berikut berasal dari klien:

79871234567 Pesan tes 1 21-07-2013T15:00:00.26 15 79871234567 Pesan tes 2 2014-08-22T16:01:10 16 79871234567 Pesan tes 3 2014-08-22T16:01:10 17

Omong kosong apa, katamu? Dan Anda akan benar dalam arti tertentu, karena. sama seperti kami mengetahui objek mana yang meninggalkan klien, objek itu datang ke server kami dalam bentuk amplop dengan bentuk yang persis sama. Benar, pesan sms tidak diserialisasi dalam XML seperti yang kami butuhkan - pesan tersebut harus dibungkus dengan elemen pesan, tidak masuk Struktur. Sekarang mari kita lihat dalam bentuk apa objek seperti itu datang ke metode Kirim SMS:

Objek(stdClass) publik "messageList" => objek(stdClass) publik "pesan" => objek(stdClass) publik "Struct" => array (ukuran=3) 0 => objek(stdClass) publik "telepon" => string "79871234567" (panjang=11) publik "teks" => string "Uji pesan 1" (panjang=37) publik "tanggal" => string "2013-07-21T15:00:00.26" (panjang=22) publik " ketik" => string "15" (panjang=2) 1 => objek(stdClass) publik "telepon" => string "79871234567" (panjang=11) publik "teks" => string "Uji pesan 2" (panjang= 37) "tanggal" publik => string "2014-08-22T16:01:10" (panjang=19) publik "ketik" => string "16" (panjang=2) 2 => objek(stdClass) publik "telepon " => string "79871234567" (panjang=11) publik "teks" => string "Uji pesan 3" (panjang=37) publik "tanggal" => string "2014-08-22T16:01:10" (panjang= 19) "tipe" publik => string "17" (panjang = 2)

Apa yang diberikan pengetahuan ini kepada kita? Hanya saja jalur yang kami pilih tidak benar dan kami belum menerima jawaban atas pertanyaan - "Bagaimana kami bisa mendapatkan struktur data yang benar di server?". Tapi saya sarankan untuk tidak putus asa dan mencoba untuk melemparkan array kami ke tipe Sebuah Objek:

$req->messageList->message = (objek)$req->messageList->message;

Dalam hal ini, kami akan menerima amplop lain:

79871234567 Pesan tes 1 21-07-2013T15:00:00.26 15 79871234567 Pesan tes 2 2014-08-22T16:01:10 16 79871234567 Pesan tes 3 2014-08-22T16:01:10 17

Datang ke metode Kirim SMS objek memiliki struktur sebagai berikut:

Objek(stdClass) publik "messageList" => objek(stdClass) publik "pesan" => objek(stdClass) publik "BOGUS" => array (ukuran=3) 0 => objek(stdClass) publik "telepon" => string "79871234567" (panjang=11) publik "teks" => string "Uji pesan 1" (panjang=37) publik "tanggal" => string "2013-07-21T15:00:00.26" (panjang=22) publik " ketik" => string "15" (panjang=2) 1 => objek(stdClass) publik "telepon" => string "79871234567" (panjang=11) publik "teks" => string "Uji pesan 2" (panjang= 37) "tanggal" publik => string "2014-08-22T16:01:10" (panjang=19) publik "ketik" => string "16" (panjang=2) 2 => objek(stdClass) publik "telepon " => string "79871234567" (panjang=11) publik "teks" => string "Uji pesan 3" (panjang=37) publik "tanggal" => string "2014-08-22T16:01:10" (panjang= 19) "tipe" publik => string "17" (panjang = 2)

Adapun saya, maka "dari perubahan tempat istilah, jumlahnya tidak berubah" (c). Apa PALSU, Apa Struktur Kami belum mencapai tujuan kami! Dan untuk mencapainya, kita perlu memastikan bahwa alih-alih nama yang tidak dapat dipahami ini, nama asli kita pesan. Namun bagaimana cara mencapainya, penulis belum mengetahuinya. Oleh karena itu, satu-satunya hal yang dapat kita lakukan adalah menyingkirkan wadah ekstra tersebut. Dengan kata lain, sekarang kita akan memastikan bahwa alih-alih pesan menjadi PALSU! Untuk melakukannya, ubah objek sebagai berikut:

// buat objek untuk dikirim ke server $req = new Request(); $msg1 = Pesan baru(); $msg1->telepon = "79871234567"; $msg1->text = "Uji pesan 1"; $msg1->date = "2013-07-21T15:00:00.26"; $msg1->tipe = 15; $msg2 = Pesan baru(); $msg2->telepon = "79871234567"; $msg2->text = "Uji pesan 2"; $msg2->tanggal = "2014-08-22T16:01:10"; $msg2->tipe = 16; $msg3 = Pesan baru(); $msg3->telepon = "79871234567"; $msg3->text = "Uji pesan 3"; $msg3->tanggal = "2014-08-22T16:01:10"; $msg3->tipe = 17; $req->messageList = $msg1; $req->messageList = $msg2; $req->messageList = $msg3; $req->messageList = (objek)$req->messageList;

Bagaimana jika kita beruntung dan nama yang benar muncul dari skema? Untuk melakukan ini, mari kita lihat amplop yang datang:

79871234567 Pesan tes 1 21-07-2013T15:00:00.26 15 79871234567 Pesan tes 2 2014-08-22T16:01:10 16 79871234567 Pesan tes 3 2014-08-22T16:01:10 17

Ya, keajaiban itu tidak terjadi! PALSU- kami tidak akan menang! Datang Kirim SMS objek dalam hal ini akan terlihat seperti ini:

Objek(stdClass) publik "messageList" => objek(stdClass) publik "BOGUS" => array (ukuran=3) 0 => objek(stdClass) publik "telepon" => string "79871234567" (panjang=11) publik " teks" => string "Uji pesan 1" (panjang=37) publik "tanggal" => string "2013-07-21T15:00:00.26" (panjang=22) publik "ketik" => string "15" (panjang =2) 1 => objek(stdClass) publik "telepon" => string "79871234567" (panjang=11) publik "teks" => string "Uji pesan 2" (panjang=37) publik "tanggal" => string " 22-08-2014T16:01:10" (panjang=19) publik "ketik" => string "16" (panjang=2) 2 => objek(stdClass) publik "telepon" => string "79871234567" (panjang= 11) publik "teks" => string "Uji pesan 3" (panjang=37) publik "tanggal" => string "2014-08-22T16:01:10" (panjang=19) publik "ketik" => string " 17" (panjang = 2)

Seperti yang mereka katakan - "Hampir"! Pada catatan (sedikit sedih) ini, saya mengusulkan untuk diam-diam membulatkan dan menarik beberapa kesimpulan untuk diri kita sendiri.

8 Kesimpulan

Akhirnya kami sampai di sini! Mari kita putuskan apa yang dapat Anda lakukan sekarang:

  • Anda dapat menulis file WSDL yang diperlukan untuk layanan web Anda;
  • Anda dapat menulis klien Anda sendiri tanpa masalah yang dapat berkomunikasi dengan server menggunakan protokol SOAP;
  • Anda dapat menulis server Anda sendiri yang berkomunikasi dengan dunia luar melalui SOAP;
  • Anda dapat mengirim array dari jenis objek yang sama ke server dari klien Anda (dengan beberapa batasan).

Juga, kami membuat beberapa penemuan untuk diri kami sendiri selama penelitian kecil kami:

  • kelas asli SoapClient tidak tahu cara membuat serialisasi struktur data dengan tipe yang sama dalam XML dengan benar;
  • saat membuat serial array ke XML, itu membuat elemen tambahan bernama Struktur;
  • saat membuat serial objek ke XML, itu membuat elemen tambahan bernama PALSU;
  • PALSU lebih jahat dari Struktur karena amplop lebih ringkas (tidak ada ruang nama tambahan yang ditambahkan ke header XML amplop);
  • sayangnya, kelas SoapServer tidak secara otomatis memvalidasi data amplop dengan skema XML kami (mungkin server lain juga tidak).

Tampilan