由于 BBS 的一些业务需求,需要使用 PHP 调用 C# 所编写的 WebService,其中遇到一些文档中未提及的细节问题,在此记录一下。

PHP 使用 SoapClient 进行调用,C#返回如下结构:

public struct QueryResult
{
    public bool Result;
    public string Message;
    public string[] Data1;
    public int[] Data2;
}

PHP 的调用代码如下,此处使用异常捕获的方式处理调用失败的情况,若 PHP 不支持异常,应用 is_soap_fault() 判断返回值。与 ASP.net 有关的注意事项写在注释中:

$client = new SoapClient("http://serveraddress/sample.asmx?wsdl");
if ($client !== false)
{
    // 使用关联数组,键名对应C#方法的参数名
    $param = array("Param1" => 1, "Param2" => 2);
    // 可以使用 $client->__soapCall() 或 $client->WebService方法名() 两种方式调用
    // 使用 $client->__soapCall() 调用时应将 $param 再包裹一层
    $result = $client->__soapCall("Method", array("parameters" => $param));
    // 使用 $client->WebService方法名() 调用时无需另行包裹 $param
    $result = $client->Method($param);
    // C# 返回结构体时,访问返回值采用 $result->结构体名称
    $resultdata = $result->Result;
    // bool 变量判断
    if ($resultdata->Result == "True")
    {
        // 访问返回的数组变量时应根据数组长度做不同的处理
        // 对于长度为1的数组,表现为普通变量,不能用下标访问
        if (count($resultdata->Data1) == 1)
        {
            // 用 $resultdata->Data1->string 访问数据
            echo $resultdata->Data1->string;
        }
        else
        {
            // 用 $resultdata->Data1->数据类型[] 访问数据
            echo $resultdata->Data1->string[0];
        }
    }
    catch (Exception $ex)
    {
        echo $ex->getMessage();
    }
}