SABUN Nedir? Örnek olarak belavia adında açık bir web servisi var.

LeaseWeb'de, dahili uygulamalarımızı birbiriyle entegre etmek için SOAP web hizmetleriyle çok çalışıyoruz. Özellikle uygulamalarımızın geliştirilmesi ve test edilmesi sırasında SOAP API'leri ile pratik yapma becerisine ihtiyacımız var.

$ curl -sS http://leaseweb.github.io/php-soap-client/installer | php

Bu, phar dosyasını mevcut çalışma dizinine indirecek ve çalıştırılabilir hale getirecektir, böylece aşağıdakileri çağırarak hemen kullanmaya başlayabilirsiniz:

$ ./soap_client

En son ana sürümü yüklemek için kaynak kodunu doğrudan GitHub'dan alabilir, kendi .phar dosyanızı paketleyebilir ve GNU Make'i kullanarak yükleyebilirsiniz.
.phar dosyasını oluşturabilmek için bestecinin kurulu olması gerekir. Besteci hakkında daha fazla bilgi edinmek için mükemmel belgelerine bakın.

# Php sabun istemcisini yükleyin $ git clone https://github.com/LeaseWeb/php-soap-client.git $ cd php-soap-client $ besteci.phar kurulumu $ make $ sudo make install

Çalıştırırken Failed to compile phar istisnası alıyorsanız, php.ini dosyanızda phar.readonly = Off değerini ayarlamanız gerekir. Bir geliştirme makinesinde bunu yapmakta sorun yoktur ancak lütfen phar.readonly'yi Off olarak ayarlarken güvenlik risklerinin farkında olun.

Yukarıdaki make install komutu, sabun_client uygulamasını /usr/local/bin dizinine yükleyecek ve çalıştırılabilir hale getirecektir, böylece onu kolayca şu şekilde çağırabilirsiniz:

$ sabun_client php-soap-client sürüm 2.1.3 Kullanım: komut Seçenekler: ... Kullanılabilir komutlar: çağrı Uzak hizmeti belirtilen 'yöntem' ile çağırın ve yanıtı stdout'a aktarın. yardım Bir komut listesi için yardım görüntüler Komut listesi yöntemlerini listeler Uzaktan kumandada çağrılabilecek mevcut yöntemlerin bir listesini alın. istek Verilen yöntem için xml formatlı bir SOAP isteği oluşturun ve stdout'a çıktı verin. wsdl Bir sabun hizmetinin WSDL'sini alın.

Bu noktadan itibaren, sabun_client.phar dosyasını sisteminizde /usr/local/bin/soap_client dizinine yüklediğinizi ve /urs/local/bin dizininin $PATH dizininizde olduğunu varsayıyoruz.

Diyelim ki http://www.webservicex.net/ConvertTemperature.asmx uzak hizmetinde hangi yöntemlerin mevcut olduğunu görmek istiyoruz. Aşağıdaki komutu verebiliriz:

$ sabun_client --endpoint="http://www.webservicex.net/ConvertTemperature.asmx?WSDL" liste yöntemleri

Hangisi aşağıdaki çıktıyı verecektir:

DönüştürmeTemp

Yukarıdaki komutu -vvv seçeneğiyle çalıştırırsanız daha ayrıntılı çıktı elde edersiniz.
Bu durumda kullanılabilen tek yöntem ConvertTemp'tir. Bu yöntem için bir SOAP XML isteğinin nasıl göründüğüne bakalım:

$ sabun_client --endpoint="http://www.webservicex.net/ConvertTemperature.asmx?WSDL" isteği ConvertTemp 0

Uzak hizmetteki ConvertTemp yöntemine SOAP isteği yapmak istiyorsanız call sub komutunu kullanın:

$ sabun_client --endpoint="http://www.webservicex.net/ConvertTemperature.asmx?WSDL" çağrısı --editor ConvertTemp

Çağrı alt komutundan sonra --editor seçeneğine dikkat edin. --editor bayrağını kullanırsanız, sabun_client, ortam değişkeniniz $EDITOR'da belirtilen düzenleyiciyi açacak, böylece istek XML'ini göndermeden önce değiştirebileceksiniz.

Aynı isteği birden çok kez gönderirseniz, bir sabun isteğini yerel bir XML dosyası olarak kaydedebilir ve bunu sabun_client çağrı komutunun /dev/stdin'ine iletebilirsiniz:

# İstek xml'ini alın ve yerel olarak saklayın $ sabun_client --endpoint="http://www.webservicex.net/ConvertTemperature.asmx?WSDL" request ConvertTemp > my_sample_request.xml # Şimdi my_sample_request.xml dosyasını düzenleyin # Şimdi Bu önceden hazırlanmış istek ile ConvertTemp yöntemi $ sabun_client --endpoint="http://www.webservicex.net/ConvertTemperature.asmx?WSDL" ConvertTemp'i çağırır< my_sample_request.xml

Uzak bir web hizmetini keşfederken sabun_client komutlarını kısa sürede sık sık tekrarlayacağınız için, WSDL'nin URL'sini içeren SOAPCLIENT_ENDPOINT ortam değişkenini ayarlayarak kendinize biraz zaman kazandırabilirsiniz. Bu ortam değişkeni ayarlandığında --endpoint komut satırı seçeneğini atlayabilirsiniz. Şimdi bunu yapalım ve ConvertTemp yöntemini çağıralım:

$export SOAPCLIENT_ENDPOINT="http://www.webservicex.net/ConvertTemperature.asmx?WSDL" $soap_client çağrısı ConvertTemp< my_sample_request.xml

Santigrat cinsinden 107,6 derece Fahrenheit'in ne kadar olduğunu bilmek istedim, bu nedenle my_sample_request.xml'im şunu içeriyor:

$ cat my_sample_request.xml 107.6 dereceFahrenheit santigrat derece

$ sabun_client ConvertTemp'i çağırır< my_sample_request.xml stdClass Object ( => 42)

Cevap 42'dir.

Yanıtları XML biçiminde görmeyi tercih ederseniz --xml komut satırı seçeneğini kullanabilirsiniz:

$ sabun_istem çağrısı --xml ConvertTemp< my_sample_request.xml 42

Bu eğitim size SOAP API'lerini keşfetmeye, test etmeye ve/veya geliştirmeye başlamanız için yeterli bilgi verecektir.
Gelecekteki bir blog yazısında php sabun istemcisi konusuna devam edeceğim. Şu anda .phar arşivini web için paketlemeye çalışıyoruz.

  • öğretici

Herkese selam!
Öyle oldu ki yakın zamanda web hizmetleri geliştirmeye başladım. Ancak bugünkü konu benimle ilgili değil, SOAP 1.2 protokolünü temel alarak kendi XML Web Servisimizi nasıl yazabileceğimizle ilgili.

Umarım konuyu okuduktan sonra şunları yapabileceksiniz:

  • bir web uygulamasının kendi sunucu uygulamasını yazın;
  • bir web uygulamasının kendi istemci uygulamasını yazın;
  • kendi web hizmeti açıklamanızı (WSDL) yazın;
  • aynı türdeki verilerin istemci dizilerini sunucuya gönderin.
Tahmin edebileceğiniz gibi, tüm sihir PHP ve yerleşik SoapClient ve SoapServer sınıfları kullanılarak yapılacak. Tavşanımız SMS mesajı göndermeye yönelik bir hizmet olacaktır.

1 Sorun bildirimi

1.1 Sınırlar

Başlangıçta konunun sonunda elde edeceğimiz sonuçla ilgilenmeyi öneriyorum. Yukarıda da açıkladığımız gibi SMS mesaj göndermek için bir servis yazacağız, daha doğrusu SOAP protokolü üzerinden farklı kaynaklardan mesaj alacağız. Bundan sonra sunucuya hangi biçimde geldiklerini ele alacağız. Sağlayıcıya daha fazla gönderilmek üzere mesajları sıraya alma süreci maalesef birçok nedenden dolayı bu yazının kapsamı dışındadır.

1.2 Hangi verileri değiştireceğiz?

Harika, sınırlara karar verdik! Atılması gereken bir sonraki adım, sunucu ve istemci arasında hangi veri alışverişini yapacağımıza karar vermektir. Bu konuda çok uzun süre kılları ayırmamanızı ve ana soruları hemen kendiniz cevaplamanızı öneririm:
  • Bir aboneye SMS mesajı göndermek için sunucuya hangi minimum verilerin gönderilmesi gerekir?
  • İstemcinin ihtiyaçlarını karşılamak için sunucudan hangi minimum veriler gönderilmelidir?
İçimden bir ses bunun için aşağıdakileri göndermeniz gerektiğini söylüyor:
  • cep telefonu numarası ve
  • SMS mesajının metni.
Prensip olarak, bu iki özellik göndermek için yeterlidir, ancak doğum günü tebriklerini içeren bir SMS'in sabah saat 3'te veya 4'te size geleceğini hemen hayal ediyorum! Şu anda beni unutmadıkları için herkese çok minnettar olacağım! Bu nedenle sunucuya da göndereceğiz ve
  • SMS mesajının gönderilme tarihi.
Sunucuya göndermek istediğim bir sonraki şey:
  • Mesaj tipi.
Bu parametre zorunlu değildir, ancak patronumuza haberlerimizden kaç müşterimizi "memnun ettiğimizi" hızlı bir şekilde söylememiz gerekirse ve bu konuda bazı güzel istatistikler çizmemiz gerekirse, bizim için çok yararlı olabilir.

Ama yine de bir şeyi unuttum! Biraz daha düşünürsek, istemcinin sunucuya aynı anda hem bir SMS mesajı hem de birden fazla mesaj gönderebileceğini belirtmekte fayda var. Başka bir deyişle, bir veri paketi birden sonsuza kadar mesaj içerebilir.

Sonuç olarak, bir SMS mesajı göndermek için aşağıdaki verilere ihtiyacımız var:

  • Cep telefonu numarası,
  • SMS mesaj metni,
  • SMS mesajının aboneye gönderilme zamanı,
  • mesaj tipi.

Birinci soruyu yanıtladık, şimdi ikinci soruyu yanıtlamamız gerekiyor. Ve belki de biraz ortalığı karıştırmama izin veririm. Bu nedenle, sunucudan yalnızca anlamı aşağıdaki anlama gelen Boolean verilerini göndereceğiz:

  • DOĞRU – paket sunucuya başarıyla ulaştı, kimlik doğrulamayı geçti ve SMS sağlayıcısına gönderilmek üzere sıraya alındı
  • YANLIŞ – diğer tüm durumlarda

Bu, sorun bildiriminin açıklamasını tamamlıyor! Ve son olarak işin eğlenceli kısmına geçelim - bu SABUN'un ne tür tuhaf bir canavar olduğunu bulalım!

2 SABUN Nedir?

Genel olarak, başlangıçta SOAP'ın ne olduğu hakkında hiçbir şey yazmayı planlamadım ve kendimi gerekli spesifikasyonları içeren w3.org web sitesine olan bağlantıların yanı sıra Wikipedia bağlantılarıyla sınırlamak istedim. Ancak en sonunda bu protokol hakkında kısa bir not yazmaya karar verdim.

Ve hikayeme, bu veri alışverişi protokolünün, antipodu REST (Temsili Durum Transferi) olan RPC (Uzaktan Prosedür Çağrısı) paradigmasına dayanan bir protokol alt kümesine ait olduğu gerçeğiyle başlayacağım. Bununla ilgili daha fazla bilgiyi Vikipedi'de okuyabilirsiniz; makalelere bağlantılar konunun en sonundadır. Bu yazılardan şunu anlamamız gerekiyor: “RPC yaklaşımı, az sayıda ağ kaynağının çok sayıda yöntem ve karmaşık bir protokolle kullanılmasına olanak tanıyor. REST yaklaşımıyla yöntemlerin sayısı ve protokol karmaşıklığı kesinlikle sınırlıdır, bu da bireysel kaynakların sayısının büyük olabileceği anlamına gelir." Yani bizimle ilgili olarak bu, sitedeki RPC yaklaşımı durumunda hizmete her zaman bir giriş (bağlantı) olacağı ve verilerle birlikte aktardığımız gelen verileri işlemek için hangi prosedürün çağrılacağı anlamına gelir. Sitemizde REST yaklaşımı ile her biri yalnızca belirli verileri kabul eden ve işleyen çok sayıda giriş (bağlantı) bulunmaktadır. Eğer okuyan biri bu yaklaşımların farkını daha basit bir şekilde nasıl açıklayacağını biliyorsa, yorumlara yazmayı unutmayın!

SOAP hakkında bilmemiz gereken bir sonraki şey, bu protokolün aktarımla aynı XML'i kullanmasıdır ki bu bir yandan çok iyidir, çünkü Cephaneliğimiz, sunucu tarafından alınan verilerin otomatik olarak doğrulanmasına olanak tanıyan, bir XML belgesinin yapısını açıklayan bir dil olan XML-Şema adlı bu işaretleme dilini temel alan bir teknoloji yığınının tam gücünü hemen içerir (teşekkürler Wikipedia!) müşterilerden.

Artık SOAP'ın uzaktan prosedür çağrılarını uygulamak için kullanılan bir protokol olduğunu ve aktarım olarak XML'i kullandığını biliyoruz! Wikipedia'daki makaleyi okursanız, oradan bunun yalnızca HTTP ile kombinasyon halinde değil, herhangi bir uygulama düzeyindeki protokol üzerinden kullanılabileceğini de öğrenebilirsiniz (maalesef bu konuda yalnızca HTTP üzerinden SOAP'ı ele alacağız). Ve tüm bunların en çok neyi hoşuma gidiyor biliyor musun? Tahmin yoksa bir ipucu vereceğim - SABUN!... Hala tahmin yok mu?... Wikipedia'daki makaleyi okuduğunuzdan emin misiniz?... Genel olarak size daha fazla işkence yapmayacağım. Bu nedenle doğrudan cevaba geçeceğim: “SOAP (İngilizce Basit Nesne Erişim Protokolünden - basit protokol nesnelere erişim; spesifikasyon 1.2'ye kadar)". Bu satırdaki en dikkat çekici şey italik yazılmış olmasıdır! Tüm bunlardan ne gibi sonuçlar çıkardığınızı bilmiyorum, ancak şunu görüyorum - bu protokol hiçbir şekilde "basit" olarak adlandırılamayacağından (ve görünüşe göre w3 bile buna katılıyor), o zaman 1.2 sürümünden itibaren şifresinin çözülmesi bir şekilde durduruldu. ! Ve SABUN olarak tanındı, sadece SABUN, nokta.

Tamam, lütfen kusura bakmayın, biraz dikkatim dağıldı. Daha önce de yazdığım gibi aktarım olarak XML kullanılıyor ve istemci ile sunucu arasında dolaşan paketlere SOAP zarfları adı veriliyor. Zarfın genel yapısını dikkate alırsanız size çok tanıdık gelecektir çünkü... HTML sayfasının yapısına benzer. Bir ana bölümü var - Zarf bölümleri içeren Başlık Ve Vücut, veya Arıza. İÇİNDE Vücut veri iletilir ve zarfın zorunlu bir bölümüdür. Başlıkİsteğe bağlı. İÇİNDE Başlık yetkilendirme veya web hizmeti prosedürlerinin giriş verileriyle doğrudan ilgili olmayan diğer veriler iletilebilir. Hakkında Arıza Herhangi bir hata durumunda sunucudan istemciye gelmesi dışında söylenecek özel bir şey yok.

