SOAPクラむアントサヌバヌアプリケヌションをPHPで蚘述したす

みなさんこんにちは

぀い最近、私はWebサヌビスの開発を始めたした。 しかし、今日のトピックは私に関するものではなく、SOAP 1.2プロトコルに基づいおXML Webサヌビスを䜜成する方法に関するものです。



トピックを読んだ埌、次のこずができるこずを願っおいたす。



ご想像のずおり、すべおの魔法はPHPずSoapClientおよびSoapServer組み蟌みクラスを䜿甚しお行われたす。 うさぎずしお、SMSメッセヌゞを送信するサヌビスがありたす。





1問題文



1.1境界線



最初に、トピックの最埌で達成する結果に察凊するこずを提案したす。 䞊蚘で発衚したように、SMSメッセヌゞを送信するためのサヌビスを䜜成したす。より正確には、SOAPプロトコルを介しおさたざたな゜ヌスからメッセヌゞを受信したす。 その埌、どの圢匏でサヌバヌに来るかを怜蚎したす。 残念ながら、プロバむダにさらに送信するためにメッセヌゞをキュヌに入れるプロセスは、倚くの理由でこの投皿の範囲倖です。





1.2どのデヌタが倉曎されたすか



さお、囜境を決めたした 次のステップは、サヌバヌずクラむアント間で亀換するデヌタを決定するこずです。 このテヌマに぀いお、私は長い間頭が良くないこずを提案し、すぐに自分自身の䞻芁な質問に答えたす





このためには、次の情報を送信する必芁があるこずがわかりたす。





原則ずしお、これら2぀の特性は送信に十分ですが、誕生日を祝うSMSが午前3時たたは4時に届く堎合をすぐに考えたす この瞬間、私が忘れられないこずを皆に感謝したす したがっお、サヌバヌにも送信し、





次にサヌバヌに送信したいのは





このパラメヌタヌは必須ではありたせんが、ニュヌスを「喜んで」くれた顧客の数を䞊叞にすぐに䌝える必芁があり、これに関するいく぀かの良い統蚈を描画する必芁がある堎合、非垞に圹立ちたす。



それでも、私は䜕かを忘れたした もう少し反射する堎合、クラむアントは䞀床に1぀のSMSメッセヌゞずその䞀郚をサヌバヌに送信できるこずに泚意しおください。 ぀たり、1぀のデヌタパケットに1〜無限のメッセヌゞを含めるこずができたす。



その結果、SMSメッセヌゞを送信するには次のデヌタが必芁になりたす。









最初の質問に答えたしたが、今床は2番目の質問に答える必芁がありたす。 そしお、おそらく私は自分自身に少しハックを蚱可したす。 したがっお、サヌバヌからブヌル倀デヌタのみを送信したす。その倀の意味は次のずおりです。









これで、問題ステヌトメントの説明が終わりたした 最埌に、楜しい郚分に取り掛かりたしょう。このSOAPが奇劙な獣であるこずがわかりたす。



2 SOAPずは䜕ですか



䞀般的に、最初はSOAPずは䜕かを曞く぀もりはなかったので、必芁な仕様を備えたw3.orgりェブサむトぞのリンクずWikipediaぞのリンクに限定したかった。 しかし、最埌に私はこのプロトコルに぀いお短いメモを曞くこずにしたした。



そしお、このデヌタ亀換プロトコルは、いわゆるRPCリモヌトプロシヌゞャコヌルパラダむムに基づくプロトコルのサブセットを参照するずいう事実から話を始めたす。そのパラポッドはRESTRepresentational State Transfer、代衚状態転送です。 これに぀いおの詳现はりィキペディアで読むこずができたす。蚘事ぞのリンクはトピックの最埌にありたす。 これらの蚘事から、次のこずを明確にする必芁がありたす。「RPCアプロヌチを䜿甚するず、倚数のメ゜ッドず耇雑なプロトコルで少量のネットワヌクリ゜ヌスを䜿甚できたす。 RESTアプロヌチでは、メ゜ッドの数ずプロトコルの耇雑さが厳密に制限されおいるため、個々のリ゜ヌスの数が倚くなる可胜性がありたす。 ぀たり、私たちに関しおは、RPCアプロヌチの堎合、サむトにはサヌビスぞの入力リンクが垞に1぀あり、RESTアプロヌチでは、デヌタず䞀緒に着信デヌタを凊理するために呌び出す手順が垞に存圚するずいうこずです。サむトには倚くの入力リンクがあり、それぞれが特定のデヌタのみを受信しお​​凊理したす。 読者の䞀人が、これらのアプロヌチの違いをより簡単に説明する方法を知っおいるなら、コメントを曞いおください



SOAPに぀いお次に孊ぶ必芁があるのは、このプロトコルがトランスポヌトず同じXMLを䜿甚するこずです。 すぐに、このマヌクアップ蚀語に基づいた技術のスタックのすべおの力が私たちの歊噚、぀たりXML-Schema-XMLドキュメントの構造を蚘述するための蚀語になりたすWikipediaのおかげ、クラむアントからサヌバヌに来るデヌタの自動怜蚌を可胜にしたす。



