0

スキルセットを少し拡張するためだけに、SOAP を独学で学ぼうとしていますが、壁にぶつかり、親切な開発者が助けてくれるかどうか疑問に思っていました。

サーバーを次のようにセットアップしました。

http://www.domain1.com/server.php

<?php
// Pull in the NuSOAP code
require_once('soap/nusoap.php');
// Create the server instance
$server = new soap_server();
// Initialize WSDL support
$server->configureWSDL('hellowsdl', 'urn:hellowsdl');
// Register the method to expose
$server->register('hello',    // method name
 array('name' => 'xsd:string'),  // input parameters
 array('return' => 'xsd:string'), // output parameters
 'urn:hellowsdl',     // namespace
 'urn:hellowsdl#hello',    // soapaction
 'rpc',        // style
 'encoded',       // use
 'Says hello to the caller'   // documentation
);
// Define the method as a PHP function
function hello($name) {
        return 'Hello, ' . $name;
}
// Use the request to (try to) invoke the service
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$server->service($HTTP_RAW_POST_DATA);
?>

そして今、別のサーバーにクライアントをセットアップしようとしました:

http://www.domain2.com/client.php

<?php
// Pull in the NuSOAP code
require_once('soap/nusoap.php');
// Create the client instance
$client = new soapclient('http://domain.com/server.php?wsdl', true);
// Check for an error
$err = $client->getError();
if ($err) {
 // Display the error
 echo '<h2>Constructor error</h2><pre>' . $err . '</pre>';
 // At this point, you know the call that follows will fail
}
// Call the SOAP method
$result = $client->call('hello', array('name' => 'Scott'));
// Check for a fault
if ($client->fault) {
 echo '<h2>Fault</h2><pre>';
 print_r($result);
 echo '</pre>';
} else {
 // Check for errors
 $err = $client->getError();
 if ($err) {
  // Display the error
  echo '<h2>Error</h2><pre>' . $err . '</pre>';
 } else {
  // Display the result
  echo '<h2>Result</h2><pre>';
  print_r($result);
 echo '</pre>';
 }
}
// Display the request and response
echo '<h2>Request</h2>';
echo '<pre>' . htmlspecialchars($client->request, ENT_QUOTES) . '</pre>';
echo '<h2>Response</h2>';
echo '<pre>' . htmlspecialchars($client->response, ENT_QUOTES) . '</pre>';
// Display the debug messages
echo '<h2>Debug</h2>';
echo '<pre>' . htmlspecialchars($client->debug_str, ENT_QUOTES) . '</pre>';
?>

しかし、私はクソなことを働かせることができません。サーバーは問題なく表示されます-wdslはロットを出力します。しかし、クライアントは接続できず、トランザクションを完了できません。次のメッセージが表示されます。

Warning: SoapClient::SoapClient() expects parameter 2 to be array, boolean given in /home/public_html/slidebank_soap_client.php on line 5

Fatal error: Uncaught SoapFault exception: [Client] SoapClient::SoapClient() [<a href='soapclient.soapclient'>soapclient.soapclient</a>]: Invalid parameters in /home/soap/slidebank_soap_client.php:5 Stack trace: #0 /home/soap/slidebank_soap_client.php(5): SoapClient->SoapClient('http://testing....', true) #1 {main} thrown in /home/public_html/soap/slidebank_soap_client.php on line 5

そして、ここで私は困惑しています...

何か案は?

H

4

3 に答える 3

3

このスレッドは、特に #9 と #10 の回答に役立ちます。

于 2010-02-12T17:57:37.793 に答える
1

私は以前、PHP3/4 で nusoap を使用するのが好きでしたが (つまり、PHP に SOAP クライアントが組み込まれていませんでした)、PHP5 の SOAP クライアントでは、最近では nusoap は必要ありません。

PHP5 のビルトイン SOAP クライアントの利点は、実装がはるかにクリーンで簡単であることです。そのため、参考になるかもしれませんので、それについて言及します (代わりに nusoap を使用することを選択する人もいますが、多くの人は、それがそこにあることに気付いていないようです。多くの "HOWTO" ガイドが古く、言及することを怠っているため、PHP5 ではこれを参照してください)。

使用例:

ini_set("soap.wsdl_cache_enabled", "1"); // Set to zero to avoid caching WSDL
$soapClient = new SoapClient('http://www.example.com/webservices/HelloWorldService/?wsdl");     
$result = $soapClient->HelloWorldMethod(array('string' => "hello!"));    
print_r($result);

サービスの種類に関する注意事項:

SOAP サービスに関して言えば、RPC/Encoded サービスではなく Document/Literal サービスを実装するのが理想的です。RPC/Encoded は扱いにくい形式であり、そのため WS-I によって非推奨にされているためです。 Document/Literal を優先します (これは、操作がはるかに簡単で、設計がより論理的です)。

まず、可能であれば、既存のサービスに対してクライアントを実装してみることをお勧めします。これにより、少なくとも適切に機能していることを確認でき、頭痛の種を減らすことができます。

残念ながら、PHP はドキュメント/リテラル​​ サービスの提供に関しては特に優れたサポートを提供していません。この IIRC には少なくとも 1 つのサードパーティ製の nusoap に似たライブラリがありますが、私には十分ではありませんでした。

(これが古くなっている場合は、修正を歓迎します。)

于 2010-02-12T17:39:16.947 に答える
0

一部のグーグルがこれを見つけた場合に備えて...

cchenesonが提案したようにphp.iniを編集しましたが、このコードは同じ開発サーバーでも問題なく機能しました。

クライアント-PHPモードのDrupalページに基づいています:

<?php
# URL for the service WSDL
ini_set("soap.wsdl_cache_enabled", "0"); // Set to zero to avoid caching WSDL
try {
    // Get a service proxy from the WSDL
    $proxy = new SoapClient('http://testing.domain.com/soap.php?wsdl');
    global $user;
    if (is_array($user->roles) && in_array('group1', array_values($user->roles))) {
        // User is logged in and is in the usergroup, perform login
        $id = $user->uid;
        $key = 1234; 
        $hashgenerator = $key . "xyz" . $id . "randomstringhere";
        $hash = sha1($hashgenerator);
        // Call a method on the service via the proxy
        $result = $proxy->handshake($id, $key, $hash);
        if ($hash==$result) {
            //Send all user details
            profile_load_profile($user);
            $email = $user->mail;
            $fname = $user->{profile_firstname};
            $lname = $user->{profile_lastname};
            $phone = $user->{profile_phone};
            $fax = $user->{profile_fax};
            $dept = "Speakers";
            $role = "Speakers";
            //Send request
            $authresult = $proxy->authlogin($id, $email, $fname, $lname, $phone, $fax, $authgroup);
            if ($authresult=='ok') {
                //Logged in, show them the page
                $_SESSION['loggedin'] = 1;
            } else {
                echo "Error 3";         
            }
        } else {
            echo "Error 2"; 
        }
    } else {
        echo "Error 1"; 
    }
} catch(SoapFault $ex) {
    echo 'Error: ';
    if ($ex->getMessage() != '') {
        echo $ex->getMessage();
    } else {
        echo $ex . "\n";
    }
}
?>

サービス:

<?php
//----------------------------------//
// This file is a dummy service It obviously does nothing with the data, but i needed it to build my client scripts and so it might give you a hand returning the correct strings.
//----------------------------------//

// Pull in the NuSOAP code
require_once('nusoap/nusoap.php');
// Create the server instance
$server = new soap_server();
// Initialize WSDL support
$server->configureWSDL('WDSL', 'urn:WDSL');
// Register the methods to expose
$server->register('handshake',              // method name
    array('id' => 'xsd:string', 
          'key' => 'xsd:string',
          'hash' => 'xsd:string'),          
    array('return' => 'xsd:string'),        // output parameters
    'urn:WDSL',                             // namespace
    'urn:WDSL#_handshake',                  // soapaction
    'rpc',                                  // style
    'encoded',                              // use
    'Initial handshake'                     // documentation
);
$server->register('authlogin',              // method name
    array('id' => 'xsd:string',             // User ID
          'email' => 'xsd:string',          // User email address
          'fname' => 'xsd:string',          // User first name
          'lname' => 'xsd:string',          // User last name
          'phone' => 'xsd:string',          // User phone
          'fax' => 'xsd:string',            // User fax 
          'dept' => 'xsd:string',           // SB department
          'role' => 'xsd:string'),          // SB role  
    array('return' => 'xsd:string'),        // output parameters
    'urn:WDSL',                             // namespace
    'urn:WDSL#authlogin',                   // soapaction
    'rpc',                                  // style
    'encoded',                              // use
    'Authentication of a user'              // documentation
);
// Define the method as a PHP function
function slidebank_handshake($uid, $key, $hash) {
    //returns the same hash string for confirmation. No need to pass UID again.
    $hashgenerator = $key . "xyz" . $uid . "randomstringhere";  
    $hash = sha1($hashgenerator);
    return $hash;
}
// Define the method as a PHP function
function slidebank_authlogin($id, $email, $fname, $lname, $phone, $fax, $dept, $role) {
    //logic to log user in and capture details etc
    return 'ok'; //options = ok or fail
}
// Use the request to (try to) invoke the service
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$server->service($HTTP_RAW_POST_DATA);
?>
于 2010-02-15T15:27:23.100 に答える