ขอคำแนะนำเรื่องเกี่ยวกับการทำ web service ด้วย PHP ครับ (SOAP WSDL และ SoapServer)
เคยทำครั้งนึงครับ
1. สร้าง WSDL มีฟังชั่นตามต้องการ
2. สร้าง php ฟังชั่นตามข้อ 1 และเปิดเซอร์วิส
3. สร้าง webservice client ติดต่อไปที่ ข้อ 1 และใช้งานตามสบาย
รูปแบบ WSDL หาได้ทั่วไปครับ ไม่ยาก แต่เขียนยาวอยู่ ^^ (อย่าให้เขียนผิดนะ ^^)
php นั้นก็ใช้พวกคลาส SoapServer, SoapClient
เวลาติดต่อ ไปที่เซิร์ฟเวอร์ ก็จะได้ใช้ฟังชั่นที่มีใน wsdl ครับ
Ex. (Webservice server)
Code (PHP)
....
//คืนค่าประวัติการจองทั้งหมด เฉพาะที่จ่ายเงินแล้ว(รวมที่เซตรายละเอียดห้อง และไม่ได้เซต)
function get_all_pay_booking_historyXML(){
if(!is_login()) exit;
$customer_id = $_SESSION['customer']['customer_id'];
//ดึงค่า setting(ค่า commission)
$query = mysql_query("SELECT commission FROM setting WHERE setting_id= 1");
$commission = mysql_result($query, 0);
$commission_multiply = (100 - $commission) / 100;
$dom = new DOMDocument( "1.0", "utf-8" );
$pay_booking = $dom->createElement('pay_booking');
$query = mysql_query("SELECT * FROM booking LEFT JOIN customerpayment USING(booking_id) WHERE customer_id= $customer_id AND !ISNULL(payment_datetime)");
while( $row = mysql_fetch_array($query) ){// bookings
$query3 = mysql_query("SELECT * FROM bookingroom LEFT JOIN room USING(room_id) LEFT JOIN roomtype USING(roomtype_id) WHERE booking_id= ".$row['booking_id']);
$room_count = mysql_num_rows($query3);
$booking_id = $dom->createElement('booking_id', $row['booking_id']);
$booking_code = $dom->createElement('booking_code', 'B'.substr('000'.$row['booking_id'], -4));
$checkin_date = $dom->createElement('checkin_date', $row['book_start_date']);
$checkout_date = $dom->createElement('checkout_date', $row['book_end_date']);
$rooms = $dom->createElement('rooms');
//ส่วนของ rooms
$query2 = mysql_query("SELECT * FROM bookingroom LEFT JOIN room USING(room_id) LEFT JOIN roomtype USING(roomtype_id) WHERE booking_id= ".$row['booking_id']);
while( $row2 = mysql_fetch_array($query2) ){
$room_id = $dom->createElement('room_id', $row2['room_id']);
$room_name = $dom->createElement('room_name', $row2['roomtype_name']);
$room_person_number = $dom->createElement('room_person_number', $row2['person_number']);
$room_floor = $dom->createElement('room_floor', $row2['floor']);
$room_description = $dom->createElement('room_description', $row2['room_description']);
$room = $dom->createElement('room');
$room->appendChild($room_id);
$room->appendChild($room_name);
$room->appendChild($room_person_number);
$room->appendChild($room_floor);
$room->appendChild($room_description);
$rooms->appendChild($room);
}
$booking = $dom->createElement('booking');
$booking->appendChild($booking_id);
$booking->appendChild($booking_code);
$booking->appendChild($checkin_date);
$booking->appendChild($checkout_date);
$booking->appendChild($rooms);
$pay_booking->appendChild($booking);
}
$dom->appendChild($pay_booking);
return $dom->saveXML();
return ''; //ถ้าไม่มีข้อมูลการจองที่ยังไม่ถูก กรอกข้อมูล
}
//สร้าง webservice server
$server = new SoapServer('webservice.wsdl');
//เพิ่มฟังชั่นให้ webservice server
$server->addFunction('login');
$server->addFunction('is_login');
$server->addFunction('logout');
$server->addFunction('get_roompriceXML');
$server->addFunction('set_roompriceXML');
$server->addFunction('get_pay_remain');
$server->addFunction('get_pay_historyXML');
$server->addFunction('get_unset_detail_bookingXML');
$server->addFunction('set_detail_bookingXML');
$server->addFunction('get_all_booking_historyXML');
$server->addFunction('get_all_pay_booking_historyXML');
//รับรีเควสจาก client
$server->handle();
Code (webservice client test)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>webservice_client_test</title>
</head>
<body>
<?php
$client = new SoapClient("http://localhost/Ebooking/webservice/webservice.wsdl");
echo '<strong>ทดสอบฟังชั่น login ด้วย logn() ด้วย user=test1, password=12345</strong><br>';
echo htmlspecialchars($client->login('test1', '12345')), '<br>';
echo '<br><br><strong>ทดสอบฟังชั่น is_login()</strong><br>';
echo $client->is_login() ? 'true' : 'false';
echo '<br><br><strong>ทดสอบฟังชั่น get_roompriceXML()</strong><br>';
echo htmlspecialchars($client->get_roompriceXML());
echo '<br><br><strong>ทดสอบฟังชั่น get_pay_remain()</strong><br>';
echo htmlspecialchars($client->get_pay_remain());
// echo '<br><br>'.($client->set_roompriceXML('aaa') ? 'true' : 'false');
echo '<br><br><strong>ทดสอบฟังชั่น get_pay_historyXML()</strong><br>';
echo htmlspecialchars($client->get_pay_historyXML());
echo '<br><br><strong>ทดสอบฟังชั่น get_unset_detail_bookingXML()</strong><br>';
echo htmlspecialchars($client->get_unset_detail_bookingXML());
// echo '<br><br>'.($client->set_detail_bookingXML('aaa') ? 'true' : 'false');
echo '<br><br><strong>ทดสอบฟังชั่น get_all_booking_historyXML()</strong><br>';
echo htmlspecialchars($client->get_all_booking_historyXML());
echo '<br><br><strong>ทดสอบฟังชั่น logout()<br>';
echo $client->logout() ? 'true' : 'false';
echo '<br><br><strong>ทดสอบฟังชั่น is_login() อีกรอบ</strong><br>';
echo $client->is_login() ? 'true' : 'false';
?>
</body>
</html>
ปล. ตอน deploy อย่าลืมแก้ WSDL ให้อ้างถึง webservice server ให้ถูกต้องด้วยนะครับ
Site: http://www.pjgunner.com
ประวัติการแก้ไข 2010-10-14 11:32:42 2010-10-14 11:38:19
Date :
2010-10-14 11:26:50
By :
pjgunner.com
ของคุณมันมี ด้วย? มันจะมีได้ไง ผมก็แค่ให้ตัวอย่างครับ
มันเป็นเมธอดที่ได้จากการประกาศที่ WSDL ครับ และสร้างฟังชั่น แอ็ดใน webservice server ในไฟล์เว็บเซอร์วิส
คุณสามารถดูว่ามีเมธอดอะไรให้ใช้บ้าง ได้โดย
Code (PHP)
$client = new SoapClient("http://localhost/Ebooking/webservice/webservice.wsdl");
echo '<strong>รายชื่อ method ทั้งหมดใน webservice server</strong> (เรียกจาก SoapClient->__getFunctions())<br>';
$webservice_server_functions = $client->__getFunctions();
foreach($webservice_server_functions as $val){
echo $val, '<br>';
}
Date :
2010-10-14 14:24:51
By :
pjgunner.com
อ๋อมผมลองรัน code ง่ายๆ ดูครับ แบบนี้
Code (PHP)
<?php
//service
function get_all_customertXML(){
require_once("../config/conndb.php");
require_once("lib/nusoap.php");
//Select data
$query = mysql_query("SELECT Cust_Name FROM customer");
$customer = mysql_result($query, 0);
$dom = new DOMDocument( "1.0", "utf-8" );
$cust_name = $dom->createElement('cust_name');
$dom->appendChild($cust_name);
return $dom->saveXML();
//สร้าง webservice server
$server = new soap_server('webservice.wsdl');
//เพิ่มฟังชั่นให้ webservice server
$server->addFunction('get_all_customertXML');
//รับรีเควสจาก client
$server->handle();
}
?>
และ
Code (PHP)
//caller
<?php
require_once("lib/nusoap.php");
$client = new soapclient("http://localhost:81/naturnova2/webservice/webservice.wsdl");
echo '<br><br><strong>ทดสอบฟังชั่น get_all_CustomerXML()</strong><br>';
echo htmlspecialchars($client->get_all_customertXML());
?>
หากผิดตรงไหนรบกวนแนะนำด้วยนะครับ ขอบคุณครับ ^^
Date :
2010-10-14 15:28:55
By :
nottp106
ผมไม่เคยใช้ nusoap นะครับ ผมใช้ PHP SOAP
แล้วคุณเขียน wsdl แล้วหรือยัง?
ประวัติการแก้ไข 2010-10-14 16:19:44
Date :
2010-10-14 16:05:37
By :
pjgunner.com
ขอบคุณพี่มากครับ ตอนนี้ผมรันตัว client ขึ้นมาแล้วพบ error นี้ครับ
Fatal error: Uncaught SoapFault exception: [Client] looks like we got no XML document in C:\AppServ\www\naturnova2\webservice5\soap-client.php:7 Stack trace: #0 [internal function]: SoapClient->__call('getCatalogEntry', Array) #1 C:\AppServ\www\naturnova2\webservice5\soap-client.php(7): SoapClient->getCatalogEntry('catalog1') #2 {main} thrown in C:\AppServ\www\naturnova2\webservice5\soap-client.php on line 7
ไม่รู้ต้องแก้ยังไง ที่ออฟิศมี proxy ด้วยไม่แน่ใจว่าจะเกี่ยวว่ามันไม่สามารถออกเนตได้หรือเปล่าครับ
Date :
2010-10-15 11:12:17
By :
nottp106
คิดว่ามันผิดชนิดข้อมูลครับ
ดูดีๆครับ ลักษณะนี้ เขียนให้คล้าย static language ทั้งข้อมูลขาเข้าและออกครับ โดยเฉพาะชนิดข้อมูลที่ปรกกาศใน wsdl
เพราะ การสร้าง webservice ควรได้มาตรฐานกลาง โดยเฉพาะชนิดข้อมูล ขาเข้าและออก
ประวัติการแก้ไข 2010-10-15 11:55:27
Date :
2010-10-15 11:52:22
By :
pjgunner.com
ลองเอาไฟล์ที่พี่ให้มารันกลับรันได้ T.T
ประวัติการแก้ไข 2010-10-15 13:56:48
Date :
2010-10-15 13:54:07
By :
nottp106
ผมลองรันโดยเอาไฟล์พี่มาแก้ไข และลองแก้ไขไฟล์ wsdl โดยผมเขียนฟังก์ชันสำหรับเรียกข้อมูลจากฐานข้อมูลมาแสดง ดังนี้
wsdl
<?xml version ='1.0' encoding ='utf-8' ?>
<definitions name='getCustomer'
targetNamespace='http://example.org/plus'
xmlns:tns=' http://example.org/plus '
xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/'
xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
xmlns='http://schemas.xmlsoap.org/wsdl/'>
<!-- For getCustomer Function -->
<message name='getCustomerRequest'>
<part name='Value' type='xsd:integer'/>
</message>
<message name='getCustomerResponse'>
<part name='Result' type='xsd:integer'/>
</message>
<!-- For second Function2 -->
<!--<message name='substractRequest'>
<part name='num1' type='xsd:float'/>
<part name='num2' type='xsd:float'/>
</message>
<message name='substractResponse'>
<part name='Result' type='xsd:float'/>
</message>-->
<portType name='getCustomerPortType'>
<operation name='getcustomer'>
<input message='tns:getCustomerRequest'/>
<output message='tns:getCustomerResponse'/>
</operation>
</portType>
<!-- For portType of Function2-->
<!--<portType name='substractPortType'>
<operation name='substract'>
<input message='tns:substractRequest'/>
<output message='tns:substractResponse'/>
</operation>
</portType>-->
<binding name='getCustomerBinding' type='tns:getCustomerPortType'>
<soap:binding style='rpc'
transport='http://schemas.xmlsoap.org/soap/http'/>
<operation name='getcustomer'>
<soap:operation soapAction='urn:xmethods-delayed-quotes#plus'/>
<input>
<soap:body use='encoded' namespace='urn:xmethods-delayed-quotes'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</input>
<output>
<soap:body use='encoded' namespace='urn:xmethods-delayed-quotes'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</output>
</operation>
</binding>
<!-- Binding for function2 -->
<!--<binding name='substractBinding' type='tns:substractPortType'>
<soap:binding style='rpc'
transport='http://schemas.xmlsoap.org/soap/http'/>
<operation name='substract'>
<soap:operation soapAction='urn:xmethods-delayed-quotes#substract'/>
<input>
<soap:body use='encoded' namespace='urn:xmethods-delayed-quotes'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</input>
<output>
<soap:body use='encoded' namespace='urn:xmethods-delayed-quotes'
encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
</output>
</operation>
</binding>-->
<service name='getCustomerService'>
<port name='getCustomerPort' binding='getCustomerBinding'>
<soap:address location='http://localhost:81/naturnova2/webservice4/service.php'/>
</port>
</service>
<!-- Service for function2 -->
<!--<service name='substractService'>
<port name='substractPort' binding='substractBinding'>
<soap:address location='http://localhost:81/naturnova2/webservice4/service.php'/>
</port>
</service>-->
</definitions>
และไฟล์ service เป็นดังนี้
Service
<?php
//Set no cache WSDL
ini_set("soap.wsdl_cache_enabled", "0");
//service function
function getCustomer(){
//connect database
require_once('../config/conndb.php');
$str = "SELECT Cust_Name FROM customer";
$query = mysql_query($str);
while($result = mysql_fetch_array($query))
{
$Value = $result['Cust_Name'];
return $Value;
}
}
//create server instance
$server = new SoapServer("testwsdl.wsdl");
//add function
$server->addFunction("getCustomer");
//handle server with client
$server->handle();
?>
ไฟล์ Client
Client
<?php header("Content-Type:text/html; charset=utf-8");?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>
<body>
<?php
//create client instance
$client = new SoapClient("http://localhost:81/naturnova2/webservice4/testwsdl.wsdl");
/*echo '<h3>รายชื่อ Function</h3>';
$funcs = $client->__getFunctions();
foreach($funcs as $func)
{
echo $func, '<br>';
}*/
echo $client->getCustomer();
?>
</body>
</html>
ปรากฏว่าถ้าผมกำหนดการรับค่าและคืนค่าใน wsdl เป็น integer มันจะ return เป็นตัวเลขคือ (888) ซึ่งค่าที่ถูกต้องคือ (888 พร็อพเพอร์ตี้ แอนด์ เซอร์วิส จำกัด) แต่ถ้าผมเปลี่ยนเป็น string มันจะ error โดยมัน error แบบนี้ครับ ไม่รู้ต้องแก้ไขที่ไหนครับ
atal error: Uncaught SoapFault exception: [SOAP-ENV:Server] SOAP-ERROR: Encoding: string '888 \xbe...' is not a valid utf-8 string in C:\AppServ\www\naturnova2\webservice4\client.php:22 Stack trace: #0 [internal function]: SoapClient->__call('getCustomer', Array) #1 C:\AppServ\www\naturnova2\webservice4\client.php(22): SoapClient->getCustomer() #2 {main} thrown in C:\AppServ\www\naturnova2\webservice4\client.php on line 22
ประวัติการแก้ไข 2010-10-15 16:32:34
Date :
2010-10-15 16:31:50
By :
nottp106
Code (PHP)
<message name='getCustomerRequest'>
</message>
<message name='getCustomerResponse'>
<part name='Result' type='xsd:integer'/>
</message>
Date :
2010-10-15 17:06:38
By :
pjgunner.com
(Hero ผมมาแล้ว ^^')
ผมลองเปลี่ยนเป็น string แล้วครับ มัน error ที่ถามไปด้านบนครับ
Date :
2010-10-15 17:08:57
By :
nottp106
พยายามหน่อยครับ ผมเองก็ไม่ได้ให้ใครมาทำให้ ผมก็ลองผิดลองถูกกว่าจะเป็นครับ
คุณเซฟไฟล์ถูกชนิดหรือยัง?
Date :
2010-10-15 17:13:35
By :
pjgunner.com
เป็นที่เรื่องการ save file จริงๆด้วยครับ ต้องเป็น utf-8 ขอบคุณครับ
Date :
2010-10-15 17:43:48
By :
nottp106
ขอบคุณครับ
Date :
2012-03-30 14:19:14
By :
312
สามารถสร้าง class ของ service ได้ใหมครับ
Date :
2012-05-08 15:57:56
By :
hanamiji
ด้วยความลืมเกี่ยวกับ webservice ค้นหาใน google ก็เจอเว็บนี้เว็บแรกเข้ามาอ่าน อ่านไปอ่านมา กระทู้ที่เราเคยถามนี่นา ตลกดีฮ่าๆ :)
Date :
2012-05-15 14:58:11
By :
nottp106
555 ยังหรอกครับพี่วิน :D ผมติดปัญหาอ่ะคับ คือถ้าผมรันที่ไม่ใช่ port 80 เช่นตอนนี้ผมใช้ port:91 ตัว Client ไม่สามารถเรียก service ได้ครับ ไม่รู้ว่าต้องแก้ไขอย่างไรครับ
ผมลองไปรันเครื่องที่ใช้ port 80 รัน php สามารถรันได้ปกติ
พี่วินหรือท่านอื่นๆพอทราบวิธีแก้ไขมั้ยครับ ขอบคุณครับ
Date :
2012-05-15 16:45:12
By :
nottp106
ผมลองข้าม port อื่น ก็ได้ปกติน่ะครับ
Date :
2012-05-15 16:51:59
By :
mr.win
ได้แล้วครับลองรัน port อื่นดูครับ ^^
Date :
2012-05-16 14:24:09
By :
nottp106
ขอบคุณครับพี่วิน
Date :
2012-05-17 08:45:42
By :
nottp106
ผมเป็นเด็กใหม่ ขอความรู้จากพี่่ๆ ผู้มีความชำนาญ ครับ
$client = new SoapClient("some.wsdl", array('login' => "some_name", 'password'=> "some_password"));
ในส่วนที่เป็นการกำหนด user ใช้งานอย่างไร ถ้าเราต้องการกำหนดหลายๆ user และต้องสร้าง user ไว้ที่ไหน
array('login' => "some_name", 'password'=> "some_password") ????
ขอบคุณครับ
Date :
2012-08-10 22:01:38
By :
เด็กใหม่
ในบทความ PHP Web Service มีตัวอย่างการทำ Login ผ่าน Web Service อยู่ครับ
Date :
2012-08-10 22:58:35
By :
mr.win
ผมอาจถามไม่ตรงประเด็นครับพี่ๆ
ผมอ่านจาก web หลายที่ การสร้าง instance ด้าน client คือ $client = new SoapClient($wsdl,$options);
จะมี option ให้เพิ่มเติม เช่น
Code (PHP)
$client = new SoapClient("some.wsdl", array('login' => "some_name", 'password'=> "some_password"));
คือเนื่องจาก เราสร้าง SoapClient ขึ้นมา แล้ว ฝั่ง server.php จะมาอ่าน array ที่ตามมาจากอะไรก่อนที่จะอนุญาต
ให้ใช้งาน operation ที่มีอยู่ ไม่ได้ต้องการสร้าง soap เพื่อตรวจสอบ user กรณีการ login form ครับ
ขอตัวอย่าง code ฝั่ง server ที่ตรวจสอบ option ก่อนเกิด instance ของ client ครับ
----------------------------------------------------------------------------
ตัวอย่าง ของ php ด้านล่าง ถ้า login ไม่ผ่าน instance จะไม่เกิดขึ้น และจะเรียกใช้ บรรทัดล่างสุดไม่ได้ ครับ
Code (PHP)
<?
$client = new SoapClient("http://10.0.1.45/WS/BWS.php?wsdl",array( 'trace'=>1,"login"=>"36072446","password" => "0812110","connection_timeout"=>300));
$param=new stdClass();
$param->Number=$num;
$result=$client->GetAreaByNumber($param);
?>
Date :
2012-08-11 23:50:03
By :
เด็กใหม่
ถามในกระทู้ใหม่น่ะครับ จะได้เป็นเรื่อง ๆ ไปครับ
Date :
2012-08-13 07:52:18
By :
mr.win
error แบบนี้คืออะไรครับ
Warning: require_once(lib/nusoap.php) [function.require-once]: failed to open stream: No such file or directory in C:\AppServ\www\php\WebServiceServer.php on line 2
Date :
2013-11-28 16:55:35
By :
vutchai14
C:\AppServ\www\php\lib\nusoap.php ไม่มีอยู่จริงครับ
ตรวจสอบ path ให้ด๊ครัส
Date :
2013-11-28 19:45:11
By :
itpcc
เห็นกรู้ที่เคยตอบสมัยไหนไม่รู้ละ ไม่น่าขุดนะคับน่าจะอ้างอิงเอา เพราะคนมาอ่านทีหลังอาจทำให้สับสน
สมัยก่อนที่ไม่ใช้ nusoap ทั้งที่มันง่ายกว่าไม่ต้องทำ wsdl เอง เพราะผมไม่แน่ใจว่ามันจะได้มาตรฐาน เวลาภาษาอื่นมาดึงข้อมูล ไม่แน่ว่ามีปัญหาหรือเปล่า และไม่รู้ว่าภาษานั้นๆ มี nusoap หรือเปล่า เท่านั้นเอง เลยเลือกใช้ของที่ php แถมาให้เลย
เผ่น http://www.youtube.com/watch?v=Y4f1cdNv_M8
Date :
2013-11-28 21:13:24
By :
pjgunner.com
ขอบคุณมากนะครับ
Date :
2013-11-29 11:05:23
By :
vutchai14
Load balance : Server 01