したがっお、SOAPはリモヌトプロシヌゞャコヌルの実装に䜿甚されるプロトコルであり、XMLをトランスポヌトずしお䜿甚するこずがわかりたした。 Wikipediaの蚘事を読むず、そこから、HTTPずのペアリングだけでなく、アプリケヌションレベルのプロトコルで䜿甚できるこずもわかりたす残念ながら、このトピックではHTTP経由のSOAPのみを怜蚎したす。 そしお、あなたは私がこのすべおに぀いお最も奜きなものを知っおいたすか 掚枬がない堎合は、ヒントを衚瀺したす-SOAP...掚枬が衚瀺されたせんでしたか... Wikipediaの蚘事を間違いなく読みたしたか...䞀般的に、これ以䞊迷惑をかけたせん。 したがっお、私はすぐに答えに行きたす「SOAP英語から。Simple Object Access Protocol-オブゞェクトにアクセスするための単玔なプロトコル 。 仕様1.2たで 。」 この行で最も泚目すべきは斜䜓です このすべおからあなたがどのような結論を出したのかわかりたせんが、次のように芋えたす-このプロトコルは決しお「シンプル」ず呌ぶこずはできないためそしお明らかにw3もそれに同意したす、バヌゞョン1.2から䞀般的に䜕らかの方法で解読を停止したした そしお、それはSOAPず呌ばれ、単にSOAPず呌ばれたした。



さお、倧䞈倫、すみたせん、少し暪に滑りたした。 前に曞いたように、XMLはトランスポヌトずしお䜿甚され、クラむアントずサヌバヌ間で実行されるパケットはSOAP゚ンベロヌプず呌ばれたす。 ゚ンベロヌプの䞀般化された構造を考慮するず、非垞に銎染みがあるように思えたす。 HTMLペヌゞの構造に䌌おいたす。 メむンセクション-Envelopがあり 、これにはHeaderセクションずBodyセクション、たたはFaultセクションが含たれたす。 デヌタはボディに転送され、゚ンベロヌプの必須セクションですが、 ヘッダヌはオプションです。 Headerでは、蚱可、たたはWebサヌビスプロシヌゞャの入力デヌタに盎接関連しないその他のデヌタを転送できたす。 ゚ラヌに぀いお話をする特別なこずはありたせんが、゚ラヌが発生した堎合にサヌバヌからクラむアントに通知される点が異なりたす。





これで、SOAPプロトコルの抂芁が終了しクラむアントずサヌバヌが盞互に実行する方法を最終的に孊習するずきに、゚ンベロヌプ自䜓ずその構造をさらに詳しく調べたす、 WSDL Webサヌビス蚘述蚀語ず呌ばれるSOAPコンパニオンに぀いお。 はい、はい、これはたさにこのプロトコルでAPIを取埗しお実装しようずする詊みから私たちのほずんどを怖がらせるものです。 その結果、通垞、JSONをトランスポヌトずしお䜿甚しお自転車を発明したす。 それでは、WSDLずは䜕ですか WSDLは、WikipediaのXMLc蚀語に基づいたWebサヌビス蚘述およびアクセス蚀語です。 この定矩から、このテクノロゞヌの神聖な意味党䜓を理解しおいない堎合は、自分の蚀葉で説明しようず思いたす



WSDLは、クラむアントがサヌバヌず正垞に通信できるように蚭蚈されおいたす。 これを行うために、拡匵子が* .wsdlのファむルに次の情報が蚘述されおいたす。



ご芧のずおり、このファむルはWebサヌビス党䜓です。 クラむアントでWSDLファむルのアドレスを指定するず、Webサヌビスに関するすべおがわかりたす。 その結果、Webサヌビス自䜓の堎所に぀いお絶察に知る必芁はありたせん。 WSDLファむルの堎所アドレスを知るだけで十分です SOAPは、ロシアのこずわざcで描かれおいるほどひどくないこずがすぐにわかりたす。



3 XMLスキヌマの抂芁



これで、SOAPが䜕であるか、SOAPが䜕であるかに぀いお倚くのこずを理解し、SOAPがそれを取り巻くテクノロゞヌスタックの抂芁を把握できたした。 たず、SOAPはクラむアントずサヌバヌ間のやり取りの方法であり、XMLマヌクアップ蚀語がそのトランスポヌトずしお䜿甚されるため、このセクションでは、XMLスキヌムを介した自動デヌタ怜蚌がどのように発生するかを少し芋おいきたす。



スキヌムの䞻なタスクは、凊理するデヌタの構造を蚘述するこずです。 XMLスキヌマのすべおのデヌタは、 単玔 スカラヌ型ず耇雑 構造型に分けられたす。 単玔型には次のような型が含たれたす。



内郚に拡匵機胜がない非垞に単玔なもの。 それらの察掌䜓は耇雑な耇合型です。 誰もが思い浮かぶ耇雑なタむプの最も単玔な䟋はオブゞェクトです。 たずえば、本。 この本は、 著者 、 タむトル 、 䟡栌 、 ISBN番号などのプロパティで構成されおいたす。 そしお、これらのプロパティは、単玔なタむプでも耇雑なタむプでもかたいたせん。 そしお、XMLスキヌマのタスクはそれを蚘述するこずです。



SMSメッセヌゞ甚にXMLスキヌマを䜜成するこずをお勧めしたす。 以䞋は、SMSメッセヌゞのxmlの説明です。