SOAP protokolü hakkındaki inceleme hikayem burada bitiyor (istemcimiz ve sunucumuz nihayet onları birbirlerine çalıştırmayı öğrendiğinde zarfların kendilerine ve yapılarına daha ayrıntılı olarak bakacağız) ve yeni bir hikaye başlıyor - SOAP arkadaşı hakkında WSDL(Web Hizmetleri Açıklama Dili). Evet, evet çoğumuzu bu protokol üzerinde API'mizi uygulamaya çalışmaktan bile korkutan şey budur. Sonuç olarak taşıma aracı olarak JSON ile tekerleğimizi genellikle yeniden icat ediyoruz. Peki WSDL nedir? WSDL, XML dilini (c) Wikipedia'yı temel alarak web hizmetlerini tanımlayan ve bunlara erişen bir dildir. Eğer bu tanım size bu teknolojinin tüm kutsal anlamını açıklamıyorsa, o zaman onu kendi kelimelerimle anlatmaya çalışacağım!

WSDL, müşterilerimizin sunucuyla normal şekilde iletişim kurmasına olanak sağlayacak şekilde tasarlanmıştır. Bunun için “*.wsdl” uzantılı dosyada aşağıdaki bilgiler anlatılmaktadır:

  • Hangi ad alanları kullanıldı?
  • Hangi veri şemaları kullanıldı?
  • Web hizmeti istemcilerden ne tür mesajlar bekliyor?
  • Hangi verinin hangi web servis prosedürlerine ait olduğu,
  • Web hizmeti hangi prosedürleri içerir?
  • Müşteri web servis prosedürlerini nasıl çağırmalı,
  • Müşteri çağrıları hangi adrese gönderilmelidir?
Gördüğünüz gibi bu dosya tüm web hizmetidir. İstemcide WSDL dosyasının adresini belirterek herhangi bir web hizmeti hakkında her şeyi bileceğiz! Sonuç olarak, web hizmetinin nerede bulunduğu hakkında kesinlikle hiçbir şey bilmemize gerek yok. Bilmeniz gereken tek şey WSDL dosyasının konumu! Yakında SOAP'ın Rus atasözlerinde anlatıldığı kadar korkutucu olmadığını öğreneceğiz.

3 XML Şemasına Giriş

Artık SOAP'ın ne olduğu, içinde ne olduğu hakkında çok şey biliyoruz ve onu çevreleyen teknoloji yığınına dair genel bir bakışa sahibiz. Her şeyden önce SOAP, istemci ile sunucu arasındaki etkileşimin bir yöntemi olduğundan ve bunun için aktarım olarak XML işaretleme dili kullanıldığından, bu bölümde XML şemaları kullanılarak otomatik veri doğrulamanın nasıl gerçekleştiğini biraz anlayacağız.

Diyagramın ana görevi, işleyeceğimiz verilerin yapısını tanımlamaktır. XML şemalarındaki tüm veriler aşağıdakilere bölünmüştür: basit(skaler) ve karmaşık(yapılar) türleri. Basit türler aşağıdaki türleri içerir:

  • astar,
  • sayı,
  • Boole değeri,
  • Tarihi.
İçinde hiçbir uzantı olmayan çok basit bir şey. Antipodları karmaşık karmaşık türlerdir. Karmaşık türün herkesin aklına gelen en basit örneği nesnelerdir. Örneğin bir kitap. Kitap özelliklerden oluşur: yazar, İsim, fiyat, ISBN numarası vesaire. Ve bu özellikler sırasıyla basit türler veya karmaşık olanlar olabilir. XML şemasının görevi de bunu anlatmaktır.

Fazla ileri gitmemenizi ve SMS mesajımız için bir XML şeması yazmanızı öneririm! SMS mesajının xml açıklaması aşağıdadır:

71239876543 Deneme mesajı 2013-07-20T12:00:00 12
Karmaşık tip diyagramımız şöyle görünecek:


Bu girdi şu şekildedir: Bir değişkenimiz var " İleti" tip " İleti" ve " adında karmaşık bir tür var İleti" sıralı bir dizi öğeden oluşur " telefon" tip sicim, « metin" tip sicim, « tarih" tip tarihSaat, « tip" tip ondalık. Bu türler basittir ve şema açıklamasında zaten tanımlanmıştır. Tebrikler! Az önce ilk XML Şemamızı yazdık!

Bence elementlerin anlamı " eleman" Ve " karmaşık Tür"Her şey sizin için aşağı yukarı netleşti, bu yüzden artık bunlara odaklanmayacağız ve doğrudan besteci unsuruna geçelim" sekans" Besteci öğesini kullandığımızda " sekans“İçerdiği elemanların her zaman şemada belirtilen sırada yer alması gerektiğini ve hepsinin zorunlu olduğunu size bildiririz. Ama umutsuzluğa kapılmayın! XML şemalarında iki besteci öğesi daha vardır: " seçenek" Ve " Tümü" Besteci " seçenek"İçinde listelenen unsurlardan birinin ve bestecinin olması gerektiğini duyurur" Tümü» – listelenen öğelerin herhangi bir kombinasyonu.

Hatırlayacağınız gibi konunun ilk bölümünde bir pakette birden sonsuza kadar SMS mesajının iletilebileceği konusunda anlaşmıştık. Bu nedenle, bu tür verilerin XML şemasında nasıl bildirildiğini anlamayı öneriyorum. Genel paket yapısı şöyle görünebilir:

71239876543 Test mesajı 1 2013-07-20T12:00:00 12 71239876543 Test mesajı N 2013-07-20T12:00:00 12
Böyle karmaşık bir türün diyagramı şöyle görünecektir:


İlk blok, “karmaşık türün tanıdık bildirimini içerir” İleti" Fark ettiyseniz, " içinde yer alan her basit türde İleti", yeni açıklayıcı özellikler eklendi" dkOluşur" Ve " maxOccurs" Adından da tahmin edebileceğiniz gibi, ilk ( dkOluşur), bu dizinin " türünde en az bir öğe içermesi gerektiğini belirtir. telefon», « metin», « tarih" Ve " tip", bir sonraki ( maxOccurs) niteliği bize dizimizde böyle bir öğenin en fazla olduğunu bildirir. Sonuç olarak, herhangi bir veri için kendi şemalarımızı yazdığımızda, bunları nasıl yapılandıracağımız konusunda bize en geniş seçenek sunulur!

Diyagramın ikinci bloğu "öğesini bildirir" mesajListesi" tip " Mesaj Listesi" Şu açık ki" Mesaj Listesi"en az bir öğe içeren karmaşık bir türdür" İleti", ancak bu tür öğelerin maksimum sayısı sınırlı değildir!

4 WSDL'nizi yazın

WSDL'nin web hizmetimiz olduğunu hatırlıyor musunuz? Umarım hatırlarsın! Biz bunu yazarken küçük web servisimiz onun üzerinde çalışacaktır. Bu nedenle ortalığı karıştırmamanızı öneririm.

Genel olarak bizim için her şeyin doğru çalışması için istemciye doğru MIME türüne sahip bir WSDL dosyası aktarmamız gerekiyor. Bunun için web sunucunuzu buna göre yapılandırmanız yani “*.wsdl” uzantılı dosyalar için MIME tipini aşağıdaki satıra ayarlamanız gerekmektedir:

Uygulama/wsdl+xml
Ancak pratikte genellikle HTTP başlığını PHP aracılığıyla gönderdim " metin/xml»:

Header("Content-Type: text/xml; karakter kümesi=utf-8");
ve her şey harika çalıştı!

Basit web hizmetimizin oldukça etkileyici bir açıklamaya sahip olacağı konusunda sizi hemen uyarmak istiyorum, bu yüzden paniğe kapılmayın, çünkü... Metnin çoğu zorunlu sudur ve bir kez yazdıktan sonra onu bir web hizmetinden diğerine sürekli olarak kopyalayabilirsiniz!

WSDL XML olduğundan, bunu doğrudan ilk satıra yazmanız gerekir. Dosyanın kök öğesi her zaman " olarak adlandırılmalıdır tanımlar»:


Tipik olarak WSDL 4-5 ana bloktan oluşur. İlk blok bir web servisinin tanımı, diğer bir deyişle giriş noktasıdır.


Burada şöyle bir hizmetimiz olduğu yazıyor: " SMS Hizmeti" Prensip olarak, WSDL dosyasındaki tüm adlar sizin tarafınızdan istediğiniz şekilde değiştirilebilir, çünkü kesinlikle hiçbir rol oynamazlar.

Bundan sonra bunu web hizmetimizde duyuruyoruz " SMS Hizmeti" adında bir giriş noktası ("bağlantı noktası") var " SmsServicePort" İstemcilerden sunucuya gelen tüm istekler bu giriş noktasına gönderilecektir. Ve “ öğesinde belirtin adres» İstekleri kabul edecek işleyici dosyasına bağlantı.

Web hizmetini tanımladıktan ve onun için giriş noktasını belirledikten sonra, desteklenen prosedürleri buna bağlamamız gerekir:


Bunun için hangi işlemlerin hangi formda çağrılacağını listeler. Onlar. liman için" SmsServicePort"adın altında bir bağlama tanımlandı" SmsServiceBinding", bir çağrı türüne sahip" rpc"ve iletim protokolü olarak HTTP kullanılıyor. Böylece HTTP üzerinden RPC çağrısı yapacağımızı burada belirtmiş olduk. Bundan sonra hangi prosedürleri açıklayacağız ( operasyon) web hizmetinde desteklenir. Yalnızca tek bir prosedürü destekleyeceğiz – “ SMS gönder" Bu prosedür sayesinde harika mesajlarımız sunucuya gönderilecektir! İşlem ilan edildikten sonra verilerin hangi formda iletileceğinin belirtilmesi gerekmektedir. Bu durumda standart SOAP zarflarının kullanılacağı belirtiliyor.

Bundan sonra prosedürü mesajlara bağlamamız gerekiyor:


Bunu yapmak için bağlamamızın " türünde olduğunu belirtiyoruz. SmsServicePortType" ve öğenin içinde " bağlantı noktası türü"Aynı türdeki isimle prosedürlerin mesajlara bağlanmasını belirtiyoruz. Ve böylece, gelen mesaj (istemciden sunucuya) “ SmsTalebi gönder" ve giden (sunucudan istemciye) " SmsYanıt gönder" WSDL'deki tüm adlar gibi, gelen ve giden mesajların adları da isteğe bağlıdır.

Şimdi mesajların kendisini tanımlamamız gerekiyor; giren ve çıkan:


Bunu yapmak için öğeleri ekliyoruz " İleti"isimlerle" SmsTalebi gönder" Ve " SmsYanıt gönder" sırasıyla. Bunlarda girdinin, yapısı veri türüne karşılık gelen bir zarf olması gerektiğini belirtiyoruz " Rica etmek" Bundan sonra sunucudan veri türünü içeren bir zarf döndürülür - “ Cevap».

Şimdi biraz yapmamız gerekiyor; bu türlerin açıklamalarını WSDL dosyamıza ekleyin! Peki sizce WSDL gelen ve giden verileri nasıl tanımlıyor? Sanırım her şeyi uzun zaman önce anladınız ve bunu XML şemalarını kullanarak kendinize söylediniz! Ve kesinlikle haklı olacaksın!


Bizi tebrik edebilirsiniz! İlk WSDL'miz yazıldı! Ve hedefimize ulaşmaya bir adım daha yaklaştık.
Daha sonra, kendi dağıtılmış uygulamalarımızı geliştirmemiz için PHP'nin bize neler sağladığına bakacağız.

5 İlk SOAP sunucumuz

Daha önce PHP'de bir SOAP sunucusu oluşturmak için yerleşik SoapServer sınıfını kullanacağımızı yazmıştım. Diğer tüm eylemlerin benimkiyle aynı şekilde gerçekleşmesi için PHP'nizde biraz değişiklik yapmanız gerekecek. Daha da kesin olmak gerekirse, “php-soap” uzantısının kurulu olduğundan emin olmanız gerekir. Bunu web sunucunuza nasıl kuracağınızı resmi PHP web sitesinde okumak en iyisidir (referans listesine bakın).

Her şey yüklenip yapılandırıldıktan sonra hostinginizin kök klasöründe bir dosya oluşturmamız gerekecek " smsservice.php» aşağıdaki içeriğe sahip:

setClass("SoapSmsGateWay"); //Sunucuyu başlat $sunucu->tanımlayıcı();
Umarım çizginin üstünü “ini_set” fonksiyonu ile açıklamaya gerek yoktur. Çünkü orada sunucudan istemciye hangi HTTP başlıklarını göndereceğimiz belirlenir ve ortam yapılandırılır. “ini_set” doğrultusunda WSDL dosyasının önbelleğe alınmasını devre dışı bırakıyoruz, böylece dosyadaki değişikliklerimiz istemcide anında etkili olur.

Şimdi sunucuya geliyoruz! Gördüğünüz gibi SOAP sunucusunun tamamı yalnızca üç satır alıyor! İlk satırda SoapServer nesnesinin yeni bir örneğini oluşturuyoruz ve web hizmetinin WSDL açıklamamızın adresini yapıcısına aktarıyoruz. Artık hostingin kökünde açıklayıcı isimde bir dosyada yer alacağını biliyoruz. smsservice.wsdl.php" İkinci satırda SOAP sunucusuna istemciden gelen zarfın işlenip zarfın yanıtla birlikte geri dönmesi için hangi sınıfın çekilmesi gerektiğini söylüyoruz. Tahmin edebileceğiniz gibi, tek yöntemimiz bu sınıfta anlatılacak SMS gönder. Üçüncü satırda sunucuyu başlatıyoruz! İşte bu, sunucumuz hazır! Bununla hepimizi tebrik ediyorum!

Şimdi WSDL dosyasını oluşturmamız gerekiyor. Bunu yapmak için, önceki bölümden içeriğini kopyalayabilir veya özgürce davranıp biraz "şablon" oluşturabilirsiniz:

"; ?> /" 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" />
Bu aşamada ortaya çıkan sunucudan tamamen memnun olmalıyız çünkü Kendisine gelen zarfları kayıt altına alıp ardından gelen verileri sakin bir şekilde analiz edebiliyoruz. Sunucudan herhangi bir şey alabilmemiz için bir istemciye ihtiyacımız var. O halde hadi konuya geçelim!

6 SOAP istemcisi yolda

Öncelikle clienti yazacağımız bir dosya oluşturmamız gerekiyor. Her zamanki gibi, onu ana bilgisayarın kökünde oluşturacağız ve adını vereceğiz " client.php"ve içine şunları yazacağız:

mesajListesi = yeni MesajListesi(); $req->messageList->message = yeni Mesaj(); $req->messageList->message->telefon = "79871234567"; $req->messageList->message->text = "Mesaj 1'i test edin"; $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($client->sendSms($req));
Nesnelerimizi tanımlayalım. WSDL'yi yazdığımızda sunucuya gelen zarf için üç varlık tanımlıyordu: Rica etmek, Mesaj Listesi Ve İleti. Buna göre sınıflar Rica etmek, Mesaj Listesi Ve İleti bu varlıkların PHP betiğimizdeki yansımalarıdır.

Nesneleri tanımladıktan sonra bir nesne oluşturmamız gerekir ( $talep), sunucuya göndereceğiz. Bundan sonra bizim için en değerli iki satır geliyor! SABUN müşterimiz! İster inanın ister inanmayın, bu, sunucumuzun istemciden mesaj almaya başlaması ve sunucumuzun bunları başarıyla alıp işlemesi için yeterlidir! Bunlardan ilkinde SoapClient sınıfının bir örneğini oluşturup WSDL dosyasının konumunun adresini yapıcısına aktarıyoruz ve parametrelerde SOAP protokolü sürüm 1.2'yi kullanarak çalışacağımızı açıkça belirtiyoruz. Bir sonraki satırda yöntemi çağırıyoruz SMS gönder nesne $müşteri ve sonucu anında tarayıcıda görüntüleyin.
Hadi çalıştıralım ve sonunda ne elde ettiğimizi görelim!

