در این قسمت قصد داریم شما را با نحوه ساخت وب سرویس با php و soap آشنا کنیم. بیشترین مثالی که از وب سرویس وجود دارد و کاملا همه ما تقریبا یک بار هم از آن استفاده کردیم وب سرویس های درگاه های پرداخت واسط مثل پارس پال است
به عنوان توسعه دهنده نرم افزار، توانایی توسعه نرم افزار و سرویس برای محدوده گسترده ای از پلتفرم ها یک مهارت ضروری است. اما برای تحقق این موضوع نمی توان انتظار داشت که همه از یک پلتفرم یا یک زبان برنامه نویسی استفاده کنند یا اینکه همه پلتفرم ها و زبان ها را پوشش داد، این یک کار نشدنی است.
اگر تنها یک استاندارد وجود داشت که به ما اجازه می داد تا کدهای نرم افزارمان را یکبار بنویسیم و دیگران با نرم افزارهای خودشان به آسانی از طریق شبکه با آن ارتباط برقرار می کردند چقدر عالی می شد. خب خوشبختانه وجود دارد و نامش هم SOAP است.
SOAP چیست
SOAP مخفف کلمات Simple Object Access Protocol است که از ورژن ۱٫۲ به بعد این پروتکل به اختصار SOAP نامیده می شود. SOAP به شما اجاز می دهد تا نرم افزار های سازگار ایجاد کنید و دیگران از مزایای نرم افزار شما روی شبکه بهره مند شوند. SOAP قوانینی را برای ارسال و دریافت RPC (مخفف کلمات Remote Procedure Call) مانند: ساختار درخواست و پاسخ را تعریف می کند بنابراین SOAP محدود به نوعی سیستم عامل مشخص یا زبان برنامه نویسی مشخصی نیست، آنچه که مهم است این است که هر کسی می تواند پیام های SOAP را در زبان مورد استفاده خودش تدوین یا تجزیه کند.
در اولین قدم از ساخت وب سرویس با php و soap در ارتباط با خصوصیات SOAP بحث خواهیم کرد و اینکه در پیام های SOAP چه مواردی دخیل است. و نشان می دهیم که چطور می توان یک سرور و کلاینت SOAP را با استفاده از کتابخانه NuSOAP ایجاد کنیم تا جریان SOAP را با مثال نشان دهیم. قدم بعدی ما در ارتباط با اهمیت فایل های WSDL و اینکه چطور می توان آنها را به راحتی با استفاده از NuSOAP ایجاد کرد و اینکه چطور یک کلاینت می تواند از WSDL برای بهتر فهمیدن وب سرویس شما استفاده کند (در پست بعدی).
ساختار یک پیام SOAP:
SOAP بر پایه XML است و توسط انسان قابل خواندن می باشد اما یک طرح خاص وجود دارد که باید رعایت شود، در کد زیر یک پیام SOAP را بدون هیچ گونه داده ای مشاهده می کنید:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soap:Header> ... </soap:Header> <soap:Body> ... <soap:Fault> ... </soap:Fault> </soap:Body> </soap:Envelope> |
ممکن است کد بالا را به صورت یک فایل XML معمولی نگاه کنید اما آنچه که ایجاد شده است یک پیام SOAP با عنصر ریشه Envelope با فضای نام soap که http://www.w3.org/2001/12/soap-envelope
در نظر گرفته می شود. صفت soap:encodingStyle، نوع داده ی استفاده شده در فایل را مشخص می کند، اما SOAP خودش شیوه کدگذاری پیش فرضی ندارد. soap:Envelope اجباری است، اما عنصر بعدی یعنی soap:Header اختیاری است و به طور معمول شامل اطلاعات مربوط به اعتبار سنجی و اداره کردن Session است. پروتکل SOAP هیچ گونه اعتبار سنجی توکاری را ارئه نمی کند اما شامل اعتبار سنجی در تگ header توسط توسعه دهنندکان می باشد.
عنصر بعدی که موردنیاز است soap:Body است که شامل پیام RPC واقعی است که خود شامل نام های متد در موارد درخواست و مقادیر برگشتی در موارد پاسخ از متد می باشد. soap:Fault که یک عنصر اختیاری است در صورت وجود هر نوع خطایی، اطلاعات وضعیت و پیغام های SOAP را نگهداری می کند که باید یک عنصر فرزند از soap:Body باشد.
حالا که مقدمات ایجاد یک پیغام SOAP را درک کردید، نگاهی به درخواست ها و پاسخ های SOAP بیندازیم. در ابتدا با درخواست SOAP شروع می کنیم.
1 2 3 4 5 6 7 8 9 10 |
<?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soap:Body xmlns:m="http://www.yourwebroot.com/stock"> <m:GetStockPrice> <m:StockName>IBM</m:StockName> </m:GetStockPrice> </soap:Body> </soap:Envelope> |
در بالا یک نمونه پیام درخواست SOAP برای بدست آوردن قیمت انبار از یک شرکت خاص است. در داخل soap:Body
باید به این نکته توجه داشته باشید که عنصر GetStockPrice
مختص به نرم افزار است و نه یک عنصر SOAP، که تابعی روی سرور است که پارمتر “نام” را برای این درخواست فراخوانی شده دریافت می کند. StocName هم مخصوص Application است و آرگومانی برای تابع می باشد.
پیام پاسخ هم شبیه به درخواست است:
1 2 3 4 5 6 7 8 9 10 |
<?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soap:Body xmlns:m="http://www.yourwebroot.com/stock"> <m:GetStockPriceResponse> <m:Price>183.08</m:Price> </m:GetStockPriceResponse> </soap:Body> </soap:Envelope> |
داخل عنصر soap:Body یک عنصر GetStockPriceResponse با فرزند Price وجود دارد که شامل داده برگشتی است. همانطور که خودتان هم حدس زدید، GetStockPriceResponse و Price مختص به خود Application می باشد.
حال که یک نمونه از درخواست و پاسخ را مشاهده کردید و ساختار پیام های SOAP را درک کردید اجازه بدهید که NuSOAP را نصب و یک کلاینت و سرور SOAP را ایجاد کنیم.
ساخت یک سرور SOAP:
آسان تر از این نمی توان SOAP را دریافت، نصب و از آن استفاده کرد. کافی است آن را از باکس دانلود , دریافت کنید و در پوشه سایت قرار دهید و از حالت فشارده خارج کنید. برای استفاده از کتابخانه کافی است که فایل nusoap.php را در کدتان فراخوانی کنید.
برای سرور قصد داریم یک سرویس را برای ارائه لیستی از محصولات بر طبق دسته بندی محصولات ارائه ایجاد کنیم. سرور باید دسته بندی را از درخواست بخواند، و به دنبال همه محصولات مطابق با آن دسته بندی باشد و لیست را در قالب CSV به کاربر برگرداند.
یک فایل PHP با نام productlist.php در پوشه ریشه با کد زیر ایجاد کنید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?php require_once "lib/nusoap.php"; function getProd($category) { if ($category == "books") { return join(",", array( "The WordPress Anthology", "PHP Master: Write Cutting Edge Code", "Build Your Own Website the Right Way")); } else { return "No products listed under that category"; } } $server = new soap_server(); $server->register("getProd"); $server->service($HTTP_RAW_POST_DATA); |
در ابتدا فایل nusoap.php را برای استفاده از کتابخانه NuSOAP، با استفاده از تابع require_once در کد فراخوانی کردیم، سپس تابع getProd تعریف شده است پس از آن یک نمونه از soap_server ایجاد شده است و تابع getProd با متد register ثبت شده است.
این واقعا همه کدهایی است که برای ایجاد یک سرور SOAP لازم است، ساده است اینطور نیست؟ در یک سناریوی واقعی شما احتمالا باید نگاهی به لیست کتابها در پایگاه داده بکنید. اگر می خواهید کارهای بیشتری را روی سرورتان انجام دهید کافی است که توابع اضافی (یا هر متدی از کلاس ها) را تعریف کنید و هر یک از آنها را به صورتی که در بالا مشاهده می کنید ثبت کنید.
ساخت کلاینت SOAP:
یک فایل PHP با نام productlistclient.php را با کدهای زیر ایجاد کنید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<?php require_once "lib/nusoap.php"; $client = new nusoap_client("http://localhost/nusoap/productlist.php"); $error = $client->getError(); if ($error) { echo "<h2>Constructor error</h2><pre class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php'>" . $error . "</pre>"; } $result = $client->call("getProd", array("category" => "books")); if ($client->fault) { echo "<h2>Fault</h2><pre class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php'>"; print_r($result); echo "</pre>"; } else { $error = $client->getError(); if ($error) { echo "<h2>Error</h2><pre class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php'>" . $error . "</pre>"; } else { echo "<h2>Books</h2><pre class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php'>"; echo $result; echo "</pre>"; } } |
یکبار دیگر nusoap.php را با استفاده از require_once در کد فراخوانی کردیم سپس یک نمونه از از nusoap-client را ایجاد کردیم. سازنده مکان سرور SOAP که به تازگی ایجاد کردیم را برای اتصال دریافت می کند. متد getError بررسی می کند تا client بدون هیچ گونه مشکلی ایجاد شده باشد و در صورت وجود مشکل کد و پیغام خطا را نمایش می دهد.
متد call درخواست SOAP را ایجاد می کند که دارای دو آرگومان است که آرگومان اول تابع یا متد در سرور را مشخص می کند و آرگومان دوم یک آرایه انجمنی از آرگومان ها برای RPC است. خصوصیت fault و تابع getError برای بررسی و نمایش هر نوع خطایی استفاده می شود اگر هیچ خطایی وجود نداشته باشد، نتیجه تابع همان خروجی خواهد بود
حالا نوبت اجراست، در Local Host اسکریپت client را اجرا می کنیم که باید نتایج را به صورت زیر در مرورگرتان مشاهده کنید.
شما می توانید برای بررسی و debug، این کدها را به پایین فایل productlistclient.php اضافه کنید.
1 2 3 4 |
echo "<h2>Request</h2>"; echo "<pre class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php'>" . htmlspecialchars($client->request, ENT_QUOTES) . "</pre>"; echo "<h2>Response</h2>"; echo "<pre class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php' class = 'brush: php'>" . htmlspecialchars($client->response, ENT_QUOTES) . "</pre>"; |
حالا header های http و محتوی XML به خروجی اضافه شده اند.
تفاوت NuSoap و SOAP :
هر دو کتابخانه ای برای ارسال و دریافت داده بین کلاینت و سرور بر طبق استاندارد خاص و پروتکل SOAP است . NuSoap یک کتابخانه مجزا است که باید در پروژه های خود بارگذاری کنید اما کتابخانه soap همانند دیگر کتابخانه ها مثل curl ,domdocument بصورت extention در بسته نصبی php وجود دارند و نیازی به دانلود و اضافه کردن آن بطور جداگانه نیست
نتیجه گیری:
در این قسمت از ساخت وب سرویس با php و soap ، پروتکل SOAP و قابلیت هایی که این پروتکل برای ساخت نرم افزار های سازگار، ارائه می کند را بررسی کردیم. در قسمت بعدی در ارتباط با WSDL که در مستند سازی و ساختار وب سرویس به ما کمک می کند بحث را ادامه خواهم داد.
هر مشکلی در پیاده سازی کد های ساخت وب سرویس با php و soap داشتید . از قسمت نظرات با ما در ارتباط باشید , سریعا پاسخگوی سوالات شما هستیم .
موفق و پیروز باشید
سلام
کد شمارو میزنم چرا خطا زیر میده
Error
no transport found, or selected transport is not yet supported!
Request
Response
سلام. ورژن php روی ۷٫۴ بزارید و مطمین باشید ماژول soap هم فعال بشه روی سرور
سلام ممنونم از اموزشتون من مانند کد شما رو برای صفحه server.php نوشتم اما خطاب زیر رو میده :
This service does not provide a Web description
ورژن php هم ۷٫۲ است
سلام. باید فایل wsdl خودتون به به برنامه بشناسونید, );
$server->configureWSDL(
یا
$client = new soapclient(‘your server url’);
دوستان به بنده فقط اطلاعات زیر رو دادن که با وب سرویسشون ارتباط بگیرم البته ادرس ای پی رو جهت امنیت اینجا تغییر دادم کسی میدونه چطور میشه ازش استفاده کرد توPHP ؟
POST /OnlineSaleService.asmx HTTP/1.1
Host: 100.100.100.100
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: “OnlineSaleService/GetItemList”
string
string
string
سلام.
در این مقاله و بخش ساخت کلاینت SOAP: نحوه استفاده گفته شده.
شما در این خط از کد $client = new nusoap_client( آدرس خودتون رو که مشخص است رو قرار میدید به اینصورت http://IP/OnlineSaleService.asmx
بعد داخل این یک سری متد هستند که باید اجرا کنید
OnlineSaleService/GetItemList
که در کدها میتونید ببینید که با call انجام میشه که باید GetItemList رو کال کنید.
موفق باشید.
جناب شفیعی عزیز، در بخش header این سند (کامل براتون نیومده) باید Tokenمعرفی کنم (که بهم دادن) و در بخش body هم باید StartDate و EndDate بدم نمیدون چطور این درخواست بسازم از CURL استفاده کردم و خیلی از آموزشهای دیگه رو تست کردم اما نتیجه نگرفتم
کد کامل به اینصورت میشه :
داخل خط ۲ و ۲۶ باید آیپی یا اگر url درست نیست باید اصلاح کنید
همچنین خطوط ۱۵ و ۱۶ میتونید StartDate و EndDate مربوط به بادی رو تغییر بدید
اگر مورد دیگری هم بود باید تغییر بدید
موفق باشید.
دقیقا همین و چک کردم قبلا جواب نگرفتم، پس من حس میکنم ممکنه مشکل از سرویس دهنده باشه
بسیار ممنونم از پاسخگویی تون
مهندس برنامم چنین اروری میده باید چیکار کنم؟
no transport found, or selected transport is not yet supported!
مربوط به ورژن php شماست. از کدام نسخه استفاده می کنید ؟
با سلام و احترا از ورژن ۷٫۲٫۷ استفاده میکنم
سلام. لطفا ورژن رو روی ۵٫۶ ببرید و دوباره تست کنید
سلام
ورژن php رو پایین آوردم بازم هم همین ارورو نشون داد.
سلام. کد خودتون رو اگه تونستید ارسال کنید تا بررسی بشه.
مهندس ما باید تمام توابع موردنیاز تعریف شده در برنامه رو به SOAP رجیستر کنیم؟
و سوال دوم اینکه ما با SOAP هم مثل RESt FULL API می توانیم چهار عمل اصلی رو ، رو دیتابس انجام بدیم؟
هر دو سوال بله و به راحتی میتونید با soap هر چهار عمل اصلی روی دیتابیس را انجام بدید.
خدمتتون عرض کنم که soap هم کارش مثل REST هست؟ یعنی با SOAP هم میشه مثل REST برای برنامه وب سرویس نوشت و کاربردش هم مشابه REST هست؟
به نظر جنابعالی از rest استفاده کنیم یا soap?کدوم بهتره و الان بیشتر از کدوم دارن استفاده میکنن؟
خب مطمینا الان بیشتر سرویس ها از rest استفاده می کنند که آموزش آن هم در سایت قرار داره می تونید کلمه rest رو جستجو کنید
rest بیشتر متکی روی برنامه نویسی بدون هیچ گونه سرویس یا قابلیت و ابزار خاصی است.
با سلام و درود آقای حسن شفیعی
بسیار عالی . آموزشهاتون همیشه عالی و مشکل گشای برنامه نویسان هست. بنده از شما تشکر بسیار میکنم
سلام. خوشحالیم که مفید واقع شده.
موفق و پیروز باشید
سلام. تشکر بابت زحماتتون.
یه سوال داشتم، من با این سورس تونستم به یه وب سرویس وصل بشم، ولی کلمات فارسی رو علامت سوال نشون میده. چطوری میتونم این مشکل رو برطرف کنم؟
تشکر
سلام. خوشحالم که مفید واقع شده. هدر utf8 را ست کنید مشکل حل میشه.
موفق باشید.