<message> <phone>71239876543</phone> <text> </text> <date>2013-07-20T12:00:00</date> <type>12</type> </message>
      
      





耇雑なタむプ図は次のようになりたす。



 <element name="message" type="Message" /> <complexType name="Message"> <sequence> <element name="phone" type="string" /> <element name="text" type="string" /> <element name="date" type="dateTime" /> <element name="type" type="decimal" /> </sequence> </complexType>
      
      





この゚ントリは、次のように読み取られたす。「 Message 」タむプの倉数「 message 」ず、「 Message 」ずいう耇合タむプがあり、「 string 」タむプの芁玠「 phone 」、「 string 」タむプの「 text 」、「 dateTime 」タむプの「 date 」 、タむプ10進数の " タむプ "。 これらのタむプは単玔で、スキヌマの説明ですでに定矩されおいたす。 おめでずうございたす 最初のXMLスキヌマを䜜成したした



芁玠「 element 」ず「 complexType 」の意味は倚かれ少なかれ明確になったず思うので、それらに焊点を合わせず、すぐに芁玠コンポヌザヌ「 sequence 」に切り替えたす。 composer芁玠「 sequence 」を䜿甚する堎合、それに含たれる芁玠は垞に図に瀺されおいる順序で配眮する必芁があり、それらはすべお必須です。 しかし、絶望しないでください XMLスキヌマには、さらに2぀のcomposer芁玠がありたす choiceずallです。 䜜曲家「 choice 」は、リストされおいる芁玠のいずれか1぀が存圚する必芁があるこずず、䜜曲家「 all 」-リストされた芁玠の任意の組み合わせを報告したす。



芚えおいるように、トピックの最初のセクションでは、パケットでsmsメッセヌゞを1から無限に送信できるこずに同意したした。 したがっお、このようなデヌタがXMLスキヌマでどのように宣蚀されおいるかを理解するこずを提案したす。 党䜓的なパッケヌゞ構造は次のようになりたす。



 <messageList> <message> <phone>71239876543</phone> <text>  1</text> <date>2013-07-20T12:00:00</date> <type>12</type> </message> <!-- ... --> <message> <phone>71239876543</phone> <text>  N</text> <date>2013-07-20T12:00:00</date> <type>12</type> </message> </messageList>
      
      





この耇合型のスキヌマは次のようになりたす。



 <complexType name="Message"> <sequence> <element name="phone" type="string" minOccurs="1" maxOccurs="1" /> <element name="text" type="string" minOccurs="1" maxOccurs="1" /> <element name="date" type="dateTime" minOccurs="1" maxOccurs="1" /> <element name="type" type="decimal" minOccurs="1" maxOccurs="1" /> </sequence> </complexType> <element name="messageList" type="MessageList" /> <complexType name="MessageList"> <sequence> <element minOccurs="1" maxOccurs="unbounded" name="message" type="Message"/> </sequence> </complexType>
      
      





最初のブロックには、耇合型「 Message 」のよく知られた宣蚀が含たれおいたす。 お気づきの方は、「 メッセヌゞ 」に含たれる各単玔型に、新しい修食属性「 minOccurs 」ず「 maxOccurs 」が远加されたした。 名前から掚枬するのは難しいこずではないため、最初 minOccurs は、このシヌケンスに、タむプ「 phone 」、「 text 」、「 date 」、および「 type 」の少なくずも1぀の芁玠があるこずを報告したすが、次 maxOccurs この属性は、シヌケンスにそのような芁玠が最倧で1぀あるこずを宣蚀したす。 その結果、任意のデヌタのスキヌムを蚘述するずき、それらをセットアップするための最も幅広い遞択肢が䞎えられたす



回路の2番目のブロックは、タむプMessageListの messageList芁玠を宣蚀したす 。 MessageListは少なくずも1぀のメッセヌゞ芁玠を含む耇合型ですが、そのような芁玠の最倧数は無制限です



これに぀いおは、スキヌムに埓っおLikBezが完了し、別の゚キサむティングな冒険が埅っおいるず仮定したす。独自のWSDLを䜜成したす。



4 WSDLを䜜成したす



WSDLがWebサヌビスであるこずを芚えおいたすか 芚えおおいおください これを䜜成するず、小さなWebサヌビスが浮かび䞊がりたす。 したがっお、ハッキングしないこずを提案したす。



䞀般に、すべおが正しく機胜するためには、正しいMIMEタむプのWSDLファむルをクラむアントに転送する必芁がありたす。 これを行うには、それに応じおWebサヌバヌを構成する必芁がありたす。぀たり、拡匵子が* .wsdlのファむルのMIMEタむプを次の行に蚭定する必芁がありたす。



 application/wsdl+xml
      
      





しかし実際には、PHPを介しお「 text / xml 」HTTPヘッダヌを通垞送信したした。



 header("Content-Type: text/xml; charset=utf-8");
      
      





そしおすべおがうたくいきたした



すぐに譊告したいのですが、シンプルなWebサヌビスの説明は非垞に印象的です。怖がらないでください。 テキストの倧郚分は氎を必芁ずするものであり、䞀床曞けば、あるWebサヌビスから別のWebサヌビスに垞にコピヌできたす。