Aşağıdaki nesne sunucudan bana döndürüldü:

Object(stdClass) public "status" => boolean true
Ve bu harika, çünkü... Artık sunucumuzun çalıştığından ve yalnızca çalışmakla kalmayıp aynı zamanda istemciye bazı değerleri de döndürebildiğinden eminiz!

Şimdi sunucu tarafında ihtiyatlı bir şekilde tuttuğumuz loga bakalım! İlk bölümünde sunucuya gelen ham verileri görüyoruz:

79871234567 Test mesajı 1 2013-07-21T15:00:00.26 15
Bu zarf. Artık neye benzediğini biliyorsun! Ancak ona her zaman bakmakla ilgilenmemiz pek olası değil, bu yüzden nesneyi günlük dosyasından seri durumdan çıkaralım ve her şeyin yolunda olup olmadığına bakalım:

Object(stdClass) public "messageList" => object(stdClass) public "mesaj" => object(stdClass) public "telefon" => string "79871234567" (uzunluk=11) public "text" => string "Test mesajı 1 " (uzunluk=37) public "date" => string "2013-07-21T15:00:00.26" (uzunluk=22) public "type" => string "15" (uzunluk=2)
Gördüğünüz gibi nesne doğru bir şekilde seri durumdan çıkarıldı ve bunun için hepimizi tebrik etmek istiyorum! Bundan sonra bizi daha ilginç bir şey bekliyor! Yani, istemciye sunucuya yalnızca bir SMS mesajı değil, bütün bir paket (daha kesin olmak gerekirse üç) göndereceğiz!

7 Karmaşık nesneleri gönderme

Bir sürü mesajı sunucuya tek bir pakette nasıl aktarabileceğimizi düşünelim mi? Muhtemelen en kolay yol, messageList öğesinin içinde bir dizi düzenlemek olacaktır! Bunu yapalım:

// sunucuya gönderilecek bir nesne oluşturun $req = new request(); $req->messageList = new MesajListesi(); $msg1 = yeni Mesaj(); $msg1->telefon = "79871234567"; $msg1->text = "Mesaj 1'i test edin"; $msg1->tarih = "2013-07-21T15:00:00.26"; $msg1->tür = 15; $msg2 = yeni Mesaj(); $msg2->telefon = "79871234567"; $msg2->text = "Mesaj 2'yi test edin"; $msg2->tarih = "2014-08-22T16:01:10"; $msg2->tür = 16; $msg3 = yeni Mesaj(); $msg3->telefon = "79871234567"; $msg3->text = "Mesaj 3'ü test edin"; $msg3->tarih = "2014-08-22T16:01:10"; $msg3->tür = 17; $req->messageList->mesaj = $msg1; $req->messageList->mesaj = $msg2; $req->messageList->mesaj = $msg3;
Günlüklerimiz istemciden aşağıdaki paketin alındığını gösteriyor:

79871234567 Test mesajı 1 2013-07-21T15:00:00.26 15 79871234567 Test mesajı 2 2014-08-22T16:01:10 16 79871234567 Test mesajı 3 2014-08-22T16:01:10 17
Ne saçmalık dedin? Ve bir bakıma haklı olacaksın, çünkü... Bir nesnenin istemciden çıktığını öğrendiğimizde, sunucumuza tamamen aynı biçimde, bir zarf şeklinde geldi. Doğru, SMS mesajları XML'de ihtiyacımız olan şekilde serileştirilmedi - öğelere sarılmaları gerekiyordu İleti, değil Yapı. Şimdi böyle bir nesnenin yönteme hangi biçimde geldiğini görelim. SMS gönder:

Object(stdClass) public "messageList" => object(stdClass) public "mesaj" => object(stdClass) public "Struct" => dizi (size=3) 0 => object(stdClass) public "phone" => string "79871234567" (uzunluk=11) public "text" => string "Test mesajı 1" (uzunluk=37) public "tarih" => string "2013-07-21T15:00:00.26" (uzunluk=22) public " type" => string "15" (uzunluk=2) 1 => object(stdClass) public "phone" => string "79871234567" (uzunluk=11) public "text" => string "Test mesajı 2" (uzunluk= 37) public "date" => string "2014-08-22T16:01:10" (uzunluk=19) public "type" => string "16" (uzunluk=2) 2 => object(stdClass) public "phone " => string "79871234567" (uzunluk=11) public "text" => string "Test mesajı 3" (uzunluk=37) public "tarih" => string "2014-08-22T16:01:10" (uzunluk= 19) public "type" => string "17" (uzunluk=2)
Bu bilgi bize ne veriyor? Sadece seçtiğimiz yol doğru değil ve “Sunucuda doğru veri yapısını nasıl elde edebiliriz?” sorusuna cevap alamadık. Ancak umutsuzluğa kapılmamanızı ve dizimizi türe dönüştürmeyi denemenizi öneririm. bir obje:

$req->messageList->message = (object)$req->messageList->message;
Bu durumda başka bir zarf alacağız:

79871234567 Test mesajı 1 2013-07-21T15:00:00.26 15 79871234567 Test mesajı 2 2014-08-22T16:01:10 16 79871234567 Test mesajı 3 2014-08-22T16:01:10 17
Yöntemin içine girdi SMS gönder nesne aşağıdaki yapıya sahiptir:

Object(stdClass) public "messageList" => object(stdClass) public "mesaj" => object(stdClass) public "BOGUS" => array (size=3) 0 => object(stdClass) public "phone" => string "79871234567" (uzunluk=11) public "text" => string "Test mesajı 1" (uzunluk=37) public "tarih" => string "2013-07-21T15:00:00.26" (uzunluk=22) public " type" => string "15" (uzunluk=2) 1 => object(stdClass) public "phone" => string "79871234567" (uzunluk=11) public "text" => string "Test mesajı 2" (uzunluk= 37) public "date" => string "2014-08-22T16:01:10" (uzunluk=19) public "type" => string "16" (uzunluk=2) 2 => object(stdClass) public "phone " => string "79871234567" (uzunluk=11) public "text" => string "Test mesajı 3" (uzunluk=37) public "tarih" => string "2014-08-22T16:01:10" (uzunluk= 19) public "type" => string "17" (uzunluk=2)
Bana göre “terimlerin yerleri değiştirildiğinde toplam değişmez” (c). Ne SAHTE, Ne Yapı– Henüz hedefimize ulaşamadık! Ve bunu başarmak için, bu anlaşılmaz isimlerin yerine yerli ismimizin görüntülendiğinden emin olmalıyız. İleti. Ancak yazar bunu nasıl başaracağını henüz bilmiyor. Bu nedenle yapabileceğimiz tek şey fazla kaptan kurtulmak. Başka bir deyişle, artık bunun yerine şundan emin olacağız: İleti oldu SAHTE! Bunu yapmak için nesneyi aşağıdaki gibi değiştirin:

// sunucuya gönderilecek bir nesne oluşturun $req = new request(); $msg1 = yeni Mesaj(); $msg1->telefon = "79871234567"; $msg1->text = "Mesaj 1'i test edin"; $msg1->tarih = "2013-07-21T15:00:00.26"; $msg1->tür = 15; $msg2 = yeni Mesaj(); $msg2->telefon = "79871234567"; $msg2->text = "Mesaj 2'yi test edin"; $msg2->tarih = "2014-08-22T16:01:10"; $msg2->tür = 16; $msg3 = yeni Mesaj(); $msg3->telefon = "79871234567"; $msg3->text = "Mesaj 3'ü test edin"; $msg3->tarih = "2014-08-22T16:01:10"; $msg3->tür = 17; $req->messageList = $msg1; $req->messageList = $msg2; $req->messageList = $msg3; $req->messageList = (object)$req->messageList;
Ya şansımız yaver giderse ve şemadan doğru isim çıkarsa? Bunu yapmak için gelen zarfa bakalım:

79871234567 Test mesajı 1 2013-07-21T15:00:00.26 15 79871234567 Test mesajı 2 2014-08-22T16:01:10 16 79871234567 Test mesajı 3 2014-08-22T16:01:10 17
Evet bir mucize gerçekleşmedi! SAHTE– kazanamayacağız! E geldi SMS gönder bu durumda nesne şöyle görünecek:

Object(stdClass) public "messageList" => object(stdClass) public "BOGUS" => dizi (boyut=3) 0 => object(stdClass) public "phone" => string "79871234567" (uzunluk=11) public " text" => string "Test mesajı 1" (uzunluk=37) public "tarih" => string "2013-07-21T15:00:00.26" (uzunluk=22) public "type" => string "15" (uzunluk) =2) 1 => object(stdClass) public "phone" => string "79871234567" (uzunluk=11) public "text" => string "Test mesajı 2" (uzunluk=37) public "tarih" => string " 2014-08-22T16:01:10" (uzunluk=19) public "type" => string "16" (uzunluk=2) 2 => object(stdClass) public "phone" => string "79871234567" (uzunluk= 11) public "text" => string "Test mesajı 3" (uzunluk=37) public "tarih" => string "2014-08-22T16:01:10" (uzunluk=19) public "type" => string " 17" (uzunluk=2)
Dedikleri gibi – “Neredeyse”! Bu (biraz üzücü) not üzerine, yavaş yavaş işleri toparlamayı ve kendimiz için bazı sonuçlar çıkarmayı öneriyorum.

8 Sonuç

Sonunda buraya geldik! Şimdi ne yapabileceğinizi bulalım:
  • web hizmetiniz için gerekli WSDL dosyasını yazabilirsiniz;
  • sunucu ile SOAP aracılığıyla iletişim kurabilen kendi istemcinizi kolayca yazabilirsiniz;
  • SOAP aracılığıyla dış dünyayla iletişim kuran kendi sunucunuzu yazabilirsiniz;
  • istemcinizden sunucuya aynı türdeki nesnelerin dizilerini gönderebilirsiniz (bazı kısıtlamalarla).
Küçük araştırmamız sırasında bazı keşifler de yaptık:
  • yerel SoapClient sınıfı, XML'de aynı türdeki veri yapılarını doğru şekilde serileştirmez;
  • bir diziyi XML'e serileştirirken, adı verilen ekstra bir öğe oluşturur. Yapı;
  • bir nesneyi XML'e serileştirirken, adı verilen ekstra bir öğe oluşturur. SAHTE;
  • SAHTE olduğundan daha az kötü Yapı zarfın daha kompakt olması nedeniyle (zarfın XML başlığına fazladan ad alanları eklenmez);
  • Ne yazık ki SoapServer sınıfı, zarf verilerini XML şemamızla otomatik olarak doğrulamaz (belki diğer sunucular da bunu yapmaz).

Brett McLaughlin Tercümesi: Ilya Chekmenev

SOAP Basit Nesne Erişim Protokolüdür. Eğer bunu daha önce hiç duymadıysanız, medeniyetten uzakta, hiçliğin ortasında yaşıyor olmalısınız. Web programlamada son moda haline geldi ve son nesil web geliştirmelerinde büyük bir fanatizmle kullanılan web hizmetlerinin ayrılmaz bir parçası haline geldi. Microsoft'un .NET'ini veya eşler arası "devrimi" duyduysanız, SOAP'a dayanan teknolojileri de duymuşsunuzdur (ne olduğunu bilmeseniz bile). Öyle biri yok ama iki Apache ve Microsoft'un MSDN destek sitelerinde (http://msdn.microsoft.com/) kendilerine ayrılmış binlerce sayfa bulunan SOAP uygulamaları.

Bu yazıda size SOAP'ın ne olduğunu ve web programlama paradigmasının gelişiminde neden bu kadar önemli bir parçası olduğunu anlatacağım. Bu, temelleri atlamanıza ve doğrudan SOAP araç seti ile çalışmaya başlamanıza yardımcı olacaktır. Daha sonra mevcut SOAP projelerine hızlı bir genel bakış sunacağım ve Apache'nin uygulanmasına dalacağım. Bu makalenin amacı SOAP'ın tam bir resmini sunmak değildir; Java ve XML, 2. Baskı adlı kitabım birçok boşluğu doldurmaktadır. Bu makaleyi okuduktan sonra aklınıza gelen birçok sorunun cevabını kitapta bulacaksınız.

giriiş

Öncelikle SABUN'un ne olduğunu anlamalısınız. W3C görüşünün tamamını (ve oldukça uzun) http://www.w3.org/TR/SOAP adresinden okuyabilirsiniz. Daha sonra bunu anlayıp tüm kabuğu attığınızda, SOAP'ın sadece bir protokol olduğunu anlayacaksınız. Dağıtılmış mimarinin bir noktasında bilgi alışverişine ihtiyaç duyulduğu fikrine dayanan basit bir protokoldür (kullanmak için yeni bir tane yazmaya gerek yoktur). Ayrıca aşırı yüklenme ve işlem süreçlerinde zorluk yaşanma ihtimali olan sistemler için bu protokol, hafif olması ve minimum miktarda kaynak gerektirmesi açısından oldukça avantajlıdır. Son olarak, tüm işlemlerin HTTP üzerinden gerçekleştirilmesine olanak tanır, bu da güvenlik duvarları gibi aldatıcı şeyleri atlamanıza ve inanılmaz sayıda bağlantı noktası üzerindeki soketleri kullanarak kendinizi dinlemeye karşı korumanıza olanak tanır. Önemli olan bunun farkına varmanızdır ve geri kalan her şey detaydır.

Elbette bu detayları bilmek istersiniz, ben de bunları göz ardı etmeyeceğim. SOAP spesifikasyonunun üç temel bileşeni vardır: bir SOAP zarfı, bir dizi şifreleme kuralı ve istek ile yanıt arasındaki etkileşim aracı. SOAP mesajını normal bir mektup gibi düşünelim. Önünde posta pulu ve adresi yazan zarfların içindeki o eski şeyleri hâlâ hatırlıyor musun? Bu benzetme, SABUN kavramını bir "zarf" olarak daha net anlamanıza yardımcı olacaktır. Şekil 12-1, bu benzetme biçiminde SOAP süreçlerini göstermektedir.

Şekil 12-1. SOAP Mesaj Süreci

Bu resmi aklımızda tutun ve SOAP spesifikasyonunun üç bileşenine bakalım. Her birinden kısaca bahsedeceğim, kavramı en iyi temsil eden örnekler vereceğim. Bu üç temel bileşen SOAP'u çok önemli ve anlamlı kılmaktadır. Hata işleme, çeşitli şifreleme desteği, parametre serileştirme ve SOAP'ın çoğu durumda HTTP üzerinden çalışması, onu dağıtılmış protokoller için diğer çözümlerden daha çekici kılmaktadır. SOAP, kitabımda daha ayrıntılı olarak ele aldığım diğer uygulamalarla yüksek derecede birlikte çalışabilirlik sağlar. Şimdilik SOAP'ın temel unsurlarına odaklanmak istiyorum.

Mektup

SOAP zarfı normal mektup zarfına benzer. Alıcı ve gönderen hakkında bilgilerin yanı sıra mesajın kendisi hakkında bilgiler de dahil olmak üzere ana SOAP bölümünde şifrelenecek mesajla ilgili bilgileri içerir. Örneğin, SOAP zarf başlığı mesajın nasıl işlenmesi gerektiğini belirtebilir. Bir uygulama bir mesajı işlemeye başlamadan önce, mesajı işleyip işleyemeyeceği de dahil olmak üzere mesajla ilgili bilgileri inceler. Standart XML-RPC çağrılarındaki durumun aksine (hatırladınız mı? XML-RPC mesajları, şifreleme vb., her şey tek bir XML parçasında birleştirilir), SOAP'ta mesaj hakkında bir şeyler öğrenmek için devam eden işlem gerçekleşir. Tipik bir SOAP mesajı, alıcının mesajı işlemesine yardımcı olacak bir şifreleme stili de içerebilir. Örnek 12-1, bir kodlama spesifikasyonuyla biten bir SOAP zarfını göstermektedir.

Örnek 12-1: SABUN Zarfı

Sabun kutusu http://www-106.ibm.com/developerworks/library/x-soapbx1.html

Gördüğünüz gibi, şifreleme zarfın içinde ayarlanmıştır, bu da uygulamanın belirlemesine olanak tanır (öznitelik değerini kullanarak) kodlama stili), öğede bulunan gelen mesajı okuyup okuyamayacağı Vücut. SOAP zarf ad alanının doğru olduğundan emin olun, aksi takdirde mesajınızı alan SOAP sunucuları sürüm uyuşmazlığı hatası bildirecek ve onlarla iletişim kuramayacaksınız.

