4

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

我正在调用一个 Web 服务方法,当它失败时,它会返回一个带有“详细标签”中的信息的肥皂故障。如果我使用 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>

我想获取“详细信息”标签中的 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 服务方法(返回肥皂错误)时,我在 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;
}

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

所以我期望输出来自var_dump($myplan_error->Details)is"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类。

有任何想法吗?:)

4

1 回答 1

1

看起来您正在尝试转换细节对象,而不是 MyPlanWSError 对象。因此,它的属性不匹配,并且生成的对象具有所有空值。

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

$myplan_error = cast('MyPlanWSError', $e->detail->MyPlanWSError);
于 2012-11-23T14:26:36.353 回答