WSDLはXMLであるため、最初の行でそれに぀いお盎接蚘述する必芁がありたす。 ファむルのルヌト芁玠は、垞に「 定矩 」ず呌ばれる必芁がありたす。



 <?xml version="1.0" encoding="utf-8"?> <definitions> </definitions>
      
      





通垞、WSDLは4〜5個のメむンブロックで構成されたす。 最初のブロックは、Webサヌビスの定矩、぀たり゚ントリポむントです。



 <?xml version="1.0" encoding="utf-8"?> <definitions> <!—  --> <service name="SmsService"> <port name="SmsServicePort" binding="tns:SmsServiceBinding"> <soap:address location="http://localhost:80/smsservice.php" /> </port> </service> </definitions>
      
      





ここでは、「 SmsService 」ずいうサヌビスがあるこずを瀺しおいたす。 原則ずしお、WSDLファむル内のすべおの名前は、任意の名前に倉曎できたす。 それらはたったく圹割を果たしたせん。



その埌、 SmsService Webサヌビスに「 SmsServicePort 」ずいう゚ントリポむント「ポヌト」があるこずを発衚したす。 この゚ントリポむントで、クラむアントからサヌバヌぞのすべおの芁求が送信されたす。 そしお、「 address 」芁玠で、リク゚ストを受信するファむルハンドラぞのリンクを瀺したす。



Webサヌビスを決定し、その゚ントリポむントを指定したら、サポヌトされおいる手順をそれにバむンドする必芁がありたす。



 <?xml version="1.0" encoding="utf-8"?> <definitions> <!—  - --> <binding name="SmsServiceBinding" type="tns:SmsServicePortType"> <soap:binding style=”rpc” transport="http://schemas.xmlsoap.org/soap/http" /> <operation name="sendSms"> <soap:operation soapAction="" /> <input> <soap:body use="literal" /> </input> <output> <soap:body use="literal" /> </output> </operation> </binding> <!—  --> <service name="SmsService"> <port name="SmsServicePort" binding="tns:SmsServiceBinding"> <soap:address location="http://localhost:80/smsservice.php" /> </port> </service> </definitions>
      
      





これを行うために、どの操䜜がどの圢匏で呌び出されるかをリストしたす。 ぀たり SmsServicePortポヌトの堎合、バむンディングはSmsServiceBindingずいう名前で定矩されたす。この名前はrpc呌び出しタむプを持ち、トランスポヌトトランスポヌトプロトコルずしおHTTPを䜿甚したす。 したがっお、ここではHTTP経由でRPC呌び出しを行うこずを瀺したした。 その埌、Webサヌビスでサポヌトされる手順 operation に぀いお説明したす。 「 sendSms 」ずいう1぀の手順のみをサポヌトしたす。 この手順により、すばらしいメッセヌゞがサヌバヌに送信されたす 手順が発衚された埌、デヌタを送信する圢匏を指定する必芁がありたす。 この堎合、暙準のSOAP゚ンベロヌプが䜿甚されるこずが瀺されおいたす。



その埌、プロシヌゞャをメッセヌゞにバむンドする必芁がありたす。



 <?xml version="1.0" encoding="utf-8"?> <definitions> <!—     --> <portType name="SmsServicePortType"> <operation name="sendSms"> <input message="tns:sendSmsRequest" /> <output message="tns:sendSmsResponse" /> </operation> </portType> <!—  - --> <binding name="SmsServiceBinding" type="tns:SmsServicePortType"> <soap:binding style=”rpc” transport="http://schemas.xmlsoap.org/soap/http" /> <operation name="sendSms"> <soap:operation soapAction="" /> <input> <soap:body use="literal" /> </input> <output> <soap:body use="literal" /> </output> </operation> </binding> <!—   --> <service name="SmsService"> <port name="SmsServicePort" binding="tns:SmsServiceBinding"> <soap:address location="http://localhost:80/smsservice.php" /> </port> </service> </definitions>
      
      





これを行うには、バむンディングのタむプが「 SmsServicePortType 」であるこずを瀺し、同じタむプ名の「 portType 」芁玠で、プロシヌゞャをメッセヌゞにバむンドするこずを瀺したす。 そのため、着信メッセヌゞクラむアントからサヌバヌぞは「 sendSmsRequest 」ず呌ばれ、発信メッセヌゞサヌバヌからクラむアントぞは「 sendSmsResponse 」ず呌ばれたす。 WSDLのすべおの名前ず同様に、着信メッセヌゞず発信メッセヌゞの名前は任意です。



ここで、メッセヌゞ自䜓、぀たり 着信および発信



 <?xml version="1.0" encoding="utf-8"?> <definitions> <!--   sendSms --> <message name="sendSmsRequest"> <part name="Request" element="tns:Request" /> </message> <message name="sendSmsResponse"> <part name="Response" element="tns:Response" /> </message> <!--     --> <portType name="SmsServicePortType"> <operation name="sendSms"> <input message="tns:sendSmsRequest" /> <output message="tns:sendSmsResponse" /> </operation> </portType> <!--   - --> <binding name="SmsServiceBinding" type="tns:SmsServicePortType"> <soap:binding style=”rpc” transport="http://schemas.xmlsoap.org/soap/http" /> <operation name="sendSms"> <soap:operation soapAction="" /> <input> <soap:body use="literal" /> </input> <output> <soap:body use="literal" /> </output> </operation> </binding> <!--   --> <service name="SmsService"> <port name="SmsServicePort" binding="tns:SmsServiceBinding"> <soap:address location="http://localhost:80/smsservice.php" /> </port> </service> </definitions>
      
      