Şifreleme

SOAP'ın ikinci önemli unsuru, özel veri türlerini şifreleme yeteneğidir. RPC (ve XML-RPC) ile şifreleme yalnızca indirdiğiniz XML-RPC araç setinde desteklenen önceden tanımlanmış veri türlerinde gerçekleştirilebilir. Diğer veri türlerinin şifrelenmesi, RPC sunucusunu ve istemcisini kendinizin değiştirmenizi gerektirir. SOAP ile, yeni veri türlerini belirlemek için bir XML şeması oldukça kolay bir şekilde kullanılabilir (yapıyı kullanarak) karmaşık Tür, kitabımın 2. Bölümünde ele alınmıştır) ve bu yeni türler XML'de SOAP'ın ana bölümünün bir parçası olarak temsil edilebilir. XML Şeması entegrasyonu sayesinde, SOAP mesajındaki her türlü veriyi XML Şeması içerisinde mantıksal olarak tanımlayarak şifreleyebilirsiniz.

Arama

Bir SOAP çağrısının nasıl çalıştığını anlamanın en iyi yolu, onu XML-RPC gibi aşina olduğunuz bir şeyle karşılaştırmaktır. Hatırlarsanız XML-RPC çağrısı Örnek 12-2'de sunulan kod parçacığına benzer.

Örnek 12-2. XML-RPC'ye çağrı

// XmlRpc.setDriver("org.apache.xerces.parsers.SAXParser"); kullanılacak XML işlemcisini (ayrıştırıcı) belirtme // Bağlantının kurulduğu sunucuyu belirtme XmlRpcClient client = new XmlRpcClient("http://rpc.middleearth.com"); // Parametre oluşturma Vector parametreleri = new Vector(); params.addElement(flightNumber); params.addElement(numSeats); params.addElement(creditCardType); params.addElement(creditCardNum); // Boolean isteği satın alınanTickets = (Boolean)client.execute("ticketCounter.buyTickets", params); // Yanıtı işle

Uçak bileti siparişi vermek için basit bir program oluşturdum. Şimdi SOAP çağrısını gösteren Örnek 12-3'e bakın.

Örnek 12-3. SOAP'a çağrı

// Parametre oluşturma Vector parametreleri = new Vector(); params.addElement(new Parameter("flightNumber", Integer.class, uçuşNumber, null)); params.addElement(new Parameter("numSeats", Integer.class, numSeats, null)); params.addElement(new Parameter("creditCardType", String.class, CreditCardType, null)); params.addElement(new Parameter("creditCardNumber", Long.class, CreditCardNum, null)); // Bir Çağrı nesnesi oluşturma Call call = new Call(); call.setTargetObjectURI("urn:xmltoday-airline-tickets"); call.setMethodName("buyTickets"); call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); call.setParams(params); // Çağrı Yanıtı res = call.invoke(new URL("http://rpc.middleearth.com"), ""); // Yanıtı işle

Gördüğünüz gibi nesnenin temsil ettiği gerçek çağrı Arama, hafıza sakini. Bu örnekte sunulmayan çağrı hedefini, çağrı yöntemini, şifreleme stilini, parametreleri ve diğer birçok parametreyi belirtmenize olanak tanır. Bu, XML-RPC yönteminden daha esnek bir mekanizmadır ve XML-RPC'de örtülü olarak tanımlanan bir dizi farklı parametreyi açıkça belirtmenize olanak tanır. Bu makalenin ilerleyen kısımlarında, SOAP'ın geçersiz istekleri nasıl ele aldığı, hata hiyerarşisi ve elbette döndürülen çağrı sonuçları da dahil olmak üzere çağrı süreci hakkında daha fazla bilgi edineceksiniz.

Bu kadar kısa bir girişten sonra zaten bu komik şeyle ilgilenecek kadar bilginiz var. Şimdi size kullanacağım SOAP uygulamasını tanıtmama izin verin. Bunu seçmemin nedenlerini açıklayacağım ve bazı kod örneklerine bakacağım.

Ayarlar

Artık kavramın temellerini öğrendiğinize göre sıra eğlenceli kısma geldi: programlama. Bunu yapmak için, bulunması ilk bakışta göründüğünden daha kolay olan uygun bir projeye veya ürüne ihtiyacınız olacak. SOAP yetenekleri sağlayan bir Java projesine ihtiyacınız varsa, bulmak için uzun süre aramanıza gerek yok. Ticari ve ücretsiz olmak üzere iki ürün grubu bulunmaktadır. Kitabımda olduğu gibi ticari ürünlerden bahsetmekten kaçınacağım. Bunun nedeni kesinlikle kötü olmaları değil (aksine, bazıları mükemmel), ancak herhangi bir okuyucunun verilen örneklerden herhangi birini deneyebilmesini istediğim için. Bunun nedeni, birçok ticari ürünün sahip olmadığı erişilebilirliktir. Bunları kullanmak için ödeme yapmanız veya indirdikten sonra sınırlı bir süre için geçici olarak kullanmanız gerekir.

Böylece açık kaynaklı projelere sorunsuz bir şekilde yaklaştık. Bu alandan yalnızca bir ürünün adını verebilirim: Apache SOAP. http://xml.Apache.org/soap adresinde bulunur ve Java için SOAP araç seti sağlar. Yazma sırasında Apache web sitesinden indirebileceğiniz 2.2 sürümü yayınlandı. Bu makalenin örneklerinde kullanacağım sürüm budur.

Diğer Alternatifler

Apache SOAP kurulumu ve yapılandırmasına geçmeden önce aklınıza gelmiş olabilecek birkaç soruyu yanıtlayacağım. Ticari ürünleri kullanmamamın nedenlerini gayet net bir şekilde anlattığımı düşünüyorum. Ancak, kullanmak isteyebileceğiniz başka açık kaynak veya ilgili projeleri düşünüyor olabilirsiniz ve onlar hakkında yorum yapmadığıma şaşırmış olabilirsiniz.

Peki ya IBM SOAP4J?

Alternatifler listesinin ilk sırasında IBM'in bir uygulaması var: SOAP4J. IBM'in çalışması, Apache SOAP projesinin temelini oluşturdu; tıpkı IBM'in XML4J'sinin artık Apache Xerces XML ayrıştırıcı projesi olarak bilinen projeye dönüşmesi gibi. IBM uygulamasının Apache SOAP ile birleştirilerek yeniden tasarlanacağı varsayılmaktadır. IBM'in XML4J'sinde de hemen hemen aynı şey oldu: artık yalnızca Xerces'te paketleme sağlıyor. Bu yalnızca eğilimleri vurguluyor - büyük üreticiler genellikle Açık Kaynak projelerini destekliyor ve kullanıyor, bu durumda her iki proje de (Apache ve IBM) aynı kod tabanını kullanıyor.

Microsoft oyunun dışında mı?

Tabii ki hayır. Microsoft ve SOAP uygulamasının yanı sıra tüm .NET hareketi (kitabımda daha ayrıntılı olarak ele alınmıştır) oldukça önemlidir. Gerçekten zamanımın çoğunu Microsoft'un SOAP uygulamasını ayrıntılı olarak inceleyerek geçirmek istedim, ancak bu yalnızca COM nesnelerini destekliyor ve Java'yı desteklemiyor. Bu nedenlerden dolayı Java ve XML ile ilgili bir makalede böyle bir açıklamaya yer verilemez. Ancak Microsoft (geliştirici olarak bizlerin bu şirketle ilgili tüm şikayetlerine rağmen) web hizmetleri alanında önemli çalışmalar yaptı ve bunu düşünmeden, yalnızca ham duyguların rehberliğinde reddederseniz hata yaparsınız. COM veya Visual Basic bileşenleriyle çalışmanız gerekiyorsa, http://msdn.microsoft.com/library/default.asp?url=/nhp/Default adresinde bulunan Microsoft SOAP araç setini kullanmayı denemenizi önemle tavsiye ederim. .asp ?contentid=28000523 diğer birçok SOAP kaynağıyla birlikte.

Eksen nedir?

Apache aktivitelerini takip edenler Apache Axis'i mutlaka duymuşlardır. Axis, Apache XML şemsiyesi altında geliştirilen yeni nesil bir SOAP araç setidir. Son zamanlarda hızla ve radikal bir şekilde gelişen SOAP'ın (belirli bir uygulama değil, bir spesifikasyon) takip edilmesi oldukça zordur. Gelişen mevcut gereksinimleri tam olarak karşılayan bir SOAP sürümü oluşturmaya çalışmak da oldukça zordur. Sonuç olarak Apache SOAP'ın mevcut sürümü tasarımıyla sınırlı bir çözüm sunmaktadır. Mevcut aracı tamamen yeniden tasarlamanın gereksiz olduğuna karar veren Apache geliştiricileri, yeni koda dayalı bir proje oluşturmaya başladı. Böylece Axis doğdu. SOAP'ın adı da önce SOAP'tan XP'ye, sonra da XMLP'ye değişti. Daha sonra yeni SOAP'ın adından spesifikasyon adı çıkarıldı ve "Axis" adı doğdu. Ancak şimdi W3C, SOAP spesifikasyonunun ismine (sürüm 1.2 veya 2.0) geri dönüyor gibi görünüyor, dolayısıyla işler hala değişebilir ve daha da fazla kafa karışıklığı yaşanabilir!

IBM SOAP4J'yi SOAP araç setinin bir mimarisi?1 olarak düşünün. Mimari olarak Apache SOAP'a (bu makalede ele alınmıştır) ne dersiniz?2. Axis ise yeni nesil mimari olan ?3 mimarisini temsil ediyor. Bu proje SAX kullanırken Apache SOAP DOM tabanlıdır. Ayrıca Axis, Apache SOAP'tan farklı olarak kullanıcı etkileşimine daha kullanıcı dostu bir yaklaşım sunar. Bu avantajları sıraladıktan sonra neden Axis'i çalışma alanım olarak seçmediğimi merak ediyor olabilirsiniz. Sadece biraz erken olurdu. Şu anda Axis'in yalnızca 0.51 sürümü yayına hazırlanıyor. Bu henüz bir beta değil, hatta bir alfa sürümü bile değil. Yeni Axis özellikleri hakkında konuşmayı çok isterdim, ancak yönetiminizi, kritik sistem ihtiyaçlarınız için alfa altı açık kaynak yazılımı kullanabileceğinize ikna etme şansınız olmaz. Bu yüzden senin gerçek olduğun bir şeye odaklanmaya karar verdim kullanabilirsinizçoktan Bugün- Apache SABUN. Apache Axis'in son sürümü yayınlandığında bu materyali kitabımın bir sonraki baskısında güncelleyeceğimi düşünüyorum. O zamana kadar halihazırda mevcut olan çözüme odaklanalım.

Kurulum

SOAP kurulumunun iki olası şekli vardır. Birincisi, SOAP mesajlarını kabul edebilen bir sunucuyla iletişim kurmak için SOAP API'sini kullanarak bir SOAP istemcisi başlatmaktır. İkinci yol ise SOAP istemcisinden mesaj alabilen bir SOAP sunucusu çalıştırmaktır. Bu bölümde her iki işlemi de anlattım.

Müşteri

SOAP istemcisini kullanmak için öncelikle http://xml.apache.org/dist/soap adresinde bulunan Apache SOAP'ı indirmeniz gerekir. Sürüm 2.2'yi ikili formatta indirdim (alt dizinden) sürüm-2.2). Daha sonra arşiv içeriğini bilgisayarınızdaki bir dizine açmalısınız. Benim durumumda bu dizindi javaxml2 (c:\javaxml2 Windows bilgisayarımda /javaxml2 Mac OS X bilgisayarımda). Sonuç olarak dosyalar açıldı /javaxml2/soap-2_2. Ayrıca Sun http://java.sun.com/products/javamail/ adresinde bulunan JavaMail paketini de indirmeniz gerekecektir. Apache SOAP tarafından kullanılan SMTP aktarım protokolünün desteklenmesi gerekecektir. Daha sonra yine Sun http://java.sun.com/products/beans/glasgow/jaf.html adresinden edinebileceğiniz Java Beans Etkinleştirme Çerçevesini (JAF) indirin. Zaten Xerces'in veya başka bir XML ayrıştırıcısının kurulu ve kullanıma hazır olduğu varsayımına dayanmaktadır.

Not: XML ayrıştırıcınızın JAXP uyumlu olduğundan ve ad alanını doğru şekilde kullandığından emin olun. Ayrıştırıcınız büyük olasılıkla bu gereksinimleri karşılıyor. Sorun yaşıyorsanız Xerces'i kullanmaya geri dönmek en iyisidir.

Not: Xerces'in en son sürümlerini kullanın. Sürüm 1.4 ve üzeri işinizi görecektir. SOAP ve Xerces 1.3(.1)'de çok sayıda hata var, bu nedenle bu kombinasyonu kullanmamanızı tavsiye ediyorum.

JavaMail ve JAF paketlerini açın ve ardından jar dosyalarını kitaplığın yanı sıra sınıf yolunuza ekleyin sabun.kavanoz. Bu jar dosyalarının her biri ilgili programın kök dizininde veya bir alt dizinde bulunmalıdır. /lib. Değişkeniniz bittiğinde sınıf yoluşöyle görünmeli:

$ echo $CLASSPATH /javaxml2/soap-2_2/lib/soap.jar:/javaxml2/lib/xerces.jar: /javaxml2/javamail-1.2/mail.jar:/javaxml2/jaf-1.0.1/activation.jar

Windows için şöyle görünecek:

c:\>echo %CLASSPATH% c:\javaxml2\soap-2_2\lib\soap.jar;c:\javaxml2\lib\xerces.jar; c:\javaxml2\javamail-1.2\mail.jar;c:\javaxml2\jaf-1.0.1\activation.jar

Ve son olarak dizini ekleyin javaxml2/soap-2_2/ senin içinde sınıf yolu SOAP örneklerini çalıştırmak için. Bu bölümde birkaç örnek için kurulumu anlattım.

Sunucu

SOAP uyumlu bir sunucu bileşenleri kümesi oluşturmak için öncelikle bir servlet motoruna ihtiyacınız vardır. Önceki bölümlerde olduğu gibi bu bölümde de örnek olarak Apache Tomcat'i (http://jakarta.apache.org/ adresinde mevcuttur) kullandım. Müşterinin ihtiyaç duyduğu her şeyi eklemeniz gerekecek sınıf yolu sunucu. Bunu yapmanın en kolay yolu sıfırlamaktır sabun.kavanoz, aktivasyon.jar Ve posta.jar, ayrıştırıcınızın yanı sıra servlet motorunuzun kütüphaneler dizinine. Tomcat için bu, otomatik yüklemeye yönelik kitaplıkları içeren /lib dizinidir. Betikler için destek sağlamak istiyorsanız (bunlar bu bölümde ele alınmamıştır ancak Apache SOAP örneklerinde yer almaktadır), bsf.jar(http://oss.software.ibm.com/developerworks/projects/bsf adresinde bulunabilir) ve js.jar(http://www.mozilla.org/rhino/ adresinde mevcuttur) aynı dizine kopyalayın.

