จากเมื่อวานที่ผมได้รับมาตอนเย็น ให้ทำให้ PHP เรียก Web Service ของ .NET แล้วตามทฤษฎีนั้นเรียกได้อยู่แล้ว แต่คราวนี้ผมต้องมาลงมือจริงๆทำจริง โดยผมได้ลองทำ Web Service ของ .NET ต้องขอบอกว่าง่ายมากๆใช้เวลาเพียงแปป เดียวเท่านั้น (อันนี้ขอข้ามนะ) เสร็จแล้วมาถึงวิธีเีรียก คราวนี้และปัญหาซึ่งบทความใน Internet ไม่มีอันไหนโดนตรงใจผมสักอัน ลองถามใน Twitter ก็มีแต่คุณ pittaya ตอบมาแล้วบอกให้เชื่อมต่อผ่าน JSON แต่.. ผมลืมบอกเขาไปว่ามันเป็น SOAP เพราะตาม requirement แล้วผมจำเป็นต้องใช้ SOAP ดังนั้นพี่เขาก็เลยบอกให้ลอง nusoap ครับแต่ทว่า… ผมกำลังคิดในใจ (ไม่ได้บอกพี่เขา) ว่า NuSOAP มันไม่เก่าไปแล้วหรอ มันมี Library ให้เรียกใช้ทำไมต้องไปใช้ NuSOAP ???
ดังนั้นเพื่อตอบสนอง Need ของตัวเองผมเลยพยายามค้นหาวิธีโดยไม่ใช้ NuSOAP แล้วผมก็ทำได้ครับ อันนี้ใช้ Library ที่ติดมาใน PHP เลยครับ โดยขั้นตอนแรกต้องไปเอา comment ของ php_soap.dll ออกจาก php.ini ก่อนครับโดยถ้าใครใช้ AppServ ก็จะอยู่ใน WINDOWS\php.ini แล้วก็เปลี่ยนจาก ;php_soap.dll เป็น php_soap.dll เอา ; ออกนั้นเอง เสร็จแล้วมาเริ่มกันเลยครับ
<s:element name=”sendObject”>
<s:complexType>
<s:sequence>
<s:element minOccurs=”0″ maxOccurs=”1″ name=”gc” type=”tns:GuestCounts”/>
</s:sequence>
</s:complexType>
</s:element>
Complex Type 1.0
<s:complexType name=”GuestCounts”>
<s:sequence>
<s:element minOccurs=”1″ maxOccurs=”1″ name=”AgeQualifyingCode” type=”s:int”/>
<s:element minOccurs=”1″ maxOccurs=”1″ name=”Count” type=”s:int”/>
</s:sequence>
</s:complexType>
Complex Type 1.1
อันนี้เป็น Complex Type นะครับคืออะไรลองศึกษากันเองครับ
$client = new SoapClient(”http://localhost/HotelService.asmx?WSDL”);
$wrapper->gc->Count = 10;
$wrapper->gc->AgeQualifyingCode = 50;
$params = new SoapParam($wrapper, “sendObject”);
var_dump($client->sendObject($params));
อันนี้คือส่วน Code ที่ใช้ครับ
code จริงๆก็ประมาณนี้เองครับ แต่อธิบายยากนะจะบอกให้ อิอิ โดยบรรทัดแรกนั้นเป็นการสร้าง SoapClient จาก WSDL ครับผมโดยอันนี้สังเกตุได้ว่าผมจะเติม ?WSDL ด้วยเพราะเจ้า WebService ของ .NET ปกติมันไม่้ได้ทำออกมาเป็น WSDL ซึ่งเราสามารถเล่นกับ WebService ก่อนได้ครับ เช่น มี Method ที่รับ Int แล้ว Return String เราก็สามารถลองใส่ Int เล่นๆได้ครับแล้วกดเพื่อดูผลลัพธ์ได้เลย
มาดูบรรทัดที่ 2 กับ 3 ครับ เราจะทำการสร้าง Array Structure ลอยๆขึ้นมาก่อนครับเพื่อให้ถูกต้องตาม Complex Type นั้นในที่นี้ผมเลยสร้างชื่อ $wrapper->gc ต้องเป็นชื่อ gc นะครับดูจาก Complex type 1.0 จะเห็นว่า name=”gc” อันนี้ต้องตั้งชื่อตามเขา ทุกๆ Variable (ส่วนคำว่า $wrapper เปลี่ยนได้) เลยเลยสรุปเป็น $wrapper->gc->Count ดูจาก Complex type 1.1 จะเห็นได้ว่า name=”Count” ซึ่งต้องเหมือนกันเปะๆ ทำเสร็จแล้วคราวนี้เราจะได้ Array Structure ที่ตรงกับ Complex Type แล้ว
ต่อมาดูบรรทัดที่ 4 ครับผมทำการสร้างตัวแปรชื่อ $params ให้เท่ากับ SoapParam($wrapper,”sendObject”); อันนี้และครับพระเอกของงานนี้ โดยเจ้า SoapParam เนี้ยมันจะทำการ Map ตัวแปร $wrapper กับ element name=”sendObject” ดูได้จาก Complex Type 1.0 นั้นหมายความว่าตอนนี้เราจะได้ $params ที่พร้อมจะส่งข้อมูลเป็น object แล้ว
บรรทัดที่ 5 ก็เป็นการเรียก WebService ในคำสั่งที่ว่า $client->sendObject($params) แบบนี้ส่วน var_dump คือการ dump ตัวแปรออกมาดูว่าข้างในมีอะไรบ้างซึ่งผลลัพธ์จะแล้วแต่คนทำ Business Logic ใน WebService นะครับโดยผมจะได้ดังนี้
object(stdClass)#3 (1) { ["sendObjectResult"]=> int(20) }
จริงๆแล้วผลลัพธ์ที่ผมได้ออกมาเป็น 20 นั้นสาเหตุคือ ผมให้มัน return 10+gc.Count แล้วผมใส่ gc.Count เป็น 10 เลยได้ออกมาเป็น 20 อย่างที่เห็นครับผม ส่วนถ้าใครต้องการข้อมูล 20 เลยนั้นต้องเรียกแบบนี้ครับ
echo $client->sendObject($params)->sendObjectResult // ผลลัพธ์ที่ได้คือ 20
อันนี้คือตามหลักของ SOAP นะครับก็คือจะมีทั้ง Request Response ก็ต้องยอมๆเขาไปครับ สังเกตุนะครับว่าไม่มีวงเล็บ เพราะมันเป็นการเรียกข้อมูล variable นะครับไม่ใช่เรียก method วันนี้ผมก็นำมา share ให้คนที่มีปัญหาเรื่องนี้ทำกันนะครับ ส่วนเรื่อง return เป็น object นั้นไม่ต้องทำอะไรเลยครับ มันก็จะ return มาเป็น เหมือน Array Structure นะครับเอาไปเรียกใช้ได้ตามสะดวกเลยครับพี่น้องครับ วันนี้ผมลาไปก่อนแล้วนะครับ สวัสดีครับ