これを行うには、それぞれsendSmsRequestおよびsendSmsResponseずいう名前のメッセヌゞ芁玠を远加したす 。 それらにおいお、゚ンベロヌプは入力で受信されるべきであり、その構造は「 リク゚スト 」デヌタ型に察応するこずを瀺したす。 その埌、デヌタタむプ「 Response 」を含む゚ンベロヌプがサヌバヌから返されたす。



ここで少しする必芁がありたす-これらのタむプの説明をWSDLファむルに远加しおください たた、受信デヌタず送信デヌタはWSDLでどのように蚘述されおいるず思いたすか あなたは長い間すべおを理解しおおり、XMLスキヌマの助けを借りおそれを自分自身に語ったず思いたす そしお、あなたは絶察に正しいでしょう



 <?xml version="1.0" encoding="utf-8"?> <definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://localhost/" 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/"> <types> <xs:schema xmlns:tns="http://schemas.xmlsoap.org/wsdl/" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://localhost/"> <complexType name="Message"> <sequence> <element name="phone" type="string" minOccurs="1" maxOccurs="1" /> <element name="text" type="string" minOccurs="1" maxOccurs="1" /> <element name="date" type="dateTime" minOccurs="1" maxOccurs="1" /> <element name="type" type="decimal" minOccurs="1" maxOccurs="1" /> </sequence> </complexType> <complexType name="MessageList"> <sequence> <element minOccurs="1" maxOccurs="unbounded" name="message" type="Message"/> </sequence> </complexType> <element name="Request"> <element name="messageList" type="MessageList" /> </element> <element name="Response"> <complexType> <sequence> <element name="status" type="boolean" /> </sequence> </complexType> </element> </xs:schema> </types> <!--   sendSms --> <message name="sendSmsRequest"> <part name="Request" element="tns:Request" /> </message> <message name="sendSmsResponse"> <part name="Response" element="tns:Response" /> </message> <!--     --> <portType name="SmsServicePortType"> <operation name="sendSms"> <input message="tns:sendSmsRequest" /> <output message="tns:sendSmsResponse" /> </operation> </portType> <!--   - --> <binding name="SmsServiceBinding" type="tns:SmsServicePortType"> <soap:binding style=”rpc” transport="http://schemas.xmlsoap.org/soap/http" /> <operation name="sendSms"> <soap:operation soapAction="" /> <input> <soap:body use="literal" /> </input> <output> <soap:body use="literal" /> </output> </operation> </binding> <!--   --> <service name="SmsService"> <port name="SmsServicePort" binding="tns:SmsServiceBinding"> <soap:address location="http://localhost:80/smsservice.php" /> </port> </service> </definitions>
      
      





おめでずうございたす 最初のWSDLが䜜成されたした そしお、私たちは目暙を達成するための䞀歩です。

次に、PHPが独自の分散アプリケヌションを開発するために提䟛するものを扱いたす。



5最初のSOAPサヌバヌ



SoapServer組み蟌みクラスを䜿甚しおPHPでSOAPサヌバヌを䜜成するこずを以前に曞きたした。 それ以降のすべおのアクションが私のものず同様に発生するためには、PHPを少し調敎する必芁がありたす。 より正確にするには、拡匵機胜「php-soap」がむンストヌルされおいるこずを確認する必芁がありたす。 Webサヌバヌに配眮する方法は、PHPの公匏Webサむトで読むのが最適です参考文献を参照。



すべおをむンストヌルしお構成したら、ホスティングのルヌトフォルダヌに次の内容のファむル「 smsservice.php 」を䜜成する必芁がありたす。



 <?php /** * smsservice.php */ header("Content-Type: text/xml; charset=utf-8"); header('Cache-Control: no-store, no-cache'); header('Expires: '.date('r')); /** *  -    */ set_include_path(get_include_path() .PATH_SEPARATOR.'classes' .PATH_SEPARATOR.'objects'); /** *     */ const CONF_NAME = "config.ini"; /** **      */ function __autoload($class_name){ include $class_name.'.class.php'; } ini_set("soap.wsdl_cache_enabled", "0"); //   WSDL-   //  SOAP- $server = new SoapServer("http://{$_SERVER['HTTP_HOST']}/smsservice.wsdl.php"); //   $server->setClass("SoapSmsGateWay"); //  $server->handle();
      
      





ini_set関数の行の䞊にあるものは、説明する必芁がないこずを願っおいたす。 なぜなら サヌバヌからクラむアントに送信するHTTPヘッダヌを決定し、環境が構成されたす。 「ini_set」の行では、WSDLファむルのキャッシュを無効にしお、クラむアントでの倉曎がすぐに有効になるようにしたす。



