【问题标题】:SOAP in php doesn't return values from MySqlphp 中的 SOAP 不从 MySql 返回值
【发布时间】:2016-06-15 21:16:30
【问题描述】:

我目前正在开发一个使用 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 文件中使用我的代码时,查询返回结果很好。只要我想通过 SOAP 执行此操作,我只会返回 test of a message with following friends:
我对PHP 的经验很少,老实说我不知道​​问题出在哪里?我一直在关注一些关于 creating the SOAP with WSDLPHP documentation 的教程。
但是最后一个没有提供任何关于这个问题的见解,老实说,我不知道如何描述这个问题,因为我不知道它在哪里。
附言这是客户端的结果:

array(5) { [0]=> string(65) "GetFirendsListResponse GetFirendsList(GetFirendsList $parameters)" [1]=> string(68) "UpdateIPAddressResponse UpdateIPAddress(UpdateIPAddress $parameters)" [2]=> string (74) "CheckIfRegisteredResponse CheckIfRegistered(CheckIfRegistered $parameters)" [3]=> string(47) "RegisterResponse Register(Register $parameters)" [4]=> string(50) "AddFriendResponse AddFriend(AddFriend $parameters)" } 数组(10) { [0]=> string(53) "struct AddFriend { string 昵称; intfriendId; }" [1]=> string(45) "struct AddFriendResponse { boolean return; }" [2]=> string( 34) "struct GetFirendsList { int Id; }" [3]=> string(49) "struct GetFirendsListResponse { string return; }" [4]=> string(46) "struct CheckIfRegistered { stringnickname; }" [5] => string(53) "struct CheckIfRegisteredResponse { boolean return; }" [6]=> string(63) "struct UpdateIPAddress { stringnickname; string ipaddress; }" [7]=> string(51) "struct UpdateIPAddressResponse { boolean返回; }" [8]=> 字符串(56) "结构t 注册{字符串昵称;字符串IP地址; }" [9]=> string(44) "struct RegisterResponse { boolean return; }" } object(stdClass)#2 (1) { ["return"]=> string(42) "与以下朋友的消息测试:" }

【问题讨论】:

  • 我不知道你对黄色块做了什么,但文本只在你使用鼠标悬停时显示:)
  • 没错,我试图在没有太多信息的情况下保持问题的简洁。如果你想在你的问题中使用它,只需在你的文本前使用>!
  • 你是如何测试你的 php 代码的(即:你说那部分工作的地方)?
  • 通过浏览器使用此 URL padr.orgfree.com/SoapClient.php
  • 好的,我看到的区别是:$client->GetFirendsList(array('Id'=> 8));,而您的 C# 代码似乎只是传递了一个整数。您能否在您的 Firends 函数中添加一个检查,以查看 C# 接口是否最终也为您提供了数组?

标签: c# php mysql soap


【解决方案1】:

问题的最终答案是 SOAP WS 使用 SOAP Envelope 将消息从客户端传输到服务器。
所以有效的是
$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;
}  

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-14
    • 1970-01-01
    • 2015-02-24
    • 2012-12-16
    • 1970-01-01
    • 2021-04-21
    • 2016-08-03
    • 2016-08-23
    相关资源
    最近更新 更多