新規投稿
フォローする

PHPでのデータ取得について

Garoon APIの 「ScheduleGetEventsByTarget」 を使用し、スケジュールのデータを取得しようとしています。

しかし、ユーザの名前が取得できずに困っています。
var_dumpでリターンの値を表示すると値が返ってきているのは確認できるのですが、print_r()でデータの中身を見るとどこにも見当たりません。
名前の情報を取得する方法はありますでしょうか?


var_dump($soap_client->__getLastResponse())の結果


<returns>
<schedule_event id="1458" event_type="normal" public_type="public" detail="TEST"version="1421890109" timezone="Asia/Tokyo" end_timezone="Asia/Tokyo" allday="false" start_only="false">
<members xmlns="http://schemas.cybozu.co.jp/schedule/2008">
<member>
<user id="1" name="AAAA" order="0"/>
</member>
<member>
<user id="2" name="BBBB" order="1"/>
</member>
<member>
<facility id="1" name="CCCC" order="2"/>
</member>
</members>
<when xmlns="http://schemas.cybozu.co.jp/schedule/2008">
<datetime start="2015-01-22T05:00:00Z" end="2015-01-22T07:00:00Z"/>
</when>
</schedule_event>
</returns>


print_r($result)の結果


stdClass Object
(
[schedule_event] => stdClass Object
(
[members] => stdClass Object
(
[member] => Array
(
[0] => stdClass Object
(
[user] => stdClass Object
(
[id] => 1
[order] => 0
)
)
[1] => stdClass Object
(
[user] => stdClass Object
(
[id] => 2
[order] => 1
)
)
[2] => stdClass Object
(
[facility] => stdClass Object
(
[id] => 1
[order] => 2
)
)
)
)
[when] => stdClass Object
(
[datetime] => stdClass Object
(
[start] => 2015-01-22T05:00:00Z
[end] => 2015-01-22T07:00:00Z
)
)
[id] => 1458
[event_type] => normal
[version] => 1421890109
[public_type] => public
[detail] => TEST
[timezone] => Asia/Tokyo
[end_timezone] => Asia/Tokyo
[allday] =>
[start_only] =>
)
)

var_dump($result)で参照しても、name項目はありませんでした。
よろしくお願いいたします。

0

2件のコメント

Avatar
Kawamukai Naoki

こちらでも調べてみましたが、
PHPのSOAP拡張ではうまくname属性を扱えないようです。

回避策としては、
レスポンスのXMLをパースし直すのがよさそうでした。

あまりすっきりしないコメントになってしまい申し訳ありませんが、
参考になりましたら幸いです。

-- 詳細

name属性について

member要素はMemberType型になっています。
この型ではname属性は明示的には定義されていません。
ただ、anyAttributeが定義されているので、
レスポンスのXMLにname属性があっても
スキーマとしては正しいです。

XML スキーマの一部

<xsd:complexType name="MemberType">
    <xsd:sequence>
      <xsd:choice>
        <xsd:element name="user">
          <xsd:complexType>
            <xsd:attribute name="id" type="base:IDType" use="required" />
            <xsd:attribute name="order" type="xsd:unsignedLong" use="optional" />
            <xsd:anyAttribute processContents="lax" />
          </xsd:complexType>
        </xsd:element>
        ...

マニュアルでもname属性は書かれていません。
https://cybozudev.zendesk.com/hc/ja/articles/202463250-%E3%82%B9%E3%82%B1%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%ABAPI%E3%81%A7%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E6%A7%8B%E9%80%A0#step2

PHP SOAP拡張とanyAttribute

PHPのSOAP拡張はanyAttributeを完全にはサポートしていないようです。
PHPのソースコードでもそのようなコメントが書いてあります。
https://github.com/php/php-src/blob/php-5.6.5/ext/soap/php_schema.c#L717
https://github.com/php/php-src/blob/php-5.6.5/ext/soap/TODO#L83

このため、WSDLモードで動かすと、
レスポンスのXMLにname属性があっても、取得できないようです。

非WSDLモードを使えばなんとかなるのではないかと思い、
挑戦してみたのですが、値がうまく取得できませんでした。

非WSDLモードで実行したときの
var_dump($client->ScheduleGetEventsByTarget($parameters));の結果

object(stdClass)#9 (1) {
  ["schedule_event"]=>
  object(stdClass)#10 (2) {
    ["members"]=>
    object(stdClass)#11 (1) {
      ["member"]=>
      object(stdClass)#12 (1) {
        ["user"]=>
        string(0) ""
      }
    }
    ["when"]=>
    object(stdClass)#13 (1) {
      ["datetime"]=>
      string(0) ""
    }
  }
}

代替案

レスポンスには正しいXMLが返ってきているので、
それをXMLとしてパースし直せばname属性の値も取得できました。

$xml_element =new SimpleXMLElement($client->__getLastResponse());
foreach($xml_element->xpath('/soap:Envelope/soap:Body/*/returns/.') as $ret)
{
    foreach ($ret as $schedule_event) {
        foreach($schedule_event->members->member as $member){
            print_r(
                array(
                    (string)$member->user["id"],
                    (string)$member->user["order"],
                    (string)$member->user["name"])
            );
        }
    }
}

実行結果

Array
(
    [0] => 1
    [1] => 0
    [2] => Administrator
)

1
Avatar
Saito

Kawamukai Naoki様、

遅くなり申し訳ありません。
丁寧な回答ありがとうございます。

説明されているようにやってみたところ、問題なく取得できました。
ありがとうございました!

0
サインインしてコメントを残してください。