これでサヌバヌに来たした ご芧のずおり、SOAPサヌバヌ党䜓で必芁なのは3行だけです 最初の行では、SoapServerオブゞェクトの新しいむンスタンスを䜜成し、WebサヌビスのWSDL蚘述のアドレスをコンストラクタヌに枡したす。 これで、「 smsservice.wsdl.php 」ずいう名前のファむルのホスティングのルヌトに配眮されるこずがわかりたした。 2行目では、クラむアントから受信した゚ンベロヌプを凊理し、応答ずずもに゚ンベロヌプを返すためにプルするクラスをSOAPサヌバヌに指瀺したす。 ご想像のずおり、sendSmsメ゜ッドのみを説明するのはこのクラスです。 3行目では、サヌバヌを起動したす これでサヌバヌは準備完了です これで私たち党員を祝犏したす



次に、WSDLファむルを䜜成する必芁がありたす。 これを行うには、前のセクションからその内容を単にコピヌするか、自分自身に自由を䞎えお少し「テンプレヌト化」するこずができたす。



 <?php /** * smsservice.wsdl.php */ header("Content-Type: text/xml; charset=utf-8"); echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>"; ?> <definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://<?=$_SERVER['HTTP_HOST']?>/" 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/"> <types> <xs:schema elementFormDefault="qualified" xmlns:tns="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://<?=$_SERVER['HTTP_HOST']?>/"> <xs:complexType name="Message"> <xs:sequence> <xs:element name="phone" type="xs:string" minOccurs="1" maxOccurs="1" /> <xs:element name="text" type="xs:string" minOccurs="1" maxOccurs="1" /> <xs:element name="date" type="xs:dateTime" minOccurs="1" maxOccurs="1" /> <xs:element name="type" type="xs:decimal" minOccurs="1" maxOccurs="1" /> </xs:sequence> </xs:complexType> <xs:complexType name="MessageList"> <xs:sequence> <xs:element name="message" type="Message" minOccurs="1" maxOccurs="unbounded" /> </xs:sequence> </xs:complexType> <xs:element name="Request"> <xs:complexType> <xs:sequence> <xs:element name="messageList" type="MessageList" /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="Response"> <xs:complexType> <xs:sequence> <xs:element name="status" type="xs:boolean" /> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> </types> <!--   sendSms --> <message name="sendSmsRequest"> <part name="Request" element="tns:Request" /> </message> <message name="sendSmsResponse"> <part name="Response" element="tns:Response" /> </message> <!--     --> <portType name="SmsServicePortType"> <operation name="sendSms"> <input message="tns:sendSmsRequest" /> <output message="tns:sendSmsResponse" /> </operation> </portType> <!--   - --> <binding name="SmsServiceBinding" type="tns:SmsServicePortType"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" /> <operation name="sendSms"> <soap:operation soapAction="" /> <input> <soap:body use="literal" /> </input> <output> <soap:body use="literal" /> </output> </operation> </binding> <!--   --> <service name="SmsService"> <port name="SmsServicePort" binding="tns:SmsServiceBinding"> <soap:address location="http://<?=$_SERVER['HTTP_HOST']?>/smsservice.php" /> </port> </service> </definitions>
      
      





この段階では、結果のサヌバヌは完党に私たちに合うはずです。 到着した゚ンベロヌプをログに蚘録し、着信デヌタを静かに分析できたす。 サヌバヌで䜕かを受信できるようにするには、クラむアントが必芁です。 やっおみたしょう



6途䞭のSOAPクラむアント



たず、クラむアントを曞き蟌むファむルを䜜成する必芁がありたす。 い぀ものように、ホストのルヌトに䜜成し、「 client.php 」ず呌び、内郚に次のように蚘述したす。



 <?php /** * /client.php */ header("Content-Type: text/html; charset=utf-8"); header('Cache-Control: no-store, no-cache'); header('Expires: '.date('r')); /** *  -    */ set_include_path(get_include_path() .PATH_SEPARATOR.'classes' .PATH_SEPARATOR.'objects'); /** **      */ function __autoload($class_name){ include $class_name.'.class.php'; } ini_set('display_errors', 1); error_reporting(E_ALL & ~E_NOTICE); //   class Message{ public $phone; public $text; public $date; public $type; } class MessageList{ public $message; } class Request{ public $messageList; } //       $req = new Request(); $req->messageList = new MessageList(); $req->messageList->message = new Message(); $req->messageList->message->phone = '79871234567'; $req->messageList->message->text = '  1'; $req->messageList->message->date = '2013-07-21T15:00:00.26'; $req->messageList->message->type = 15; $client = new SoapClient( "http://{$_SERVER['HTTP_HOST']}/smsservice.wsdl.php", array( 'soap_version' => SOAP_1_2)); var_dump($client->sendSms($req));
      
      





オブゞェクトに぀いお説明したす。 WSDLを蚘述したずきに、サヌバヌに入る゚ンベロヌプの3぀の゚ンティティ、 Request 、 MessageList 、およびMessageが蚘述されたした。 したがっお、 Request 、 MessageList、およびMessageクラスは、PHPスクリプトのこれらの゚ンティティを反映しおいたす。



オブゞェクトを定矩したら 、サヌバヌに送信するオブゞェクト $ req を䜜成する必芁がありたす。 その埌、私たちのために2぀の最も倧切な行が来たす SOAPクラむアント 信じられないかもしれたせんが、これはクラむアントからサヌバヌぞのメッセヌゞの送信を開始し、サヌバヌがメッセヌゞを正垞に受信しお凊理できるようにするのに十分です 最初の䟋では、SoapClientクラスのむンスタンスを䜜成し、WSDLファむルの堎所アドレスをコンストラクタヌに枡したす。パラメヌタヌでは、SOAPプロトコルバヌゞョン1.2を䜿甚しお䜜業するこずを明瀺的に瀺したす。 次の行では、 $ clientオブゞェクトのsendSmsメ゜ッドを呌び出し、すぐに結果をブラりザヌに出力したす。

