xml|リモートサービス
PHP で XML テクノロジーを使用してリモート サービスを構築します
将来の Web はサービス中心の Web になり、XML_RPC 標準によりサービスの作成と適用が非常に簡単になります。この記事では、XML_RPC 標準とその PHP 実装を紹介し、例を通じて PHP で XML_RPC サービスとクライアント プログラムを開発する方法を示します。
1. サービス Web
コンテンツ プロバイダーが採用するシンプルな手法から、UDDI (Universal description、Discovery、Integration) の将来ビジョンに至るまで、業界では「サービス Web」について多くの説明やコメントが行われています。 Web の初期段階では、Web は単なる文書の収集および配布センターであり、閲覧可能な情報のみを提供していました。 Web の発展に伴い、Web 上でのサービスの実行はますます魅力的になってきています。将来的には、Web は企業が顧客や他の企業に便利なサービスを提供する媒体となるでしょう。 B2B モデルと B2C モデル間のコラボレーションは、サービス指向の Web とみなすことができます。
非常に重要な質問は、Web 上でどのようなサービスを提供できるかということです。 Web は多くのサービスを提供できますが、その中には現在すでに使用されているサービスもあれば、近い将来登場するサービスもあります。問題を説明するために、Web を通じて提供できるサービスの小さなリストを以下に示します:
トピック指向の垂直型検索エンジン。
ユーザーが情報を見つけるためのナレッジベース。
ユーザーが質問できるエキスパートシステム。
銀行サービス。
ニュースおよび情報公開サービス。
デジタル決済関連サービス。
グラフィック処理サービス。
健康とウェルネスのサービス。
では、企業や組織が Web を通じてサービスを提供する正しい方法は何でしょうか?これは非常に重要な質問です。現在、一部のサービスでは HTML インターフェイスが提供され、ドキュメント形式でサービスが提供されていますが、サービス インターフェイスの背後には何が隠されているのでしょうか。 Web を引き継ぐ競争に参加しているのは Web ブラウザだけではありません。携帯電話、ハンドヘルド デバイス、電子レンジなどのデバイスはすべて、Web へのアクセス、データベースのクエリ、データの変換、情報の抽出などを望んでいます。真のサービス Web を実現するには、プレゼンテーション層 (HTML) の下に別の層が必要です。
2. XML_RPC 標準
XML は、企業がサービス環境を構築するための基礎となる標準です。サービス付き Web を構築するには、XML_RPC 標準を学ぶ必要があります。これは、XML_RPC が Web 上にサービスを配置するのに役立つだけでなく、XML_RPC が既に確立されている標準であり、簡単に採用できるためでもあります。 B2Bサービスにおいては、サービスを提供するための基準が非常に重要であり、その基準を遵守する企業は、他社が提供するサービスを活用することで急成長を遂げることができます。真にサービスを提供する Web がさまざまな民間サービス標準に基づいて構築できることを想像することは不可能です。サービスには従うことができる標準が必要です。
XML_RPC は、インターネット分散処理の標準です。 RPC は、Remote Procedure Call の略語で、他のマシン上に存在し、他の言語で記述されたプロシージャを呼び出すために使用されるリモート呼び出しメカニズムです。リモート プロシージャ コールは、分散コンピューティングの重要な柱です。たとえば、分散コンピューティング環境では、他のマシン上で実行される加算および減算演算を実行するプロセスを見つけて利用できます。加算演算を実行するプロセスは APL で記述され、RS6000 マシン上で実行されます。減算演算 おそらく C で書かれ、Unix 上で実行されます。このような分散計算機を使用したい他の開発者もそれらを使用することも、別のより優れた計算機を選択することもできます。
RPC ではプロシージャが最も重要なコンポーネントであり、サーバーはクライアントが呼び出すためのプロセスを提供します。プロシージャはパラメータを受け取り、結果を返すことができます。 XML_RPC は、プロトコル キャリアとして HTTP を使用し、データを送受信するための XML ボキャブラリを通じて RPC メカニズムを実装します。 XML_RPC サーバーは XML_RPC 要求を受信して XML_RPC 応答を返し、XML_RPC クライアントは XML_RPC 要求を送信して XML_RPC 応答を受信します。サーバーとクライアントは、XML_RPC 標準の要件に従って応答と要求を処理する必要があります。
3. XML_RPC プロトコル
完全な XML_RPC 仕様は、http://www.xmlrpc.com/spec で参照できます。以下にその要点を解説します。
3.1 XML_RPC リクエスト
XML_RPC リクエストは HTTP POST リクエストである必要があり、その本文は XML 形式です。リクエストの XML 部分の形式は次のとおりです:
</param>
</params>
</methodCall>
データの送信先を指定する URL はここでは指定されません。サーバーが RPC 処理専用の場合は、「/」になる可能性があります。上記の XML ドキュメントのペイロードは「methodCall」構造です。 MethodCall には、呼び出されるメソッドを説明する文字列を含む「methodName」サブ要素が含まれている必要があります。 「methodName」の内容をどのように解釈するかは完全にサーバー次第です。たとえば、実行可能ファイルの名前、データベース内のレコードの名前、またはその他の名前にすることができます。プロシージャがパラメータを受け入れる場合、「methodCall」には「params」要素といくつかの「param」子要素を含めることができます。各「param」要素には、型記述子を含む値が含まれます。型記述子は次の表に示すとおりです。
マークの説明
<i4> または <int> 12 などの 4 バイトの符号付き整数
<boolean > 0 (false)、または 1 (true)
<base64> eW91IGbid0IHJlQgdGhpcyE などの、base64 でエンコードされたバイナリ データ
3.1.1 構造体
値は構造体にすることができ、その構造体は
3.1.2 配列
値は配列型にすることができ、配列は
<array>
<data>
<value><boolean>0</boolean></value>
<value><i4>9</i4></value>
3.2 XML_RPC レスポンス
XML_RPC レスポンスは HTTP レスポンスであり、コンテンツタイプは text/xml です。レスポンスボディの形式は以下のとおりです。
<?xml version="1.0"?>
<methodResponse>
<params>
<param>
<value><string>ABCDEFG</string></value>
</param>
</params>
</methodResponse>
<値><int>4</int></value>
</member>
<member>
<name>faultString</name>
<value><string>Error!</string ></value>
< /member>
</struct>
</value>
</fault>
4. XML_RPCをベースにしたWebサービス
サービスの構築や利用にはXML_RPCを使うととても便利です。企業は、自社が提供するさまざまなサービスのために XML_RPC サーバーを展開し、ユーザー、クライアント ソフトウェア、およびクライアント企業はこのサービスを使用して、エンド ユーザー向けのハイエンド サービスやアプリケーションを構築できます。より効果的で、安価で、高品質なサービスを提供するためのこの競争により、アプリケーション サービスの品質が大幅に向上します。
しかし、Web 上でサービスをカタログ化、インデックス付け、検索する方法など、解決すべき問題がまだいくつかあります。 UDDI はこの問題の解決を試みていますが、標準は単純ではなく、それに対する業界の対応も不透明です。ただし、XML_RPC を企業内に適用すると、コードの再利用性が向上するだけでなく、今後数年間で重要な知識の宝となる新しい分散コンピューティング モデルがもたらされます。 XML_RPC の開発は、分散コンピューティングの問題を解決することから始まり、サービス Web の基本レベルとなり、非常に良いスタートを切りました。この標準に対する人々の熱意は確実に続くでしょう。ここでは、XML_RPC の実際の応用を見てみましょう。
4.1 PHP で XML_RPC を適用する
PHP は、Web サービスを提供するための理想的な言語です。 PHP コードを記述して適切な場所に配置するだけで、URL を通じて「呼び出す」ことができるサービスがすぐに作成されます。 PHP での XML_RPC 実装は複雑な場合もあれば単純な場合もありますが、多くのオプションがあります。ここでは、Useful Information Company の XML_RPC 実装を選択します。そのコードとドキュメントは http://xmlrpc.usefulinc.com/ からダウンロードできます。
この XML_RPC 実装の基本クラスには 2 つのファイルが含まれます:
xmlrpc.inc: XML_RPC の php クライアントに必要なクラスが含まれます
xmlrpcs.inc: XML_RPC の php サーバーに必要なクラスが含まれます
4.2 クライアント
XML_RPC クライアントの作成とは、次のことを意味します:
1. XML_RPC リクエスト メッセージを作成します
2. XML_RPC メッセージを作成します
4. 応答を取得します
6.応答を解釈します
次の例を参照してください:
<?php
$f=new xmlrpcmsg('examples.getStateName',array(new xmlrpcval(14, "int")));
$c=new xmlrpc_client( "/RPC2 ", "betty.userland.com", 80);
$r=$c->send($f);
$v=$r->value();
if (!$r ->faultCode()) {
print "ステータスコード" . $HTTP_POST_VARS["stateno"] .
$v->scalarval() "
はサーバーのResponse<BR><PRE>" .<br>htmlentities($r->serialize()). "</PRE><HR>n";
} else {
print "エラー: ";
print "コード: " . $r->faultCode() .
" 理由: '" .$r->faultString()."'
";
}
?>
この例では、まず、 create 「examples.getStateName」メソッドを呼び出し、値が 14 の「int」型の整数パラメータを渡す XML_RPC メッセージ。次に、呼び出される URL (パス、ドメイン、ポート) を記述するクライアントを作成します。次に、メッセージを送信し、応答オブジェクトを受信して、エラーをチェックしました。エラーがなければ結果を表示します。
RPC クライアント プログラムを作成するときに使用される主な関数は次のとおりです:
クライアントを作成するには:
$client=new xmlrpc_client($server_path, $server_hostname, $server_port);
メッセージの送信方法は次のとおりです。
$response=$client->send($xmlrpc_message);
xmlrpcresp のインスタンスを返します。渡すメッセージは、次のメソッドで作成された xmlrpcmsg のインスタンスです:
$msg=new xmlrpcmsg($methodName, $parameterArray);
methodName は呼び出されるメソッド (プロセス) の名前です。 parameterArray は、xmlrpcval オブジェクトの PHP 配列です。例:
$msg=new xmlrpcmsg("examples.getStateName", array(new xmlrpcval(23, "int")));
xmlrpcval オブジェクトは次の形式で作成できます:
<?php
$ myVal=new xmlrpcval($stringVal);
$myVal=new xmlrpcval($scalarVal, "int" | "boolean" | "string" | "double" | "dateTime.iso8601" | "base64");
$myVal= new xmlrpcval( $arrayVal, "array" | "struct");
?>
最初の形式は、xmlrpc 文字列値を作成します。 2 番目の形式は、値と型を説明する値を作成します。 3 番目の形式は、配列のような構造で他の xmlrpc 値を結合することによって複雑なオブジェクトを作成します。例:
<?php
$myArray=new xmlrpcval(array(new xmlrpcval("Tom"), new xmlrpcval("Dick) "),new xmlrpcval("Harry")), "array");
$myStruct=new xmlrpcval(array(
"name" => new xmlrpcval("Tom"),
"age" => new xmlrpcval (34, "int"),
"geek" => new xmlrpcval(1, "boolean")),"struct");
?>
の send メソッドを呼び出すことで、応答オブジェクトは xmlrpcresp 型になります。顧客オブジェクトを取得します。サーバー側では、次のように xmlrpcresp 型のオブジェクトを作成できます:
$resp=new xmlrpcresp($xmlrpcval); クライアント側では、次のメソッドを使用して応答から xmlrpcval を取得します:
$xmlrpcVal =$resp ->value();
次に、次のメソッドを使用して、応答結果を記述する PHP 変数を取得できます。
$scalarVal=$val->scalarval(); 複雑なデータ型の場合、非常に便利な関数が 2 つあり、どちらも xmlrpc.inc にあります:
$arr=xmlrpc_decode($xmlrpc_val);
この関数は、xmlrpcval 変数 $xmlrpc_val のデータを含む PHP 配列を返します。 PHP自体が持つ変数型に変換されています。
$xmlrpc_val=xmlrpc_encode($phpval);
この関数は、$phpval で記述された PHP データを含む xmlrpcval 型の値を返します。配列と構造体の場合、このメソッドにより再帰的分析が可能になります。非基本データ型 (base-64 データや日付時刻データなど) はサポートされていないことに注意してください。
4.3 サーバーサイド
xmlrpcs.inc が提供するクラス作成サービスを使用するのは非常に簡単です。サービスを作成するには、次のように xmlrpc_server のインスタンスを作成します:
<?php
$s=new xmlrpc_server( array("examples.myFunc" =>
array("function" => "foo")) );
?>
xmlrpc_server コンストラクターに渡されるのは、連想配列の連想配列です。プロシージャ「examples.myFunc」は「foo」関数を呼び出します。このため、foo はメソッド ハンドルと呼ばれます。
メソッドハンドルの記述は簡単です。メソッド ハンドルのスケルトンは次のとおりです:
<?php
function foo ($params) {
global $xmlrpcerruser; // ユーザー エラー コード値を導入します
// $params は xmlrpcval オブジェクトの配列です
if ( $err) {
// エラー条件
return new xmlrpcresp(0, $xmlrpcerruser+1, // ユーザーエラー 1
"Error!");
} else {
// 成功
return new xmlrpcresp(new xmlrpcval("わかりました!" , "string"));
}
}
?>
プログラムがエラーをチェックし、エラーがある場合はエラーを返していることがわかります ($xmlrpcerruser+1 から開始)。それ以外の場合、すべてが正常であれば、成功メッセージとして説明操作 xmlrpcresp が返されます。
5. アプリケーション例
次の例では、サービスを構築します。指定された値 n に対して、サービスは n*2 を返します。クライアントはこのサービスを使用して 5*2 の値を計算します。
サーバー側のコードは次のとおりです:
include("xmlrpc.inc");
include("xmlrpcs.inc");
function foo ($params)
{
global $xmlrpcerruser; // ユーザーの紹介 エラー コード値
// $params は xmlrpcval オブジェクトの配列です
$vala=$params->params[0];
$sval=$vala->scalarval();
$ret=$ sval*2;
return new xmlrpcval($ret, "int"));
}
$s=new xmlrpc_server( array("product" =>
array("function" =>"foo") )));
?>
クライアントコードは次のとおりです:
<?php
include("xmlrpc.inc");
if ($HTTP_POST_VARS["number"]!="") {
$ f=new xmlrpcmsg(' product',array(new xmlrpcval($HTTP_POST_VARS["number"], "int")));
$c=new xmlrpc_client("/xmlrpc/servfoo.php", "luigi.melpomenia. com.ar", 80 );
$c->setDebug(0);
$r=$c->send($f);
$v=$r->value();
if ( !$r->faultCode()) {
print "数値 ". $HTTP_POST_VARS["数値"] . " は " .
$v->scalarval() ";
print "
" .<br>htmlentities($r->serialize()). "
n";
} else {
print "操作が失敗しました: ";
print "コード: " . $r->faultCode() .
" 理由: '" .$r->faultString()."'
";
}
}
print "