Not: Xerces'i Tomcat ile kullanıyorsanız Bölüm 10'da ele aldığım hileyi tekrarlamanız gerekecektir. ayrıştırıcı.jar V z_parser.jar, A jaxp.jar V z_jaxp.jar emin olmak için xerces.jar ve JAXP'nin dahil edilen sürümü, diğer herhangi bir ayrıştırıcı veya JAXP uygulamasından önce yüklenir.

Ardından servlet motorunuzu yeniden başlatın, ardından SOAP sunucu bileşenlerini yazmaya hazırsınız.

Yönlendirici Servlet ve Yönetici İstemcisi

Apache SOAP, temel işlemlerin yanı sıra bir yönetici istemcisinin yanı sıra bir yönlendirici sunucu uygulamasını da içerir. Kullanmayı düşünmüyorsanız bile SOAP'ın doğru kurulduğunu test etmek için kurmanızı öneririm. Bu işlem hangi servlet motorunu kullandığınıza bağlı olduğundan kurulum işlemini Tomcat ile sınırlandıracağım. Diğer bazı servlet motorları için kurulum talimatları http://xml.Apache.org/soap/docs/index.html adresinde bulunabilir.

Tomcat altında kurulum çok basittir: sadece dosyayı alın sabun.savaş rehberden sabun-2_2/webapps ve dizine bırakın $TOMCAT_HOME/webapps- ve bu kadar! Kurulumu kontrol etmek için adresi tarayıcınıza girin http://localhost:8080/soap/servlet/rpcrouter. Şekil 12-2'de gösterilene benzer bir yanıt almalısınız.

Şekil 12-2. Yönlendirici RPC Sunucu Uygulaması

Mesaj bir hata mesajı gibi görünse de her şeyin düzgün çalıştığını gösterir. Tarayıcınızı yöneticinin istemci adresine yönlendirirseniz aynı yanıtı almalısınız: http://localhost:8080/soap/servlet/messagerouter.

Sunucu ve istemciyi test etmeyi tamamlamak için tüm talimatları tamamen uyguladığınızdan emin olun. Ardından, RPC yönlendirici sunucu uygulamasına ilişkin sunucu uygulaması URL'nizi desteklemek için aşağıdaki Java sınıfını aşağıda gösterildiği gibi çalıştırın:

C:\>Java org.Apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter list Dağıtılan Hizmetler:

Yukarıda gösterildiği gibi boş bir hizmet listesi almalısınız. Herhangi bir mesaj alırsanız lütfen http://xml.Apache.org/soap/docs/trouble/index.html adresinde bulunan olası hataların uzun listesini inceleyin. Bu, karşılaşabileceğiniz sorunların en kapsamlı listesidir. Boş bir liste alırsanız bu, kurulumun tamamlandığı ve bu bölümde verilen örneklere bakmaya hazır olduğunuz anlamına gelir.

Başlayalım

Herhangi bir SOAP tabanlı sistem yazmanın üç ana aşaması vardır. Bunları listeledikten sonra her birini kısaca tartışacağım:

  • SOAP-RPC ve SOAP mesajları arasında seçim yapma;
  • Bir SOAP hizmetine yazma veya erişim kazanma;
  • Bir SOAP istemcisine yazma veya erişme.

İlk adım, SOAP'ı RPC çağrıları (sunucuda uzaktan bir prosedürün yürütüldüğü) veya mesajlar (istemcinin sunucuya yalnızca bilgi parçaları gönderdiği) için mi kullanacağınızı seçmektir. Bu süreçleri aşağıda detaylı olarak ele alacağım. Bu kararı verdikten sonra kendi hizmetinize erişmeniz veya kendi hizmetinizi oluşturmanız gerekecektir. Elbette hepimiz Java uzmanı olduğumuz için bu bölümde kendinizinkini nasıl oluşturacağınız anlatılmaktadır. Ve son olarak bu hizmet için bir client yazmanız gerekiyor, hepsi bu!

RPC mi, Mesajlaşma mı?

İlk görevinizin programlamayla hiçbir ilgisi yoktur ve daha çok tasarım niteliğindedir. RPC'yi mi yoksa mesaj servisini mi kullanacağınızı seçmeniz gerekiyor. RPC'ye aşina olduğunuzu varsayacağız (örneğin kitabımın bölümlerinden birini okuyarak). İstemci, sunucuda uzaktan bir prosedür yürütür ve ardından bir yanıt alır. Bu senaryoda SOAP, ağ üzerinden daha iyi hata yönetimi ve karmaşık veri türlerinin aktarımını sağlayan gelişmiş bir XML-RPC sistemi görevi görür. Bu kavrama zaten aşinasınız ve RPC sistemlerini SOAP'ta yazmak daha kolay olduğundan onlarla başlayacağım. Bu makalede, bir RPC hizmetinin, bir RPC istemcisinin nasıl oluşturulacağı ve sistemin nasıl devreye sokulacağı açıklanmaktadır.

SOAP'ı çalıştırmanın başka bir yolu da mesaj alışverişine dayanmaktadır. Uzaktan prosedürler gerçekleştirmek yerine yalnızca bilgi alışverişi için kullanılır. Tahmin edebileceğiniz gibi bu, istemcinin herhangi bir sunucunun bireysel yöntemlerini bilmesini gerektirmeyen güçlü bir araçtır. Ayrıca veri paketlerinin (ağ anlamında değil mecazi anlamda paketler) diğer sistemlere gönderilmesine izin vererek uzak sistemlerin modellenmesini daha izole hale getirir. Aynı zamanda diğer sistemlerin bu verilerle yapılan işlemleri bilmesine gerek yoktur. Bu stil, RPC programlamadan daha karmaşık olduğundan burada açıklamayacağım. Bunu, işletmeler arası etkileşimin diğer ayrıntılarıyla birlikte kitabımda bulacaksınız. Öncelikle SOAP-RPC programlamayla tanışın.

Çoğu tasarım probleminde olduğu gibi bu kararı vermek de size bağlıdır. Uygulamanızı analiz edin ve neden SOAP kullanmanız gerektiğini belirlemeye çalışın. İsteğe bağlı olarak belirli iş işlevlerini gerçekleştiren bir sunucunuz ve bir dizi istemciniz varsa, RPC sizin için daha uygundur. Veri alışverişinin talep üzerine belirli iş işlevlerini yerine getirmekten daha fazlası olduğu karmaşık sistemlerde, SOAP mesajlarının kullanılması daha çok tercih edilir.

RPC hizmeti

Artık formaliteler bittiğine göre harekete geçme zamanı geldi. Bildiğiniz gibi RPC'de yöntemleri uzaktan yürütülecek sınıflara ihtiyacınız olacak.

Kod parçacıkları

Sunucuya ilişkin bazı kod parçacıklarına bakarak başlayacağım. Bu parçalar, RPC istemcileri için yürütülen yöntemlerin bulunduğu sınıflardır. Örnek olarak kitabımdaki kodu kullandım. Basit sınıflar kullanmak yerine SOAP'ın yeteneklerini olabildiğince açık bir şekilde göstermek için daha karmaşık bir örnek seçtim. Bu yüzden örnek olarak CD sınıfını kullandım. İlk önce elemanı tanımlıyoruz harita standart olmayan her parametre türü için. Özellik için kodlama stili, en azından Apache SOAP 2.2'de. http://schemas.xmlsoap.org/soap/encoding/ değerini sağlamanız gerekir. Bu şu anda desteklenen tek kodlamadır. Kullanıcı tanımlı tür için ad alanını ve ardından bu tür için ad alanı önekiyle birlikte sınıf adını belirtmeniz gerekir. Bizim durumumuzda bu amaçlar için hayali bir ad alanı ve basit bir önek kullandım " X". Ardından özelliği kullanarak javaType, Java sınıfının gerçek adını ayarlayın (bu durum için - javaxml2.CD). Ve son olarak niteliklerle kuralesil java2XMLSınıfAdı Ve xml2JavaClassName. Onların yardımıyla, Java'dan XML'e (veya tam tersi) dönüştürülen bir sınıf belirlenir. Apache SOAP'ın içerdiği inanılmaz derecede kullanışlı BeanSerializer sınıfını kullandım. Özel parametreniz JavaBean formatındaysa, bu seri hale getirici ve seri durumdan çıkarıcı, sizi kendi parametrenizi yazma zorunluluğundan kurtaracaktır. Varsayılan kurucuya sahip bir sınıfa ihtiyacınız var (CD sınıfı için basit, parametresiz bir kurucu tanımladığımı unutmayın) ve bu sınıfın tüm verilerini yöntemleri kullanarak yayınlamanız gerekir. setXXX Ve getXXX. Çünkü sınıf CD tüm bu gereksinimleri mükemmel bir şekilde karşılar, Fasulye Serileştirici mükemmel çalışıyor.

Not: Hangi sınıf CDŞartları yerine getiriyor Fasulye Serileştirici. pek önemli değil. Çoğu sınıf kolayca bu formata dönüştürülür. Bu nedenle, kendi seri hale getiricilerinizi ve seri durumdan çıkarıcılarınızı yazmaktan kaçınmanızı tavsiye ederim. Bu ekstra bir baş ağrısıdır (karmaşık bir şey değildir, ancak çok zahmetlidir) ve enerjinizi korumanızı ve özel parametrelerinizde fasulye dönüşümünü kullanmanızı öneririm. Çoğu durumda, fasulye dönüşümleri sınıfınızda yalnızca varsayılan bir kurucu gerektirir (parametre yok).

Şimdi yeniden yaratalım kavanoz hizmetimizi dosyalayın ve yeniden yükleyin:

(gandalf)/javaxml2/Ch12$ java org.Apache.soap.server.ServiceManagerClient http://localhost:8080/soap/servlet/rpcrouter xml/CDCatalogDD.xml

Dikkat: Sunucu uygulaması motorunuzu çalışır halde bırakırsanız ve aynı anda bir hizmeti yeniden barındırırsanız, SOAP hizmeti için yeni sınıfları etkinleştirmek ve hizmeti yeniden barındırmak için servlet motorunu yeniden başlatmanız gerekecektir.

Artık geriye kalan tek şey istemciyi yeni sınıfları ve yöntemleri kullanacak şekilde değiştirmektir. Örnek 12-10, istemci sınıfının değiştirilmiş bir versiyonunu içerir CDAder. Önceki sürümde yapılan değişiklikler vurgulanır.

Örnek 12-10: Güncellenmiş CDAdder sınıfı

paket javaxml2; Java.net.URL'yi içe aktarın; Java.util.Vector'ı içe aktarın; org.apache.soap.Constants'ı içe aktar; org.Apache.soap.Fault'u içe aktar; org.Apache.soap.SOAPException'ı içe aktar; org.Apache.soap.encoding.SOAPMappingRegistry'yi içe aktarın; org.Apache.soap.encoding.soapenc.BeanSerializer'ı içe aktarın; org.apache.soap.rpc.Call'ı içe aktar; org.Apache.soap.rpc.Parameter'ı içe aktar; org.Apache.soap.rpc.Response'u içe aktar; org.Apache.soap.util.xml.QName'i içe aktarın; genel sınıf CDAdder( public void add(URL URL'si, Dize başlığı, Dize sanatçısı, Dize etiketi) SOAPException'ı ( System.out.println("Başlığı "" + başlık + "" sanatçı "" + sanatçı + "" stüdyo " + etiket olan bir CD ekleniyor); CD cd = yeni CD(başlık, sanatçı, etiket); // Bir çağrı nesnesi oluşturun Call Call call = new Call(); call.setSOAPMappingRegistry(kayıt defteri); call.setTargetObjectURI("urn:cd-catalog"); call.setMethodName("addCD"); call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); // Parametrelerin ayarlanması Vektör parametreleri = new Vector(); params.addElement(new Parameter("cd", CD.class, cd, null)); call.setParams(params); // Çağrı Yanıt yanıtının işlenmesi; yanıt = call.invoke(url, ""); if (!response.geneatedFault()) ( System.out.println("CD ekleme başarıyla tamamlandı."); ) else ( Arıza hatası = Response.getFault(); System.out.println(Hata: " + error.getFaultString ()); )) public static void main(String args) ( if (args.length != 4) ( System.out.println("Template: java javaxml2.CDAdder " + "\"[CD Başlığı]\" \"[Sanatçı Adı]\ " \"[Stüdyo CD'si]\""); dönüş; ) try ( // Bağlantının yapıldığı SOAP sunucusunun URL'si URL url = new URL(args); // Yeni CD Dizisi başlığının değerlerini al = args; Dize sanatçısı = args; Dize etiketi = bağımsız değişkenler; // CD CDAdder'ı ekleyin toplayıcı = new CDAdder(); adder.add(url, başlık, sanatçı, etiket); ) catch (Exception e) ( e.printStackTrace(); )) ))

Gerçekten ilginç olan tek değişiklik sınıf haritalamasındadır CD:

// Bu türü SOAP SOAPMappingRegistry ile kullanılabilecek şekilde eşleyin kayıt defteri = new SOAPMappingRegistry(); BeanSerializer serileştirici = yeni BeanSerializer(); kayıt defteri.mapTypes(Constants.NS_URI_SOAP_ENC, new QName("urn:cd-catalog-demo", "cd")), CD.class, serileştirici, serileştirici);

Bir kullanıcı parametresi bu şekilde kodlanabilir ve ağ üzerinden iletilebilir. Sınıfın nasıl olduğunu sana daha önce söylemiştim. Fasulye Serileştirici sınıf gibi JavaBean formatındaki parametreleri işlemek için kullanılabilir CD. Bunları sunucuya belirtmek için bir yerleştirme tanımlayıcısı kullandım, ancak şimdi istemciye bu seri hale getiriciyi ve seri durumdan çıkarıcıyı kullanmasını söylemem gerekiyor. Bu işlev sınıf tarafından gerçekleştirilir SOAP Eşleme Kayıt Defteri. Yöntem harita Türleri()şifrelenmiş dizeyi alır (yine bunun için bir sabit kullanmak daha iyidir) NS_URI_SOAP_ENC) ve özel serileştirmenin kullanılması gereken parametre türü hakkında bilgi. İlk olarak QName belirtilir. Barındırma tanımlayıcısında garip ad alanının kullanılmasının nedeni budur. Burada aynı URN'yi, öğenin yerel adını (bu örnek için "CD") ve ardından Java nesnesini sağlamanız gerekir. Sınıf serileştirilecek sınıf ( CD.sınıfı) ve son olarak serileştirme ve seri durumdan çıkarma için sınıfın bir örneği. Bu örnek için, her iki durum da bir örneği içerecektir Fasulye Serileştirici. Tüm bu ayarlar kayıt defterine girildikten sonra nesneye bildirimde bulunun. Arama yöntemi kullanarak setSOAPMapping-Registry().

Bu sınıfı daha önce gösterildiği gibi bir CD ekleyerek çalıştırabilirsiniz; her şey beklendiği gibi çalışmalıdır:

C:\javaxml2\build>java javaxml2.CDAdder http://localhost:8080/soap/servlet/rpcrouter "Tony Rice" "Manzanita" "Şeker Tepesi" Sugar Hill'in "Manzanita" adlı eserinden "Tony Rice" adlı bir CD ekleniyor Bir CD başarıyla eklendi.