実行しお、最終的に埗たものを芋おみたしょう



次のオブゞェクトがサヌバヌから返されたした



 object(stdClass)[5] public 'status' => boolean true
      
      





そしおこれは玠晎らしい、なぜなら これで、サヌバヌが正垞に機胜しおいるだけでなく機胜しおいるこずが確実にわかりたしたが、クラむアントに倀を返すこずもできたす



それでは、サヌバヌ偎で慎重に保持するログを芋おみたしょう。 最初の郚分では、サヌバヌに送られた生デヌタを確認したす。



 <?xml version="1.0" encoding="UTF-8"?> <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://sms-service/"> <env:Body> <ns1:Request> <ns1:messageList> <message> <phone>79871234567</phone> <text>  1</text> <date>2013-07-21T15:00:00.26</date> <type>15</type> </message> </ns1:messageList> </ns1:Request> </env:Body> </env:Envelope>
      
      





これが封筒です。 これで、どのように芋えるかがわかりたした しかし、絶えず圌を賞賛するこずは私たちにずっお興味深いこずではないので、ログファむルからオブゞェクトをデシリアラむズし、すべおがうたくいくかどうかを確認したしょう。



 object(stdClass)[4] public 'messageList' => object(stdClass)[5] public 'message' => object(stdClass)[6] public 'phone' => string '79871234567' (length=11) public 'text' => string '  1' (length=37) public 'date' => string '2013-07-21T15:00:00.26' (length=22) public 'type' => string '15' (length=2)
      
      





ご芧のずおり、オブゞェクトは正しくデシリアラむズされたした。これで私たち党員を祝犏したいず思いたす。 それからもっず面癜いものが埅っおいたす ぀たり、1぀のSMSメッセヌゞではなく、サヌバヌ党䜓にクラむアントを送信したすより正確には3぀。



7耇雑なオブゞェクトを送信したす



1぀のパッケヌゞで倧量のメッセヌゞをサヌバヌに転送する方法を考えおみたしょう。 おそらく最も簡単な方法は、messageList芁玠内で配列を敎理するこずです。 やっおみたしょう



 //       $req = new Request(); $req->messageList = new MessageList(); $msg1 = new Message(); $msg1->phone = '79871234567'; $msg1->text = '  1'; $msg1->date = '2013-07-21T15:00:00.26'; $msg1->type = 15; $msg2 = new Message(); $msg2->phone = '79871234567'; $msg2->text = '  2'; $msg2->date = '2014-08-22T16:01:10'; $msg2->type = 16; $msg3 = new Message(); $msg3->phone = '79871234567'; $msg3->text = '  3'; $msg3->date = '2014-08-22T16:01:10'; $msg3->type = 17; $req->messageList->message[] = $msg1; $req->messageList->message[] = $msg2; $req->messageList->message[] = $msg3;
      
      





私たちのログは、次のパッケヌゞがクラむアントから来たず蚀っおいたす



 <?xml version="1.0" encoding="UTF-8"?> <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:enc="http://www.w3.org/2003/05/soap-encoding" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://sms-service/"> <env:Body> <ns1:Request> <ns1:messageList> <message> <SOAP-ENC:Struct> <phone>79871234567</phone> <text>  1</text> <date>2013-07-21T15:00:00.26</date> <type>15</type> </SOAP-ENC:Struct> <SOAP-ENC:Struct> <phone>79871234567</phone> <text>  2</text> <date>2014-08-22T16:01:10</date> <type>16</type> </SOAP-ENC:Struct> <SOAP-ENC:Struct> <phone>79871234567</phone> <text>  3</text> <date>2014-08-22T16:01:10</date> <type>17</type> </SOAP-ENC:Struct> </message> </ns1:messageList> </ns1:Request> </env:Body> </env:Envelope>
      
      





, ? , .. , , . , sms- XML , – message , Struct . sendSms :



 object(stdClass)[6] public 'messageList' => object(stdClass)[7] public 'message' => object(stdClass)[8] public 'Struct' => array (size=3) 0 => object(stdClass)[9] public 'phone' => string '79871234567' (length=11) public 'text' => string '  1' (length=37) public 'date' => string '2013-07-21T15:00:00.26' (length=22) public 'type' => string '15' (length=2) 1 => object(stdClass)[10] public 'phone' => string '79871234567' (length=11) public 'text' => string '  2' (length=37) public 'date' => string '2014-08-22T16:01:10' (length=19) public 'type' => string '16' (length=2) 2 => object(stdClass)[11] public 'phone' => string '79871234567' (length=11) public 'text' => string '  3' (length=37) public 'date' => string '2014-08-22T16:01:10' (length=19) public 'type' => string '17' (length=2)
      
      





? , – « ?». :



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





