[PHP]yaml_emitとは?PHPの値をYAML形式の文字列に変換する方法を徹底解説

PHP

はじめに

設定ファイルやDocker Compose、GitHub Actionsのワークフローなど、YAML形式のファイルを目にする機会は近年ますます増えています。PHPアプリケーションからYAML形式のデータを生成したい場合、json_encode() のような標準関数に相当するのが yaml_emit() です。

まず押さえておくべき重要な点として、yaml_emit() はPHP標準のコア関数ではなく、yaml というPECL拡張(libyamlをベースにした拡張モジュール)に属する関数です。多くのレンタルサーバーや標準的なPHPインストールにはデフォルトで含まれておらず、pecl install yaml のような形で別途インストールする必要があります。本記事では、この関数の基本的な使い方から、拡張の導入方法、実践的な活用例まで詳しく解説します。


関数概要

項目内容
関数名yaml_emit()
所属拡張yaml拡張(PECL、標準では無効)
シグネチャyaml_emit(mixed $data, int $encoding = YAML_ANY_ENCODING, int $linebreak = YAML_ANY_BREAK, array $callbacks = []): string
引数1$data — YAML形式に変換したいPHPの値(配列、スカラー値など)
引数2$encoding — 出力の文字エンコーディング
引数3$linebreak — 改行コードの形式
引数4$callbacks — カスタムのシリアライズ処理を指定するコールバック配列
戻り値YAML形式の文字列
対応バージョンyaml拡張2.0.0以降(PECL)
対になる関数yaml_parse()(YAML文字列をPHPの値に変換)

導入から利用までの流れ(イメージ図)

  yaml拡張の導入
  ┌────────────────────────┐
  │ 1. libyamlをシステムにインストール │
  │    (apt install libyaml-dev など)  │
  │ 2. pecl install yaml              │
  │ 3. php.iniに"extension=yaml"を追加  │
  └────────────┬────────────┘
               ▼
  PHPの配列データ
  ['name' => '太郎', 'age' => 30]
               │
               ▼
        yaml_emit($data)
               │
               ▼
  YAML形式の文字列
  "name: 太郎
  age: 30
  "

ポイントは、yaml_emit() を使う前提としてyaml拡張が有効になっている必要があるという点です。この前提を見落として Call to undefined function yaml_emit() というエラーに遭遇するケースは非常によくあります。使用前に必ず extension_loaded('yaml') などで確認する習慣をつけましょう。


実践サンプル7選

例1:拡張の存在確認を含めた基本的な使い方

<?php

class BasicYamlEmitter
{
    public function emit(array $data): string
    {
        if (!extension_loaded('yaml')) {
            throw new RuntimeException('yaml拡張がインストールされていません。pecl install yaml を実行してください。');
        }

        return yaml_emit($data);
    }
}

$emitter = new BasicYamlEmitter();
echo $emitter->emit(['name' => '太郎', 'age' => 30, 'active' => true]);

例2:アプリケーション設定をYAMLファイルとして書き出すクラス

<?php

class ConfigYamlWriter
{
    /**
     * 連想配列形式の設定データを
     * YAMLファイルとして永続化する
     */
    public function write(array $config, string $filePath): void
    {
        $yaml = yaml_emit($config);
        file_put_contents($filePath, $yaml);
    }
}

$writer = new ConfigYamlWriter();
$writer->write([
    'app'      => ['name' => 'MyApp', 'debug' => false],
    'database' => ['host' => 'localhost', 'port' => 5432],
], '/tmp/config.yaml');

例3:ネストした配列の階層構造を確認するデモ

<?php

class NestedStructureDemo
{
    /**
     * 多階層の配列がYAMLのインデント構造として
     * 正しく表現されることを確認する
     */
    public function demonstrate(): string
    {
        $data = [
            'services' => [
                'web' => [
                    'image' => 'nginx:latest',
                    'ports' => ['80:80', '443:443'],
                ],
                'db' => [
                    'image' => 'postgres:15',
                    'environment' => ['POSTGRES_PASSWORD' => 'secret'],
                ],
            ],
        ];

        return yaml_emit($data);
    }
}

$demo = new NestedStructureDemo();
echo $demo->demonstrate();

例4:複数のYAMLドキュメントを1つの文字列にまとめて出力する

<?php

class MultiDocumentYamlBuilder
{
    /**
     * 複数の独立したデータセットを、
     * "---"区切りの複数YAMLドキュメントとして結合する
     */
    public function buildMultiDocument(array $documents): string
    {
        $parts = array_map(
            fn (array $doc) => rtrim(yaml_emit($doc)),
            $documents
        );

        return implode("\n---\n", $parts) . "\n";
    }
}

$builder = new MultiDocumentYamlBuilder();
echo $builder->buildMultiDocument([
    ['kind' => 'Pod', 'name' => 'app-1'],
    ['kind' => 'Service', 'name' => 'app-service'],
]);

例5:yaml_emitとjson_encodeの出力を比較するツール

<?php

class FormatComparisonTool
{
    /**
     * 同じデータに対するYAMLとJSONの出力形式の違いを比較する
     */
    public function compare(array $data): array
    {
        return [
            'yaml' => yaml_emit($data),
            'json' => json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE),
        ];
    }
}