Sınıf değişikliğinden ayrıldım CD Listesi senin için. Her şey aynı şablona göre üretiliyor. Kendinizi test etmek için kitabımın halihazırda bu güncellenmiş sınıfları içeren örnek dosyalarına başvurabilirsiniz.

Not: Buna karar verebilirsiniz çünkü sınıf CD Listesi nesneyle doğrudan etkileşime girmez CD(yöntemle döndürüldü liste() tip önemlidir Karma tablo), o zaman herhangi bir değişiklik yapmanıza gerek yoktur. Ancak geri dönen sınıf Karma tablo nesne örneklerini içerir CD. SOAP bunların nasıl seri durumdan çıkarılacağını bilmiyorsa, istemci bir hata verecektir. Bu durumda sorunu çözmek için nesnede belirtmeniz gerekir. Arama kopyala SOAP Eşleme Kayıt Defteri.

Verimli hata yönetimi

Artık özel nesneleri gördüğünüze ve RPC çağrıları yaptığınıza göre, daha az heyecan verici bir konu hakkında konuşayım: hata yönetimi. Herhangi bir ağ işleminde birçok arıza meydana gelebilir. Hizmet başlamıyor, sunucuda bir hata var, bir nesne bulunamıyor, sınıflar eksik ve daha birçok sorun var. Şu ana kadar sadece yöntemi kullandım arıza.getString() hata mesajları oluşturmak için. Fakat bu yöntem her zaman faydalı olmayabilir. Bunu çalışırken görmek için yapıcının yorumunu kaldırın CD Kataloğu:

genel CDCatalog() ( //katalog = yeni Hashtable(); // Bir dizin oluşturun addCD(new CD("Nickel Creek", "Nickel Creek", "Sugar Hill")); addCD(yeni CD("Bırak Düşsün", "Sean Watkins", "Şeker Tepesi")); addCD(yeni CD("Hava Sınırları", "Michael Hedges", "Windham Hill")); addCD(yeni CD("Taproot", "Michael Hedges", "Windham Hill")); )

Yeniden derleyin, servlet motorunu yeniden başlatın ve yeniden barındırın. Bu bir istisnayla sonuçlanacaktır NullPointerException sınıf kurucusu başlatılmamış dosyaya CD eklemeye çalıştığında Karma tablo. İstemciyi başlatırken bir hata mesajı görünecektir, ancak bu çok bilgilendirici olmayacaktır:

(gandalf)/javaxml2/build$ java javaxml2.CDLister http://localhost:8080/soap/servlet/rpcrouter Geçerli CD dizinini görüntüleyin. Hata: Hedef nesne çözülemiyor: null

Bu, bir hatanın tanımlanmasına ve düzeltilmesine yardımcı olabilecek hiçbir bilgi değildir. Bununla birlikte, çerçeve hata işlemeyle düzgün bir şekilde başa çıkıyor. Hatırlıyor musun DOMFaultListeneröğenin değeri olarak belirttiğiniz hata Dinleyici? Onun oyuna girme zamanı geldi. Hata durumunda döndürülen nesne Arıza DOM'yi (Belge Nesne Modeli) içerir org.w3c.dom.Element hata hakkında ayrıntılı bilgi içerir. Öncelikle kaynak kodunuza bir içe aktarma ifadesi ekleyin java.util.Iterator:

Java.net.URL'yi içe aktarın; Java.util.Enumeration'ı içe aktarın; Java.util.Hashtable'ı içe aktarın; Java.util.Iterator'ı içe aktarın; Java.util.Vector'ı içe aktarın; org.apache.soap.Constants'ı içe aktar; org.Apache.soap.Fault'u içe aktar; org.Apache.soap.SOAPException'ı içe aktar; org.Apache.soap.encoding.SOAPMappingRegistry'yi içe aktarın; org.Apache.soap.encoding.soapenc.BeanSerializer'ı içe aktarın; org.apache.soap.rpc.Call'ı içe aktar; org.Apache.soap.rpc.Parameter'ı içe aktar; org.Apache.soap.rpc.Response'u içe aktar; org.Apache.soap.util.xml.QName'i içe aktarın;

Şimdi list() yöntemindeki hataları ele almak için değişiklikler yapalım:

if (!response.geneatedFault()) ( Parametre returnValue = Response.getReturnValue(); Hashtable katalog = (Hashtable)returnValue.getValue(); Sayım e = katalog.keys(); while (e.hasMoreElements()) ( String title = (String)e.nextElement(); CD cd = (CD)catalog.get(title); System.out.println(" "" + cd.getTitle() + "" artist " + cd.getArtist() + " studios " + cd.getLabel()); ) ) else ( Arıza arızası = Response.getFault(); System.out.println("Hata: " + arıza.getFaultString()); Vektör girişleri = error.getDetailEntries(); for (Iterator i = entry.iterator(); i.hasNext();) ( org.w3c.dom.Element entry = (org.w3c.dom.Element)i.next(); System.out.println(entry) .getFirstChild().getNodeValue()); ) )

Yöntemi kullanma getDetailEntries() SOAP hizmetine ve sorunu destekleyen ham veri sunucusuna erişebilirsiniz. Kod bunları yeniden işler (genellikle tek bir öğe vardır, ancak bu çok dikkat gerektirir) ve DOM'u keser. Öğe, her girişte bulunur. Temel olarak, üzerinde çalıştığınız XML şu şekildedir:

SOAP-ENV:Server.BadTargetObjectURI Hedef çözülemiyor: null İşte istediğimiz bu!

Başka bir deyişle Fault nesnesi, SOAP zarfının hatalar içeren kısmına erişmenizi sağlar. Ayrıca Apache SOAP, hatalar oluştuğunda bir Java yığın izlemesi sağlayarak bunları düzeltmek için gereken ayrıntılı bilgileri sağlar. Bir öğenin ele geçirilmesi yığın izleme ve düğüm değerinin yazdırılması Metin bu öğeden istemciniz sunucu yığın izini yazdırabilir. Bu değişiklikleri derleyip istemciyi yeniden başlattığınızda aşağıdaki sonucu elde edersiniz:

C:\javaxml2\build>java javaxml2.CDLister http://localhost:8080/soap/servlet/rpcr external Geçerli CD dizinini görüntüleyin. Hata: Hedef çözülemiyor: javaxml2.CDCatalog'daki javaxml2.CDCatalog.addCD(CDCatalog.java:24) içindeki null Java.lang.NullPointerException. (CDCatalog.java:14) java.lang.Class.newInstance0(Yerel Yöntem) içinde java.lang.Class.newInstance(Class.java:237) içinde

Çok daha iyi değil ama en azından bir istisnanın meydana geldiğine dair bazı küçük bilgileri görebilirsiniz NullPointerException hatta bu sorunun oluştuğu sunucu sınıflarındaki satır numaralarını bile öğrenebilirsiniz. Bu son değişikliklerin sonucu size hata işleme sorununun net bir resmini verdi. Artık sunucu sınıflarınızı hatalara karşı kontrol etmelisiniz. Evet, neredeyse unutuyordum, ondan önce sınıfınızı geri almayı unutmayın CD Kataloğu netlik sağlamak için kasıtlı olarak ortaya koyduğumuz hatalardan kurtulmak için!

  1. SOAP'ın SMTP (hatta Jabber) gibi diğer protokoller üzerinden çalıştırılmasıyla ilgili çok fazla konuşma var. SOAP standardı şu anda bunu sağlamamaktadır ancak gelecekte benzer yetenekler eklenebilir. Bu nedenle bu konuyla ilgili aktif tartışmalarla karşılaşırsanız şaşırmayın.

Ne olduğu sorusu üzerinde durmayacağım Ağ hizmetleri ve bunlara neden ihtiyaç duyulduğu. İnternette bu konuyla ilgili birçok makale var. PHP'de herhangi bir web hizmeti için istemci oluşturmanın ne kadar basit olduğunu kısaca göstermeye çalışacağım.

Ayarlar

Kullanmak için SABUN php'de SOAP modülünü (php5 dağıtımına dahil) bağlamanız gerekir. Windows altında, bu basit bir şekilde yapılır - eklemeniz gerekir (yani ekleyin, çünkü bu satır sadece orada yorumlanmamıştır, tamamen eksiktir). php.ini:
uzantı=php_soap.dll

Modül olarak php yüklediyseniz sunucuyu yeniden başlatmayı unutmayın.


WSDL belgesinden SOAP istemcisi oluşturma

Bir SOAP istemcisi oluşturmak genellikle şu şekilde gerçekleşir: WSDL belgesi, belirli bir web hizmetini tam olarak açıklayan, belirli bir formattaki bir XML belgesidir. WSDL ile ilgili ayrıntılar için sizi W3C konsorsiyumunun web sitesine yönlendiriyorum - http://www.w3.org/TR/2005/WD-wsdl20-soap11-binding-20050510/.

Bir web hizmeti için istemci oluşturmak amacıyla bilmeniz gereken en önemli şey, WSDL belgesinin URL'sini bilmektir.
Örneğin xmethods.com'dan "Döviz Kurları" web hizmetini ele alalım. Çevrimiçi döviz kurları almanızı sağlayan bu web hizmetinin adresi http://www.xmethods.net/sd/2001/CurrencyExchangeService.wsdl'dir.

İkinci önemli nokta, web hizmetinin açıklamasından, bu hizmetin hangi yöntemleri sağladığı ve ona girdi değerleri olarak hangi parametreleri aktarmamız gerektiği hakkında bilgi edinmenin gerekli olmasıdır (normal bir PHP işlevini veya sınıfını çağırmaya çok benzer) yöntem). Genellikle bu bilgi web sitesindeki hizmetin açıklamasında bulunur. Döviz kurlarını elde etmeye yönelik web hizmetimiz, para birimi kodlarının argüman olarak iletildiği getRate() yöntemini sağlar.

Ve son olarak, yanıt olarak ne bekleyeceğinizi bilmek önemlidir: kaç değer, hangi tür vb. Bu aynı zamanda açıklamadan da elde edilebilir.
Sonuç olarak, kodun çok basit ve derli toplu, neredeyse basit olduğu ortaya çıkıyor:

// Web hizmetini kullanma
// xmethods.com'dan "Döviz Kuru"

// WSDL belgesinden SOAP istemcisi oluşturma
$client = new SoapClient("http://www.xmethods.net/sd/2001/CurrencyExchangeService.wsdl");

// SOAP isteği gönder ve sonucu al
$sonuç = $client->getRate("bize", "rusya");

Echo 'Geçerli dolar döviz kuru: ', $sonuç, ' ruble';
?>

Koddan da görebileceğiniz gibi WSDL belgesinin URL'sini SoapClient sınıfı yapıcısına iletmeniz ve istediğiniz web hizmetiyle çalışacak bir nesne almanız gerekiyor. Daha sonra bu nesnenin adı web hizmeti yönteminin adıyla aynı olan bir yöntem çağrılır. Bu yöntem istediğimiz sonucu döndürür.

Bu basit örnek, PHP'de web hizmetleri için bir SOAP istemcisi oluşturma ilkesini göstermektedir. Ancak gerçek bir uygulamada hala dikkat edilmesi gereken çok şey vardır; özellikle de web hizmeti çağrıldığında geçici olarak kullanılamayabilir veya bir hata verebilir. Açıkça bir blok kullanılmasını önerir dene/yakala/at :)

(PHP 5 >= 5.0.1)

SoapClient::SoapClient — SoapClient yapıcısı

Parametreler

wsdl

URI'si WSDL dosya veya HÜKÜMSÜZ eğer çalışıyorsan WSDL olmayan modu.

Geliştirme sırasında WSDL önbelleğe alma, aşağıdakilerin kullanılmasıyla devre dışı bırakılabilir: sabun.wsdl_cache_ttl php.ini ayarı aksi halde WSDL dosyasında yapılan değişikliklerin şu ana kadar hiçbir etkisi olmayacaktır: sabun.wsdl_cache_ttl süresi doldu.

seçenekler

Bir dizi seçenek. WSDL modunda çalışıyorsanız bu parametre isteğe bağlıdır. WSDL olmayan modda çalışıyorsanız, konum Ve uri seçenekler ayarlanmalıdır, burada konum isteğin gönderileceği SOAP sunucusunun URL'sidir ve uri SOAP hizmetinin hedef ad alanıdır.

stil Ve kullanmak seçenekler yalnızca WSDL olmayan modda çalışır. WSDL modunda bunlar WSDL dosyasından gelir.

sabun_versiyonu seçeneği SOAP 1.1 (varsayılan) veya SOAP 1.2 istemcisinin kullanılıp kullanılmayacağını belirtir.

HTTP kimlik doğrulaması için, giriş yapmak Ve şifre Kimlik bilgilerini sağlamak için seçenekler kullanılabilir. Proxy sunucusu aracılığıyla HTTP bağlantısı kurmak için seçenekler Vekalet sahibi, proxy_port, proxy_login Ve proxy_password ayrıca mevcuttur. HTTPS istemci sertifikası kimlik doğrulama kullanımı için yerel_sertifika Ve parola seçenekler. Bir kimlik doğrulaması şu şekilde sağlanabilir: kimlik doğrulama seçenek. Kimlik doğrulama yöntemi şunlardan biri olabilir: SOAP_AUTHENTICATION_BASIC(varsayılan) veya SOAP_AUTHENTICATION_DIGEST.

sıkıştırma seçeneği, HTTP SOAP isteklerinin ve yanıtlarının sıkıştırılmasının kullanılmasına izin verir.