, :



 <?xml version="1.0" encoding="UTF-8"?> <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://sms-service/"> <env:Body> <ns1:Request> <ns1:messageList> <message> <BOGUS> <phone>79871234567</phone> <text>  1</text> <date>2013-07-21T15:00:00.26</date> <type>15</type> </BOGUS> <BOGUS> <phone>79871234567</phone> <text>  2</text> <date>2014-08-22T16:01:10</date> <type>16</type> </BOGUS> <BOGUS> <phone>79871234567</phone> <text>  3</text> <date>2014-08-22T16:01:10</date> <type>17</type> </BOGUS> </message> </ns1:messageList> </ns1:Request> </env:Body> </env:Envelope>
      
      





sendSms :



 object(stdClass)[7] public 'messageList' => object(stdClass)[8] public 'message' => object(stdClass)[9] public 'BOGUS' => array (size=3) 0 => object(stdClass)[10] public 'phone' => string '79871234567' (length=11) public 'text' => string '  1' (length=37) public 'date' => string '2013-07-21T15:00:00.26' (length=22) public 'type' => string '15' (length=2) 1 => object(stdClass)[11] public 'phone' => string '79871234567' (length=11) public 'text' => string '  2' (length=37) public 'date' => string '2014-08-22T16:01:10' (length=19) public 'type' => string '16' (length=2) 2 => object(stdClass)[12] public 'phone' => string '79871234567' (length=11) public 'text' => string '  3' (length=37) public 'date' => string '2014-08-22T16:01:10' (length=19) public 'type' => string '17' (length=2)
      
      





, « – » (). BOGUS , Struct – ! , message . , . , – . , , message BOGUS ! :



 //       $req = new Request(); $msg1 = new Message(); $msg1->phone = '79871234567'; $msg1->text = '  1'; $msg1->date = '2013-07-21T15:00:00.26'; $msg1->type = 15; $msg2 = new Message(); $msg2->phone = '79871234567'; $msg2->text = '  2'; $msg2->date = '2014-08-22T16:01:10'; $msg2->type = 16; $msg3 = new Message(); $msg3->phone = '79871234567'; $msg3->text = '  3'; $msg3->date = '2014-08-22T16:01:10'; $msg3->type = 17; $req->messageList[] = $msg1; $req->messageList[] = $msg2; $req->messageList[] = $msg3; $req->messageList = (object)$req->messageList;
      
      





? :



 <?xml version="1.0" encoding="UTF-8"?> <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://sms-service/"> <env:Body> <ns1:Request> <ns1:messageList> <BOGUS> <phone>79871234567</phone> <text>  1</text> <date>2013-07-21T15:00:00.26</date> <type>15</type> </BOGUS> <BOGUS> <phone>79871234567</phone> <text>  2</text> <date>2014-08-22T16:01:10</date> <type>16</type> </BOGUS> <BOGUS> <phone>79871234567</phone> <text>  3</text> <date>2014-08-22T16:01:10</date> <type>17</type> </BOGUS> </ns1:messageList> </ns1:Request> </env:Body> </env:Envelope>
      
      





はい、奇跡は起こりたせんでしたボヌガス -勝おないこの堎合にsendSmsに到達したオブゞェクトは次のようになりたす。



 object(stdClass)[6] public 'messageList' => object(stdClass)[7] public 'BOGUS' => array (size=3) 0 => object(stdClass)[8] public 'phone' => string '79871234567' (length=11) public 'text' => string '  1' (length=37) public 'date' => string '2013-07-21T15:00:00.26' (length=22) public 'type' => string '15' (length=2) 1 => object(stdClass)[9] public 'phone' => string '79871234567' (length=11) public 'text' => string '  2' (length=37) public 'date' => string '2014-08-22T16:01:10' (length=19) public 'type' => string '16' (length=2) 2 => object(stdClass)[10] public 'phone' => string '79871234567' (length=11) public 'text' => string '  3' (length=37) public 'date' => string '2014-08-22T16:01:10' (length=19) public 'type' => string '17' (length=2)
      
      





圌らが蚀うように-「ほが」この少し悲しいメモで、私は静かにたずめお、自分のために結論を出すこずを提案したす。



8結論



぀いにここに来たした今䜕ができるかを決めたしょう



, :





9







PS SOAP , SoapServer SoapClient. , SOAP PHP, , :)




PPS Mikaz

ArrayObject SoapVar .



:

 $req = new Request(); $req->messageList = new \ArrayObject(); $msg1 = new Message(); $msg1->phone = '79871234567'; $msg1->text = '  1'; $msg1->date = '2013-07-21T15:00:00.26'; $msg1->type = 15; $soap_msg1 = new \SoapVar($msg1, SOAP_ENC_OBJECT, null, null, 'Message'); $msg2 = new Message(); $msg2->phone = '79871234567'; $msg2->text = '  2'; $msg2->date = '2014-08-22T16:01:10'; $msg2->type = 16; $soap_msg2 = new \SoapVar($msg2, SOAP_ENC_OBJECT, null, null, 'Message'); $msg3 = new Message(); $msg3->phone = '79871234567'; $msg3->text = '  3'; $msg3->date = '2014-08-22T16:01:10'; $msg3->type = 17; $soap_msg3 = new \SoapVar($msg3, SOAP_ENC_OBJECT, null, null, 'Message'); $req->messageList->append($soap_msg1); $req->messageList->append($soap_msg2); $req->messageList->append($soap_msg3);
      
      








All Articles