$tool = new FormatComparisonTool();
$result = $tool->compare(['name' => 'sample', 'tags' => ['a', 'b', 'c']]);
echo "--- YAML ---\n" . $result['yaml'];
echo "--- JSON ---\n" . $result['json'] . "\n";

例6:カスタムコールバックを使って特定オブジェクトの出力形式を制御する

<?php

class DateTimeYamlEmitter
{
    /**
     * 第4引数のcallbacksを使うことで、
     * DateTimeオブジェクトなど特殊な型の出力方法をカスタマイズできる
     */
    public function emitWithDateTime(array $data): string
    {
        $callbacks = [
            'tag' => 'tag:yaml.org,2002:str',
            DateTime::class => function (DateTime $date) {
                return [
                    'tag'   => '!datetime',
                    'value' => $date->format('Y-m-d H:i:s'),
                ];
            },
        ];

        return yaml_emit($data, YAML_ANY_ENCODING, YAML_ANY_BREAK, $callbacks);
    }
}

$emitter = new DateTimeYamlEmitter();
echo $emitter->emitWithDateTime(['created_at' => new DateTime('2026-08-17')]);

例7:Composerで代替ライブラリ(Symfony YAML)を使う場合との比較

<?php

class AlternativeLibraryComparison
{
    /**
     * yaml拡張が使えない環境向けに、
     * Symfony YAMLコンポーネントを使った代替実装を示す
     * (composer require symfony/yaml が必要)
     */
    public function emitWithSymfonyYaml(array $data): string
    {
        // yaml拡張が利用できない場合の代替手段として、
        // ピュアPHP実装のSymfony\Component\Yaml\Yaml::dump()がよく使われる
        return \Symfony\Component\Yaml\Yaml::dump($data, 4, 2);
    }

    public function emitWithNativeExtension(array $data): string
    {
        return yaml_emit($data);
    }
}

// $comparison = new AlternativeLibraryComparison();
// echo $comparison->emitWithSymfonyYaml(['key' => 'value']);

関連関数との比較

関数/ライブラリ役割yaml_emitとの違い
yaml_emit()PHPの値をYAML形式の文字列に変換本記事の対象。PECL拡張(libyamlベース)が必要
yaml_parse()YAML形式の文字列をPHPの値に変換yaml_emit()の対になるデコード関数
json_encode()PHPの値をJSON形式の文字列に変換標準搭載でインストール不要。フォーマットがJSON
serialize()PHPの値を独自形式の文字列に変換PHP固有の形式であり、YAML/JSONとは互換性がない
Symfony\Component\Yaml\Yaml::dump()ピュアPHP実装のYAML出力Composerでインストール可能。C拡張のビルドが不要

よくある落とし穴(注意点)

  1. yaml拡張がインストールされていないと即座にエラーになる yaml_emit() を呼び出す前に、必ず extension_loaded('yaml') などで拡張の有無を確認するか、function_exists('yaml_emit') でチェックする習慣をつけましょう(例1を参照)。共有ホスティング環境では、この拡張が有効になっていないことが多い点に注意が必要です。
  2. libyamlのシステムライブラリが必要 PECL拡張のインストール自体、事前にシステムレベルで libyaml 開発パッケージ(libyaml-dev など)がインストールされている必要があります。Dockerイメージなどでは、この依存関係を明示的にインストールする手順が必要です。
  3. 拡張が使えない環境ではSymfony YAMLなどの代替を検討する C拡張のビルドやインストールが難しい環境(一部の共有ホスティングなど)では、Composerでインストールできる symfony/yaml のようなピュアPHP実装のライブラリの方が現実的な選択肢になることがあります(例7を参照)。
  4. 出力されるYAMLの細かいフォーマット(インデント幅など)を直接制御しにくい yaml_emit() は内部的にlibyamlの出力ルールに従うため、Symfony YAMLのようにインデント幅を柔軟に指定するオプションが少ない傾向があります。厳密なフォーマット要件がある場合は、代替ライブラリとの比較検討が有効です。
  5. PHP配列とYAMLのマッピング/シーケンスの対応関係を理解しておく 連想配列は「マッピング」、数値インデックスの配列は「シーケンス」としてそれぞれ異なる形式で出力されます。意図しない配列構造(連想配列のつもりが数値インデックスの混在配列になっているなど)は、想定外のYAML構造につながることがあります。

まとめ

観点まとめ
何をする関数かPHPの値(配列、スカラー値など)をYAML形式の文字列に変換する
前提条件標準搭載ではなく、yaml PECL拡張の別途インストールが必要
主な用途設定ファイルの生成、Docker Compose/CI設定ファイルの動的生成
対になる関数yaml_parse()(YAML文字列をPHPの値にデコード)
注意点拡張の有無の事前確認、libyaml依存、代替ライブラリ(Symfony YAML)との比較検討

yaml_emit() は、PHPからYAML形式のデータを扱う上で基本となる関数ですが、標準のコア関数とは異なり、事前の拡張インストールが必要な点を必ず押さえておく必要があります。実行環境によっては拡張のインストールが難しいこともあるため、必要に応じて symfony/yaml のような代替ライブラリとの使い分けも検討しながら活用しましょう。

タイトルとURLをコピーしました