kodlama seçeneği dahili karakter kodlamasını tanımlar. Bu seçenek SOAP isteklerinin kodlamasını değiştirmez (her zaman utf-8'dir), ancak dizeleri buna dönüştürür.

iz seçeneği, arızaların geriye doğru izlenebilmesi için talebin izlenmesini sağlar. Bu varsayılan olarak YANLIŞ

sınıf haritası seçeneği bazı WSDL türlerini PHP sınıflarıyla eşlemek için kullanılabilir. Bu seçenek, anahtar olarak WSDL türlerinin ve değer olarak PHP sınıflarının adlarının bulunduğu bir dizi olmalıdır.

Boole değerini ayarlama iz seçeneği SoapClient->__getLastRequest , SoapClient->__getLastRequestHeaders , SoapClient->__getLastResponse ve SoapClient->__getLastResponseHeaders yöntemlerinin kullanılmasını sağlar.

istisnalar seçenek, sabun hatalarının SoapFault türünde istisnalar atıp atmadığını tanımlayan bir boole değeridir.

Bağlantı zamanaşımı seçeneği, SOAP hizmetine bağlantı için saniye cinsinden bir zaman aşımı tanımlar. Bu seçenek, yavaş yanıt veren hizmetler için bir zaman aşımı tanımlamaz. Aramaların bitmesi için beklenecek süreyi sınırlamak için default_socket_timeout ayarı mevcuttur.

yazı haritası seçenek bir tür eşleme dizisidir. Tür eşleme, anahtarları olan bir dizidir tür_adı, type_ns(ad alanı URI'si), from_xml(bir dize parametresini kabul eden geri arama) ve to_xml(bir nesne parametresini kabul eden geri arama).

önbellek_wsdl seçenek bunlardan biridir WSDL_CACHE_NONE, WSDL_CACHE_DISK, WSDL_CACHE_MEMORY veya WSDL_CACHE_BOTH.

kullanıcı_agent seçenek kullanılacak dizeyi belirtir Kullanıcı Aracısı başlık.

akış_bağlamı seçenek bir bağlam içindir.

özellikler seçenek bir bit maskesidir SOAP_SINGLE_ELEMENT_ARRAYS, SOAP_USE_XSI_ARRAY_TYPE, SOAP_WAIT_ONE_WAY_CALLS.

hayatta kal seçenek, mesajın gönderilip gönderilmeyeceğini tanımlayan bir boole değeridir. Bağlantı: Canlı Tut başlık veya Bağlantı: kapat .

Değişiklik günlüğü

Sürüm Tanım
5.4.0 Yeni hayatta kal seçenek.

Örnekler

Örnek 1 SoapClient::SoapClient() örnek

$client = new SoapClient("bazı.wsdl");

$client = new SoapClient ("some.wsdl", array("soap_version" => SOAP_1_2 ));

$client = new SoapClient ("some.wsdl", array("login" => "some_name",
"password" => "some_password" ));

$client = new SoapClient ("some.wsdl", array("proxy_host" => "localhost",
"proxy_port" => 8080));

$client = new SoapClient ("some.wsdl", array("proxy_host" => "localhost",
"proxy_port" => 8080,
"proxy_login" => "bazı_adlar",
"proxy_password" => "some_password" ));

$client = new SoapClient ("some.wsdl", array("local_cert" => "cert_key.pem" ));

$client = new SoapClient (null , array("konum" =>
"uri" => "http://test-uri/" ));

$client = new SoapClient (null , array("location" => "http://localhost/soap.php",
"uri" => "http://test-uri/",
"stil" => SOAP_DOCUMENT,
"kullan" => SOAP_LITERAL ));

$client = new SoapClient("bazı.wsdl",
array("sıkıştırma" => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP ));

$sunucu = new SoapClient ("some.wsdl", array("encoding" => "ISO-8859-1" ));

sınıf MyBook(
genel $başlık ;
genel $yazar ;
}

$sunucu = new SoapClient ("books.wsdl", array("classmap" => array("book" => "MyBook" ));

?>

Chris Gunawardena

Bir unix sunucusuna gelen ve giden SOAP çağrılarını izlemek için:

Sudo tcpdump -nn -vv -A -s 0 -i eth0 dst veya src ana bilgisayarı xxx.xxx.xxx.xxx ve bağlantı noktası 80

Ve her zaman "cache_wsdl" => WSDL_CACHE_NONE kullanın

selfhtml nokta org şirketinde svenr

"Classmap" seçeneği aslında SOAP içinde kullanılan "ComplexType"tan PHP Sınıflarınıza bir eşlemedir.

İsteğiniz için döndürülen XML etiketi adlarını bu ComplexTypes ile karıştırmayın. SOAP onların farklı olmalarını sağlar.

Şöyle bir şeyim vardı:
...


FooBar

TagName, sınıf haritanıza koymak istediğiniz anahtar değildir; bu TagName'in ifade ettiği ComplexType'ın adını bilmeniz gerekir. Bu bilgi WSDL kaynağının içinde bulunur.

gmail dot com'da paulovitorbal

Sertifikaları kullanırken "local_cert" parametresinde dosyanın adını değil, dosya içeriğini kullanın.

New sabunclient("http://localhost/index.php?wsdl ", array("local_cert"=>file_get_contents("./key.pem"),"passphrase"=>"password"));

PHP'de sınıf haritanızda kullandığınız sınıflarda tanımlanmış özel özelliklere sahip olabilirsiniz. Dolayısıyla, sınıfınızda özel bir $foo özelliği oluşturursanız ve SOAP öğesinin bir alt öğesi varsa $foo içeriği, içeriğine göre ayarlanacaktır. . Bu şekilde sınıflarınızdaki özelliklere erişimi kontrol edebilirsiniz.

(Not: Bu, Facebook'un HPHP'sinde çalışmaz).

willem dot stuursma ve hyves dot nl

Sınıf haritanızda farklı bir ad alanındaki sınıfları kullanmak istiyorsanız hedef sınıf adında ters eğik çizgiyi kullanmanız yeterlidir.

Örnek:
$classmap = array("result" => "MyNamespace\\Result" );
?>

Ters eğik çizgiyi iki kez belirtmeniz gerekir çünkü bu, dizelerdeki kaçış karakteridir.

gmx dot ch şirketinde Simonlang

Proxy üzerinden HTTP kimlik doğrulamasına sahip bir sabun istemcisi örneği:

yeni SoapClient(
"service.wsdl",
sıralamak(
// Geliştirmeye yönelik şeyler.
"iz" => 1,
"istisnalar" => true,
"cache_wsdl" => WSDL_CACHE_NONE,
"özellikler" => SOAP_SINGLE_ELEMENT_ARRAYS,

// SOAP isteği için kimlik doğrulama bilgileri.
"giriş" => "kullanıcı adı",
"şifre" => "şifre",

// Proxy URL'si.
"proxy_host" => "example.com", // Şemayı buraya eklemeyin (http veya https). İşe yaramayacak.
"proxy_port" => 44300,

// Proxy için kimlik doğrulama bilgileri.
"proxy_login" => BOŞ,
"proxy_password" => BOŞ,
);
?>
Uzak sunucudaki (aynı zamanda HTTP kimlik doğrulamasıyla korunan) bir WSDL dosyasına URL sağlamak işe yaramadı.WSDL'yi indirdim ve yerel sunucuda sakladım.

Asaf Meller

Tam çalışan bir php .net sabun yapılandırması:
notlar
1. .net sunucusundaki web.config, temel http bağlamayla çalışmalıdır.
2. sabun fonksiyonlarına parametreler şu şekilde iletilmelidir:
array("parm1_name"=>"parm1_value",
"parm2_name"=>"parm2_value"...)

başlık("İçerik Türü: metin/düz");

Denemek (
$seçenekler = dizi(
"soap_version" => SOAP_1_1,
"istisnalar" => true,
"iz" => 1,
"cache_wsdl" => WSDL_CACHE_NONE
);
$istemci = yeni SoapClient ( "http://www.example.com/end_point.wsdl", $seçenekler);

) catch (İstisna $e ) (
Eko "

İstisna Hatası!

" ;
echo $e -> getMessage();
}

Echo "HelloWorld'ü çalıştırıyor:" ;

Denemek (
$yanıt = $istemci -> MerhabaDünya();

}
yakala (İstisna $e)
{
echo "İstisna yakalandı: " , $e -> getMessage (), "\n" ;
}

Print_r($yanıt);
?>
iyi şanslar!
Asaf.

faebu nokta ch'de faebu

Temel http kimlik doğrulamasıyla korunan bir WDSL dosyasını yüklemeye çalışırken aynı sorunları yaşıyorum, çünkü oturum açma adı ve parola parametreleri yalnızca istek için kullanılıyor ancak wdsl dosyasını okurken kullanılmaz. İndirerek aşağıdaki geçici çözümü kullanıyorum. xml dosyasını sunucumdaki korunmayan bir konuma kopyaladım. Lütfen bunun herhangi bir tür önbelleğe almayı desteklemediğini unutmayın.

SoapAuthClient sınıfı SoapClient'i genişletir (
/**
* PHP SOAP paketi temel kimlik doğrulamayı desteklemediğinden
* bu sınıf cURL paketini kullanarak WDSL dosyasını indirir ve
* sunucunuzda wdsl'nin yerel bir kopyasını oluşturur.
*Aşağıdaki ek parametreyi girdiğinizden emin olun:
* $optionsArray:
* wdsl_local_copy => doğru
*/

Özel $cache_dir = "/home/example/htdocs/cache/" ;
özel $cache_url = "http://www.example.com/cache/";

Function SoapAuthClient ($wdsl, $seçenekler) (
if (isset($options [ "wdsl_local_copy" ]) &&
$options [ "wdsl_local_copy" ] == doğru &&
isset($options [ "giriş" ]) &&
isset($seçenekler [ "şifre" ])) (

$dosya = md5(uniqid()). ".xml" ;

If (($fp = fopen ($this -> önbellek_dizini . $dosya , "w" )) == false ) (
yeni İstisna oluştur ( "Yerel WDSL dosyası oluşturulamadı (". $this -> önbellek_dir . $dosya. ")" );
}

$ch = curl_init();
$kredi = ($seçenekler["giriş"]. ":" . $seçenekler["şifre" ]);
curl_setopt($ch, CURLOPT_URL, $wdsl);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, $kredi);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_FILE, $fp);
if (($xml = curl_exec ($ch )) === false ) (
//curl_close($ch);
fclose($fp);
bağlantıyı kaldır ($this -> önbellek_dizini . $dosya);

Yeni İstisnayı atın(curl_error($ch));
}

Curl_close($ch);
fclose($fp);
$wdsl = $this -> önbellek_url . $dosya;
}

Unset($seçenekler [ "wdsl_local_copy" ]);
unset($seçenekler [ "wdsl_force_local_copy" ]);

Yankı $wdsl ;
ebeveyn :: __construct ($wdsl, $options);

Bağlantıyı kaldır ($this -> önbellek_dizini . $dosya);
}
}
?>

gmail dot com'da tatupheba

Merhaba millet!

Geliştiriciler için bir ipucu:

Bazı sabun sunucularını programlarken php.ini dosyasındaki "soap.wsdl_cache_enabled" yönergesini 0'a ayarlayın:

Soap.wsdl_cache_enabled=0

Aksi takdirde wsdl'nizin yanlış veya eksik olduğunu söyleyen bir sürü garip hata verecektir.

Bunu yapmak sizi birçok gereksiz acıdan kurtaracaktır.

phpdevshell nokta org şirketinde titan

Bir dönüş hatası alırsanız şunu unutmayın: "Nesne başvurusu, bir nesnenin örneğine ayarlanmadı.". Bunun nedeni yanlış parametrelerin iletilmesi kadar basit bir şey olabilir. Bu XML'e baktığınızda:



sicim
tarihSaat
tarihSaat

Kodunuz şöyle görünmeli:

denemek (
$seçenekler = dizi(
"soap_version" => SOAP_1_2,
"istisnalar" => true,
"iz" => 1,
"cache_wsdl" => WSDL_CACHE_NONE
);
$istemci = yeni SoapClient ( "http://example.com/doc.asmx?WSDL", $seçenekler);
// XML'de "Get" ve "request" etiketlerinin nerede olduğuna dikkat edin
$sonuçlar = $istemci -> Get (array("istek" =>array("MüşteriKimliği" => "1234" )));
) catch (İstisna $e ) (
Eko "

İstisna Hatası!

" ;
echo $e -> getMessage();
}

$sonuçlar = $istemci -> Get (array("istek" =>array("MüşteriKimliği" => "842115" )));
?>

WSDL dosyanız base64Binary türünde bir parametre içeriyorsa, sabun değişkenlerinizi aktarırken base64_encode() kullanmamalısınız. İsteği gerçekleştirirken, SOAP kitaplığı verilerinizi otomatik olarak base64 ile kodlar, aksi takdirde onu iki kez kodlamış olursunuz.

WSDL pasajı:

$dizge = "veri_sen_istiyorsun_göndermek___like_xml_in_soap";
$soap_veri = dizi(
"foo" => "çubuk",
//"content" => base64_encode($string) // bunu yapma
"içerik" => $string //bunu yap
);
$yanıt = $istemci -> Gönder ($soap_data );
?>

marcovtwout, hotmail nokta com'da

SOAP'ta yeni olduğumdan, mesajımın neden sabun arayüzünde yanıt aldığını, ancak php kodumla yanıt almadığını öğrenmek için bir süre araştırma yapıyordum. Bahsettiğim belirli hizmet, başarı durumunda HTTP 202 Kabul edildi (yanıt yok) veriyor, ancak hatalar durumunda bir SOAP mesajı döndürüyor.

Durum:
(Kimliği doğrulanmış) bir istemci bağlantısı ve bir WDSL dosyası kullanan "Tek Yönlü" türündeki SOAP çağrıları, bir yanıt beklenmesine rağmen bir yanıt başlığı vermez.

Çözüm:
İstemci yapıcısını çağırırken $options["features"] içinde SOAP_WAIT_ONE_WAY_CALLS değerini ayarlayın.

Tim tdinternet nokta com'da

PHP 5.2.11, WSDL'nin doğruluğu konusunda pek seçici görünmüyor.

Diğer SOAP istemcileri şema ve ad alanı sorunlarından şikayet ederken, PHP'nin SoapClient'i tamamen iyi çalışıyordu. Ancak diğer istemciler için bu sorunların düzeltilmesi PHP'nin SoapClient'ını, SOAP yöntemine aktarılan nesnelerin sunucuda boş diziler haline gelmesi noktasına kadar bozdu. sunucu tarafı.

Alınan ders: bazı öğelere xsd öneki eklendi ve diğerleri eklenmedi -- WSDL'nizin doğru ve tutarlı olduğundan kesinlikle emin olun (düzeltilmiş bir WSDL_Gen.php kullanıyorum).

James Dot Ellis, Gmail Dot Com'da

Kullanılan SoapClient'ta belirgin bir sorun olmadan Coldfusion SOAP sunucusundan yanıt almada sorun yaşıyordum.

Sonunda sunucunun 1.2'yi değil, yalnızca SOAP 1.1 isteklerini kabul ettiğini buldum. Bunun sistem genelinde bir Coldfusion ayarı olup olmadığından emin değilim, ancak aynı duvara çarparsanız, SoapClient seçeneği "soap_version"'ı sabit SOAP_1_1'e ayarlamayı deneyin (bu varsayılandır ancak istemci başka bir hizmet için yeniden kullanıldığından benimki varsayılan olarak 1.2'ye ayarlandı). )

fonant dot com şirketinde ajcartmell

PHP'nin son sürümlerinde (5.2.9'dan sonraki ve 5.2.11'e eşit veya önceki bir sürümden) proxy_host ve proxy_port seçenekleri için boş dizelerin belirtilmesinde bir sorun var gibi görünüyor.

Proxy_host ve proxy_port için boş dize değerleri sağlamak "ana bilgisayar bulunamadı" türü hatalara neden olur: NULL veya FALSE sağlamak iyi çalışır.

gmail nokta com'da bhargav nokta khatana

Yerel PHP SOAP'ta WSSE (Web Hizmeti Güvenliği) başlıklarının nasıl uygulanacağını bulmam bir haftadan uzun sürdü. Bu konuda çok fazla kaynak yok, bu nedenle topluluğun yararı için bunu buraya eklemeyi düşündüm.

Adım 1: WSSE başlıklarına yönelik bir yapı oluşturmak için iki sınıf oluşturun

sınıf clsWSSEAuth(
özel $Kullanıcı adı ;
özel $Şifre;
function __construct ($kullanıcı adı, $şifre) (
$this -> Kullanıcı Adı = $kullanıcıadı ;
$this -> Şifre = $şifre ;
}
}

Sınıf clsWSSEToken (
özel $UsernameToken ;
işlev __construct ($innerVal)(
$this -> Kullanıcı AdıToken = $innerVal ;
}
}
?>
Adım 2: Kullanıcı Adı ve Şifre için Sabun Değişkenleri Oluşturun

$kullanıcıadı = 1111;
$şifre = 1111;

//Sağlayıcınızın hangi güvenlik ad alanını kullandığını kontrol edin.
$strWSSENS = "http://schemas.xmlsoap.org/ws/2002/07/secext";

$objSoapVarUser = new SoapVar($kullanıcıadı, XSD_STRING, NULL, $strWSSENS, NULL, $strWSSENS);
$objSoapVarPass = new SoapVar($password, XSD_STRING, NULL, $strWSSENS, NULL, $strWSSENS);
?>
Adım 3: Yetkilendirme Sınıfı için Nesne Oluşturun ve sabun var'ını iletin

$objWSSEAuth = new clsWSSEAuth ($objSoapVarUser, $objSoapVarPass);
?>
Adım 4: Auth sınıfının nesnesinden SoapVar oluşturun

