サイボウズGaroonでSOAP APIを使ってPHPでリクエストを送る

## 記事の概要
社内ネットワークで組んでいるシステムから、同じく社内ネットワーク内にあるオンプレミス版のgaroon5のユーザ情報を取得したいという状況が発生し、初めてSOAP APIを使ってみたという内容の記事です。

### 下調べ
ひとまずcybozu developer networkでgaroon API ドキュメントを確認。
[→SOAP APIの共通仕様](https://cybozu.dev/ja/garoon/docs/soap-api/overview/soap/)
[→ユーザ情報を取得するAPI](https://cybozu.dev/ja/garoon/docs/soap-api/base/get-users/)

### 使用しているgaroonのAPI定義確認
定義の中にリクエストの送り先がAPIの種類ごとに書いてあります。
```xml
<service name="BaseService">
    <port name="BasePort" binding="base_services:BaseBinding">
        <soap12:address location="http://xxxxxxxxxxxx"/>
    </port>
</service>
```
という感じで、サービスごとにいくつか並んでいると思います。
例えば…
今回は、ログイン名からユーザ情報を取得したいのでBaseGetUsersByLoginNameというAPIを使いますが、API名の最初がBaseで始まっているので、Base APIにリクエストを送ります。

### リクエスト内容
SOAP APIはXMLでデータのやり取りをするとのことで、下調べの共通仕様で示されていリクエスト例が次のような感じです。(2024‐02‐07現在)
```xml
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
  <soap:Header>
    <Action>
      BaseGetApplicationStatus
    </Action>
    <Security>
      <UsernameToken>
        <Username>xxxxxxxxxx</Username>
        <Password>xxxxxxx</Password>
      </UsernameToken>
    </Security>
    <Timestamp>
      <Created>2010-08-12T14:45:00Z</Created>
      <Expires>2037-08-12T14:45:00Z</Expires>
    </Timestamp>
    <Locale>ja</Locale>
  </soap:Header>
  <soap:Body>
    <BaseGetApplicationStatus>
      <parameters></parameters>
    </BaseGetApplicationStatus>
  </soap:Body>
</soap:Envelope>
```
使うAPIに応じて該当する部分を書き換えます。
\<action>の内容は、使うAPI名に書き換えます。
\<UsenameToken>の内容は、garoonのユーザネームとパスワードに書き換えます。
\<soap:Body>の内容は、使うAPIに応じてタグごと書き換えます。

で、今回やりたいのは、BaseGetUsersByLoginNameになります。下調べのAPI説明を見てみると、リクエスト例が次のようになっています。(2024-02-07現在)
```xml
<parameters>
  <login_name>Administrator</login_name>
  <login_name>saito</login_name>
</parameters>
```
ですので、\<soap:Body>の内容を次のように書き換えます。
```xml
<BaseGetUsersByLoginName>
    <parameters>
        <login_name>情報取得したいユーザ名1</login_name>
        <login_name>情報取得したいユーザ名2</login_name>
        ....
    </parameters>
</BaseGetUsersByLoginName>
```

### リクエストをPHPで送ってみる
リクエストのXMLが書けましたので、PHPで送ります。
```php
// リクエストURL(定義で確認した送り先)
$url = 'http://xxxxxxxxxxx';

// リクエストXMLデータ
$xmlData = '<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
  <soap:Header>
    <Action>
      BaseGetUsersByLoginName
    </Action>
    <Security>
      <UsernameToken>
        <Username>xxxxxxxxxx</Username>
        <Password>xxxxxxxxxx</Password>
      </UsernameToken>
    </Security>
    <Timestamp>
      <Created>2010-08-12T14:45:00Z</Created>
      <Expires>2037-08-12T14:45:00Z</Expires>
    </Timestamp>
    <Locale>ja</Locale>
  </soap:Header>
  <soap:Body>
    <BaseGetUsersByLoginName>
      <parameters>
        <login_name>xxxxxxxxx</login_name>
        <login_name>xxxxxxxxx</login_name>
        <login_name>xxxxxxxxx</login_name>
      </parameters>
    </BaseGetUsersByLoginName>
  </soap:Body>
</soap:Envelope>';

// cURLセッションの初期化
$ch = curl_init($url);

// cURLオプションの設定
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: text/xml; charset=UTF-8',
));

// リクエストの実行
$response = curl_exec($ch);

// cURLセッションの終了
curl_close($ch);

// 戻りXML出力
echo $response;
```
:::note info
リクエストデータ2行目の\<soap:Envelope xmlns:soap="xxxxxxxx">の部分のアドレスは書き換えちゃダメという指示がcybozu developer network内にありました。 
:::

これで$responseにgaroonからの答えが返ってきています。