将php异常(soap fault)转换为特定的类

时间:2012-11-23 14:16:42

标签: php web-services soap casting

我在将PHP异常转换为泛型类时遇到问题。

我正在调用一个Web服务方法,当它失败时,它返回一个soap fault,其中包含“详细信息标记”中的信息。如果我使用Soap UI(http://soapui.org)调用Web服务方法,结果就是这样:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
      <s:Fault>
         <faultcode>s:Client</faultcode>
         <faultstring xml:lang="sv-SE">Error Posting New Sponsor Full to Middleware</faultstring>
         <detail>
            <MyPlanWSError xmlns="http://schemas.datacontract.org/2004/07/MyPlanPOA" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
               <BadParameters i:nil="true"/>
               <Details>2 duplicate(s) detected</Details>
               <Duplicates>
                  <DuplicateInfo>
                     <DuplicatedExtRelNo>0</DuplicatedExtRelNo>
                     <POAStatus>New</POAStatus>
                     <Source>NewExtRels</Source>
                     <SourceRecordID>194</SourceRecordID>
                     <Type>eMail</Type>
                  </DuplicateInfo>
                  <DuplicateInfo>
                     <DuplicatedExtRelNo>0</DuplicatedExtRelNo>
                     <POAStatus>New</POAStatus>
                     <Source>NewExtRels</Source>
                     <SourceRecordID>194</SourceRecordID>
                     <Type>Address</Type>
                  </DuplicateInfo>
               </Duplicates>
               <ErrorNumber>7</ErrorNumber>
            </MyPlanWSError>
         </detail>
      </s:Fault>
   </s:Body>
</s:Envelope>

我想获取“detail”标签中的MyPlanWSError内容。我想将其转换为php类。

我使用了漂亮的工具wsdl2php(http://www.urdalen.no/wsdl2php)来生成基于wsdl文件的辅助类,这样我就不必自己编写所有代码了:)生成的工具MyPlanWSError看起来像这样:

class MyPlanWSError
{
  public $BadParameters;
  public $Details;
  public $Duplicates;
  public $ErrorNumber;
  public function __construct($BadParameters, $Details, $Duplicates, $ErrorNumber)
  {
    $this->BadParameters = $BadParameters;
    $this->Details = $Details;
    $this->Duplicates = $Duplicates;
    $this->ErrorNumber = $ErrorNumber;
  }
}

当我调用Web服务方法(返回soap错误)时,我在try catch子句中执行此操作:

function add_new_sponsor() {
  // ... code
  try {
    $new_sponsor = new PostNewSponsor(
        $accessKey,
        $type,
        $initialRecordStatus,
        $monthlyAmount,
        $categoryCode,
        $titleCode,
        $firstName,
        $lastName,
        $organisationName,
        $street,
        $houseNumber,
        $apartment,
        $extraAddressLine,
        $postCode,
        $town,
        $countryISOCode,
        $privatePhone,
        $mobilePhone,
        $workPhone,
        $eMailAddress,
        $sourceCode,
        $paymentFrequencyCode,
        $paymentTypeCode,
        $numberOfChildren,
        $scGender,
        $continentCode,
        $scCountryISOCode,
        $olderChildFlag,
        $personalID,
        $AddressTypeCode,
        $extRelNo,
        $comments,
        $iPAddress);

    $result = plan_utils_post_sponsor($new_sponsor);
  } catch (Exception $e) {
    echo 'Exception->detail var_dump: <br/>';
    var_dump($e->detail);
    echo '<br/></br>';

    $myplan_error = cast('MyPlanWSError', $e->detail);
    echo 'MyPlanWSError var_dump <br/>';
    var_dump($myplan_error);
    echo '<br/><br/>';

    echo 'MyPlanWSError->Details var_dump <br/>';
    var_dump($myplan_error->Details);
    echo '<br/><br/>';
  }
}

function cast($destination, $sourceObject)
{
    if (is_string($destination)) {
        $destination = new $destination();
    }
    $sourceReflection = new ReflectionObject($sourceObject);
    $destinationReflection = new ReflectionObject($destination);
    $sourceProperties = $sourceReflection->getProperties();
    foreach ($sourceProperties as $sourceProperty) {
        $sourceProperty->setAccessible(true);
        $name = $sourceProperty->getName();
        $value = $sourceProperty->getValue($sourceObject);
        if ($destinationReflection->hasProperty($name)) {
            $propDest = $destinationReflection->getProperty($name);
            $propDest->setAccessible(true);
            $propDest->setValue($destination,$value);
        } else {
            $destination->$name = $value;
        }
    }
    return $destination;
}

演员方法取自//http://stackoverflow.com/questions/3243900/convert-cast-an-stdclass-object-to-another-class。

所以我希望输出来自var_dump($myplan_error->Details) "2 duplicate(s) detected",而是NULL :(

以下是catch子句的整个输出:

Exception->detail var_dump:
object(stdClass)#4 (1) { ["MyPlanWSError"]=> object(stdClass)#5 (4) { ["BadParameters"]=> NULL ["Details"]=> string(23) "2 duplicate(s) detected" ["Duplicates"]=> object(stdClass)#6 (1) { ["DuplicateInfo"]=> array(2) { [0]=> object(stdClass)#7 (5) { ["DuplicatedExtRelNo"]=> string(1) "0" ["POAStatus"]=> string(3) "New" ["Source"]=> string(10) "NewExtRels" ["SourceRecordID"]=> string(3) "194" ["Type"]=> string(5) "eMail" } [1]=> object(stdClass)#8 (5) { ["DuplicatedExtRelNo"]=> string(1) "0" ["POAStatus"]=> string(3) "New" ["Source"]=> string(10) "NewExtRels" ["SourceRecordID"]=> string(3) "194" ["Type"]=> string(7) "Address" } } } ["ErrorNumber"]=> string(1) "7" } }

MyPlanWSError var_dump
object(MyPlanWSError)#3 (5) { ["BadParameters"]=> NULL ["Details"]=> NULL ["Duplicates"]=> NULL ["ErrorNumber"]=> NULL ["MyPlanWSError"]=> object(stdClass)#5 (4) { ["BadParameters"]=> NULL ["Details"]=> string(23) "2 duplicate(s) detected" ["Duplicates"]=> object(stdClass)#6 (1) { ["DuplicateInfo"]=> array(2) { [0]=> object(stdClass)#7 (5) { ["DuplicatedExtRelNo"]=> string(1) "0" ["POAStatus"]=> string(3) "New" ["Source"]=> string(10) "NewExtRels" ["SourceRecordID"]=> string(3) "194" ["Type"]=> string(5) "eMail" } [1]=> object(stdClass)#8 (5) { ["DuplicatedExtRelNo"]=> string(1) "0" ["POAStatus"]=> string(3) "New" ["Source"]=> string(10) "NewExtRels" ["SourceRecordID"]=> string(3) "194" ["Type"]=> string(7) "Address" } } } ["ErrorNumber"]=> string(1) "7" } }

MyPlanWSError->Details var_dump
NULL

所以似乎问题是我无法成功将$e>detail转换为MyPlanWSError类。

有什么想法吗? :)

1 个答案:

答案 0 :(得分:1)

看起来你正在尝试强制转换详细对象,而不是MyPlanWSError对象。因此,它的属性不匹配,结果对象具有所有空值。

试试这个,它应该可以正常工作:

$myplan_error = cast('MyPlanWSError', $e->detail->MyPlanWSError);