$objSoapVarWSSEAuth= new SoapVar ($objWSSEAuth , SOAP_ENC_OBJECT , NULL , $strWSSENS , "UsernameToken" , $strWSSENS );
?>
Adım5: Token Sınıfı için nesne oluşturun

$objWSSEToken = new clsWSSEToken ($objSoapVarWSSEAuth );
?>
Adım 6: Token sınıfının nesnesinden SoapVar oluşturun

$objSoapVarWSSEToken= new SoapVar ($objWSSEToken, SOAP_ENC_OBJECT, NULL, $strWSSENS, "UsernameToken", $strWSSENS);
?>
Adım 7: "Güvenlik" düğümü için SoapVar oluşturun

$objSoapVarHeaderVal=new SoapVar ($objSoapVarWSSEToken, SOAP_ENC_OBJECT, NULL, $strWSSENS, "Güvenlik", $strWSSENS);
?>
Adım 8: Güvenlik sabunundan başlık nesnesi oluşturun

$objSoapVarWSSEHeader= new SoapHeader ($strWSSENS , "Güvenlik" , $objSoapVarHeaderVal , true , "http://abce.com");

//Buradaki üçüncü parametre "mustUnderstand=1" yapar
//Forth parametresi "actor="http://abce.com "" değerini oluşturur
?>
Adım 9: Soap Client'ın nesnesini oluşturun

$objClient = new SoapClient ($WSDL, $arrOptions);
?>
Adım 10: Soapclient nesnesinin başlıklarını ayarlayın

$objClient -> __setSoapHeaders (array($objSoapVarWSSEHeader ));
?>
Adım 11: Yönteme son çağrı

$objResponse = $objClient -> __soapCall ($strMethod , $requestPayloadString );
?>

webacoustics nokta com şirketinden Peter

Soapclient'te temel kimlik doğrulama kullanılırken WSDL almanın başarısız olduğunu buldum. Bu yüzden wget kullanarak aşağıdaki geçici çözümü uyguladım. Wget'in bazı ortamlar için bir seçenek olmayabileceğinin farkındayım, bu durumda cURL bir sonraki en basit şey olacaktır.

$wsdl = get_wsdl ( "https://example.com/soap/service?wsdl");
$this -> client = new SoapClient ($wsdl, array("user" => "someuser", "password" => "somepassword" ));

Özel işlev get_wsdl ($url) (
küresel $g;
$url = kaçışshellarg($url);
$cache_file = "/tmp/soap.wsdl." . md5($url);

//sadece her saat başı yeni bir wsdl getir
if(! file_exists ($cache_file ) || filectime ($cache_file )< time () - 3600 ) {
$agent = kaçışshellarg("--user-agent=($g["useragent"])");
mwexec("wget ​​--quiet --timeout=5 ( $agent ) --no-check-sertifika --output-document=( $önbellek_dosyası ) ( $url ) " );
if(! file_exists ($cache_file )) (
throw new Exception("WSDL ($url) adresine yüklenemedi" );
}
}
geri dönmek
$cache_file ;
}
?>

meltir nokta com şirketinde meltir

NTLM kimlik doğrulamalı proxy sunucularıyla sorun yaşayanlar için işte ATM'de kullandığım bir çözüm:

/**
* Ntlm proxy kimlik doğrulamasını destekleyen SoapClient'in bir alt öğesi
*
* @yazar Meltir
*
*/
NTLM_SoapClient sınıfı SoapClient'i genişletir (

Genel işlev __construct ($wsdl, $options = dizi()) (
if (empty($options [ "proxy_login" ]) || empty($options [ "proxy_password" ])) yeni İstisna oluştur ( "NTLM kimlik doğrulaması için kullanıcı adı ve şifre gerekli!");
$this -> proxy_login = $seçenekler [ "proxy_login" ];
$this -> proxy_password = $options [ "proxy_password" ];
$this -> proxy_host = (empty($options [ "proxy_host" ]) ? "yerel ana bilgisayar": $seçenekler[ "Vekalet sahibi"]);
$bu-> proxy_port= (boş($seçenekler[ "proxy_port"]) ? 8080 : $seçenekler[ "proxy_port"]);
ebeveyn:: __inşa etmek($wsdl, $seçenekler);
}

/**
* Ntlm kimlik doğrulaması ile curl kullanarak bir URL'yi çağırın
*
* @param string $url
* @param string $veri
* @dönüş dizesi
* Kıvrılma bağlantı hatasında @throws SoapFault
*/
korumalı fonksiyonçağrıCurl($url, $veri) {
$tutamaç= curl_init();
curl_setopt($tutamaç, CURLOPT_HEADER, YANLIŞ);
curl_setopt($tutamaç, CURLOPT_URL, $url);
curl_setopt($tutamaç, CURLOPT_FAILONERROR, doğru);
curl_setopt($tutamaç, CURLOPT_HTTPHEADER,Sıralamak("PHP SOAP-NTLM İstemcisi"));
curl_setopt($tutamaç, CURLOPT_RETURNTRANSFER, doğru);
curl_setopt($tutamaç, CURLOPT_POSTFIELDS, $veri);
curl_setopt($tutamaç, CURLOPT_PROXYUSERPWD, $bu-> proxy_login. ":" . $bu-> proxy_password);
curl_setopt($tutamaç, CURLOPT_PROXY, $bu-> Vekalet sahibi. ":" . $bu-> proxy_port);
curl_setopt($tutamaç, CURLOPT_PROXYAUTH, CURLAUTH_NTLM);
$cevap= curl_exec($tutamaç);
eğer (boş(
$cevap)) {
yeni atmak
Sabun Arızası("CURL hatası:". curl_error($tutamaç), curl_errno($tutamaç));
}
curl_close($tutamaç);
geri dönmek
$cevap;
}

Kamu işlevi __doRequest($istek, $konum, $eylem, $versiyon, $one_way= 0 ) {
geri dönmek
$bu-> çağrıCurl($konum, $istek);
}

}
?>

Kıvrılma gerektirir ve genişletilebilir, ancak basit ihtiyaçlarım için işe yarıyor.

gmail dot com'da eric dot caron

Jan tarafından bestbytes'te işaret edildiği ve "WSDL Ayrıştırma: Bulunamadı"nın ortak kaynaklarından biri olan #27777 numaralı hatada tartışıldığı düşünülüyor "Hata, HTTP kimlik doğrulamasıyla korunan bir WSDL'ye erişmeye çalışmaktan kaynaklanıyor. 2. parametrede kullanıcı adını/şifreyi iletmek her zaman işe yaramaz; bu nedenle, bu hata mesajıyla karşılaşırsanız ve korumalı bir WSDL dosyasına erişmeye çalışıyorsanız, kullanıcı adını ve şifreyi ilk parametreyle birlikte aktarmayı deneyin.

Anonim

Standart Parlay X web hizmetlerini kullanmaya çalışırken hiçbir başarı elde edemediğimde oldukça garip bir davranışla mücadele etmek zorunda kaldım. Ancak sorunuma çare buldum.

Karşılaştığım sorun, web servisine gönderilen hatalı, geçersiz bir HTTP temel kimlik doğrulama isteğiyle ilgiliydi. Doğru kimlik bilgilerini göndermeme rağmen kimlik doğrulama hatasıyla karşılaşıyordum. PHP'nin doğrudan web hizmeti aracılığıyla kullanıma sunulmayan başka bir uç noktaya HTTP istekleri gönderdiği ve bu uç noktanın kimlik doğrulama gerektirmediği ortaya çıktı.

Bu soruna çarem, sendSms Paraly-X yöntemini kullanma örneğinde bu basit satırları kullanmaktı.

İlk olarak, herhangi bir HTTP kimlik doğrulama seçeneği olmayan bir sabun istemcisi oluşturmak:

$müşteri= yeniSoapClient($wsdl_url);
?>

Yukarıdaki istek wsdl'yi /tmp dizininde önbelleğe alacaktır. Bu yapının hemen ardından, bu sefer HTTP kimlik doğrulama seçenekleriyle başka bir sabun istemcisi oluşturuyoruz:

denemek (
$müşteri= yeniSoapClient($wsdl_url, sıralamak("giriş yapmak"=> "grifon",
"şifre"=> "şifre"));
) yakalamak (
İstisna $e) {
baskı("Hata:SendSms: %s\n", $e-> __toString'e());
geri dönmek
YANLIŞ;
}
?>

Şimdi sorunsuz çalışması gerekiyor. İkinci çağrı olmazsa PHP, kimlik bilgileri olmadan sendSms'i çağırır ve kimlik doğrulama bilgilerinin eksik olması nedeniyle başarısız bir girişimle sonuçlanır. Bu prosedürün en basit olduğunu buldum.

Bu işlem, önbelleğe alınan wsdl'nin süresi dolduğunda yapılmalıdır veya yalnızca bir işlem, php.ini'den önbelleğe alınan wsdl'nin yaşam süresini artırabilir.

net-entwicklung noktasında jon dot gilbert

Geçersiz bir URL için bir sabun istemcisi oluşturmanın (bir hizmet mevcut olmadığında ne olacağını test edersiniz, değil mi?) genellikle try..catch ile yakalanabilecek bir istisna oluşturduğunu unutmayın. Ancak xdebug aktifse, yakalanamayacağı kesin olan ölümcül bir hata alırsınız.

gmail dot com'da sloloem

Sınıf haritasının kullanımını tartışırken çözmem biraz zaman alan bir sorun yaşadım. Dokümanların bahsettiği WSDL türünün, SOAP'ta döndürülen öğenin adı olduğunu varsayıyordum;

Ve neden haritalamanın yapıldığını merak ediyordum
"classmap"=>array("node"=>"MyNode")

Hiçbir şey yapmadım.
Bunun nedeni WSDL'mde düğümü şu şekilde tanımlamış olmamdır:

İhtiyacım olan sınıf haritası şuydu:
"classmap"=>array("nodeType"=>"MyNode")

Tür adlarını SoapClient->__getTypes() kullanarak bulabildim
Daha sonra ihtiyacım olan yazı tipi adını WSDL'nin içinde nereye bakabileceğimi fark ettim.

Acı verici derecede bariz bir şeyi kaçırıp kaçırmadığımı bilmiyorum ama belki bu bazı belgeleri açıklığa kavuşturabilir.

Jon

Microsoft ISA aracılığıyla harici bir sunucuya bağlanırken SoapClient'ı kullanırken bazı sorunlar yaşadık (şu anda v.2006, ancak bu diğer sürümler için de geçerli olabilir). Proxy_host, proxy_port, proxy_login ve proxy_password'ü sağlıyoruz ancak ISA sunucusu oturum açmayı kendi dosyasında rapor ediyor "anonim" olarak günlüğe kaydeder.

Sistem yöneticimiz bunun PHP'nin NTLN bilgilerini (Windows güvenlik protokolü) doğru formatta sağlamamasından kaynaklandığına inanıyor (ve özel proxy'lerle çalışıp çalışmaması gerektiği elbette başka bir tartışma). "Kullanıcı adı", "ETKİ ALANI\kullanıcı adı"nı hiçbir etki yaratmadan denedik. Çözüm, hedef ana bilgisayar adı/IP için ISA sunucusuna bir istisna eklemektir; daha sonra proxy_login ve proxy_password için null değeri sağlanabilir ve bağlantı daha sonra çalışmalıdır beklenildiği gibi.

Biraz ilgili bir not olarak, sorun yaşıyorsanız port numarasının tam sayı olarak verildiğinden emin olun. Bağlantı noktası numarası bir dize olarak sağlanırsa PHP'nin bazı sürümleri SoapClient ile proxy'yi kullanmaz.

jan at bestbytes dot de

Temel kimlik doğrulama gerekiyorsa bir wsdl alabilirsiniz:

$giriş = "bert";
$şifre= "bert şifresi";

$müşteri= yeniSoapClient(
"http://". urlen kodu($giriş) . ":" . urlen kodu($şifre) . "@www.server.com/path/to/wsdl",
sıralamak(
"giriş yapmak"=> $giriş,
"şifre"=> $şifre
)
);

?>

nicksilvestro dot net'te bilgi

ArrayOf_xsd_string ile sorun yaşayan ve "Dizi türü için seri durumdan çıkarıcı tanımlanmadı (http://www.w3.org/2001/XMLSchema)string" benzeri bir hata alan herkes için
SOAP_USE_XSI_ARRAY_TYPE olarak ayarlanan "özellikler" parametresini kullanmayı deneyin; bu, doğru seri durumdan çıkarıcının kullanıldığından emin olmanızı sağlar.

Örneğin,
$müşteri= yeniSoapClient("bazı.wsdl", sıralamak("özellikler"=> SOAP_USE_XSI_ARRAY_TYPE));
?>

Keskin nisanci

İyi bir örnek arıyordum ve bulamadım
sonunda bir yerde buldum (nerede olduğunu unuttum) sanırım burası
birden fazla parametreyle sabun isteğinde bulunmanın en iyi örneği

$params->AWSAccessKeyId = AMAZON_API_KEY;
$params->Request->SearchIndex = "Kitaplar";
$params->Request->Keywords = "php5 oop";

$amazon = new SoapClient("http://webservices.amazon.com)
/AWSECommerceService/AWSECommerceService.wsdl");
$sonuç = $amazon->itemSearch($params);

alex reutone virgül com'da

PHP SOAP'ı MS SOAP'a bağlamak için (CRM/EXCHANGE/...) Aşağıdaki ve diğer yerlerdeki açıklamaları kullanarak bazı sınıflar oluşturdum.
www.reutone.com/heb/articles.php?instance_id=62&actions=show&id=521

Gmail dot com'da naugtur

SoapFault istisnası: Görünüşe göre XML belgemiz yok sunucunuzun daha önce bir şey çıktısı verdiğinde meydana geldiği zaten belirtilmişti ... > etiket.

İçin bununla sorunu olan herkes, Vesunucu koduna erişim yok:
Yanıtları temizleyecek bir proxy bu şekilde yapılıriçinSen

php
/**
* James Ellis'in notundan alınan basit ders
*/
sınıfProxy_ClientuzanırSoapClient{
korumalı
$cacheDocument= "" ;
kamu işlevi
__inşa etmek($wsdl, $seçenekler) {
ebeveyn:: __inşa etmek($wsdl, $seçenekler);
}

/**
* SetCacheDocument() önceden önbelleğe alınmış belge içeriğini ayarlar
*/
kamu işleviÖnbellekBelgesini Ayarla($belge) {
$bu-> önbellekBelge= $belge;
}

/**
* __doRequest(), yerel bir isteği işlemek için standart SoapClient'ı geçersiz kılar
*/
kamu işlevi__doRequest() {
geri dönmek
$bu-> önbellekBelge;
}
}

//bu kodu fonksiyonunuzun içine veya gerekli tüm değişkenlerin ayarlandığı yere koyun

$müşteri= yeniSoapClient($wsdl_url, $settings_array);
$boşluk= $müşteri-> $yöntem($paramlar); //sunucudan yanıt almak için bunu çağırın

$response_string= $müşteri-> __getLastResponse();

//bu kısım bazı şeyleri kaldırır
$başlangıç= strpos($response_string, ");
$son= strpos($response_string, ">" );
$response_string= alt dizi($response_string, $başlangıç, $son- $başlangıç+ 1 );

//proxy'nizi hazırlayın
$vekil= yeniProxy_Client($wsdl_url, $settings_array);
//ve bunu sunucunun yanıtıyla doldurun
$vekil-> ÖnbellekBelgesini Ayarla($response_string);

$and_finally_the_result_is= $vekil-> $yöntem($paramlar);

baskı_r($and_finally_the_result_is); //bu orada ne olduğunu görmenizi sağlar

?>

$method, yöntemin adıdır; örneğin. $method="getVersion";
$params - bir sabun yöntemi için tipik parametreler