PHP / SOAP - 尝试学习,但实现有问题

时间:2010-02-12 17:22:13

标签: php soap nusoap

我正在尝试自学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

这就是我难倒的地方......

有什么想法吗?

ħ

3 个答案:

答案 0 :(得分:3)

thread可能会对您有所帮助,尤其是回答#9和#10。

答案 1 :(得分:1)

我曾经是使用PHP3 / 4的nusoap的粉丝(也就是当PHP没有内置的SOAP客户端时)但是使用PHP5的SOAP客户端我发现这些天我没有任何需要nusoap。

PHP5内置的SOAP客户端的一个优点是它实现起来更清晰,更简单,所以提及它可能对你有帮助(我知道有些人选择使用nusoap,但很多人显然不是意识到它存在于PHP5中,因为很多“HOWTO”指南已经过时而忽略了它。)

使用示例:

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服务,理想情况下,您希望实现Document / Literal服务,而不是RPC / Encoded服务,因为RPC / Encoded是一种难以使用的格式,因此已被弃用WS-I支持Document / Literal(在设计中更易于使用和更合理)。

首先,如果可以,您可能希望尝试针对现有服务实施客户端 - 这样您就知道它至少可以正常工作,这可能会让您感到头疼。

不幸的是 - 虽然它非常适合消费它们 - 但PHP并没有特别支持提供文档/文字服务。这个IIRC至少有一个第三方类似nusoap的图书馆,但它并没有为我完全削减它。

(如果其中任何一个已过时,欢迎更正。)

答案 2 :(得分:0)

以防一些googlers发现这个...

我按照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);
?>