php 中的 SOAP 没有 return 来自 MySql 的值

SOAP in php doesn't return values from MySql

我目前正在开发 PHP 和 MySQL 中开发的 WebService。
我用 C# 和 WPF 开发的应用程序正在使用这些服务。

我的 SOAP 服务器正在使用 PDO 访问数据库记录。
问题
当我尝试从我的应用程序访问网络服务时,我没有从数据库中获得任何结果。
这是我的 C# 应用程序尝试检索一些信息的示例:

bool result;
try
{
    PADR_API.PADR_APIWSClient client = new PADR_API.PADR_APIWSClient();
    string friends = client.GetFirendsList(8);        
}
catch (Exception ex)
{
    string i = ex.Message;//excuse this attempt but I am desperate to find the cause
    throw;
}
return result;  

然而,我在响应中得到的只是我的测试消息。
这是来自我的 SOAP 服务器的 PHP 代码:

public function GetFirendsList($id){
    $response = new getFreindsListResponse();
    $response->return = 'test of a message with following ';
    $response->return .= 'friends: ';
    $pdo = new PDO('mysql:host=localhost;dbname=****', $user, $pwd);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $stmt = $pdo->prepare("SELECT id,friends FROM PADR_users WHERE id = :id");
    $stmt->bindValue(':id', $id, PDO::PARAM_INT);
    $stmt->execute();
//        foreach ($stmt as $row) {
//            $response->return .= $row['friends'];
//        }
    while ($row = $stmt->fetch()) {
        $response->return .= $row['friends'];
    }
    //$response->return = var_dump($stmt);
    //$response->return = $pdo->errorInfo()[0];
    //$response->return = $res;
    return $response;
}

下面是我如何设置 SOAP 服务器的代码:

$options=array('cache_wsdl'=> WSDL_CACHE_NONE);
//create a new SOAP server
$server = new SoapServer('PADRAPIWS.wsdl', $options);//,$options
//attach the API class to the SOAP Server
$server->setClass('PADR_APIWS');
//start the SOAP requests handler
$server->handle();

我也试过使用 PHP SOAPClient

$options = array(//'location' => 'http://localhost/index.php', 
            'uri' => 'http://localhost/',
            'trace' => 1, 
            'exceptions' => true, 
            'cache_wsdl' => WSDL_CACHE_NONE, 
            'features' => SOAP_SINGLE_ELEMENT_ARRAYS);
$client = new SoapClient('http://padr.orgfree.com/index.php?wsdl', $options);
$client->__setLocation('http://padr.orgfree.com/index.php');
//var_dump($client);
var_dump($client->__getFunctions());
var_dump($client->__getTypes());
$res = $client->GetFirendsList(array('Id'=> 8));
var_dump($res);

真正有趣的是,当我在没有 SOAP 的 php 文件中使用我的代码时,查询 returns 结果很好。一旦我想通过 SOAP 完成它,我只会返回 test of a message with following friends:.
我对 PHP 的经验很少,老实说我不知道​​错在哪里?我一直在关注一些关于 creating the SOAP with WSDL and PHP documentation.
的教程 然而,最后一个没有提供任何关于这个问题的见解,老实说,我不知道如何描述这个问题,因为我不知道它在哪里。
P.S。这是来自客户端的结果:

数组(5) { [0]=> 字符串(65) "GetFirendsListResponse GetFirendsList(GetFirendsList $parameters)" [1]=> 字符串(68) "UpdateIPAddressResponse UpdateIPAddress(UpdateIPAddress $parameters)" [2]=> 字符串(74) "CheckIfRegisteredResponse CheckIfRegistered(CheckIfRegistered $parameters)" [3]=> 字符串(47) "RegisterResponse Register(Register $parameters)" [4]=> 字符串(50) "AddFriendResponse AddFriend(AddFriend $parameters)" } 数组(10) { [0]=> 字符串(53) "struct AddFriend { string nickname; int friendId; }" [1]=> 字符串(45) "struct AddFriendResponse { boolean return; }" [2]=> 字符串(34) "struct GetFirendsList { int Id; }" [3]=> 字符串(49) "struct GetFirendsListResponse { string return; }" [4]=> 字符串(46 ) "struct CheckIfRegistered { string nickname; }" [5]=> 字符串(53) "struct CheckIfRegisteredResponse { boolean return; }" [6]=> 字符串(63) "struct UpdateIPAddress { string nickname; string ipaddress; }" [7]=> 字符串(51) "struct UpdateIPAddressResponse { boolean return; }" [8 ]=> 字符串(56) "struct Register { string nickname; string ipaddress; }" [9]=> 字符串(44) "struct RegisterResponse { boolean return; }" } 对象(stdClass)#2 (1) { ["return"]=> 字符串(42) "test of a message with following friends: "}

问题的最终答案是 SOAP WS 使用 SOAP 信封将消息从客户端传输到服务器。
所以起作用的是
$request = array('Id' => array('Value'=> 21)); $res = $client->GetFirendsList($request);
其中 wsdl 方法如下所示:

<message name="GetFirendsList">
    <part name="parameters" element="tns:GetFirendsList"/>
</message>
<message name="GetFirendsListResponse">
    <part name="parameters" element="tns:GetFirendsListResponse"/>
</message>
<operation name="GetFirendsList">
  <input wsam:Action="http://wsdl.example.org/PADR_APIWS/GetFirendsListRequest" message="tns:GetFirendsList"/>
  <output wsam:Action="http://wsdl.example.org/PADR_APIWS/GetFirendsListResponse" message="tns:GetFirendsListResponse"/>
</operation>
<operation name="GetFirendsList">
  <soap:operation soapAction=""/>
  <input>
    <soap:body use="literal"/>
  </input>
  <output>
    <soap:body use="literal"/>
  </output>
</operation>  

和 xsd 文件:

<xs:complexType name="getFirendsList">
<xs:sequence>
  <xs:element name="Value" type="xs:int"/>
</xs:sequence>

很抱歉xml。
这是 C# 代码:

PADR_API.getFirendsList request = new PADR_API.getFirendsList();
request.Value = 8;
client.GetFirendsList(request);  

所有这些现在都有效了。
结论
因此,从中吸取的教训是,即使您只想发送 int 或任何其他原始类型,您也需要将其封装在一个对象中,然后将其视为 SOAP 信封。
SOAP 服务器需要一个必须在服务器端定义的响应类型,如下所示:

class getGetFirendsListResponse {
    public $return;
}