Skip to content

PDF Oxide を始める (PHP)

PDF Oxide はテキスト抽出において最速の PHP 向け PDF ライブラリです。平均 0.8ms、3,830 件の PDF で 100% の成功率を達成しています。抽出・変換・生成を 1 つのライブラリでこなし、Python・Node・Go・C#・Ruby・Java の各バインディングと同じ Rust コアの上に構築されています。

インストール

composer require oxide/pdf-oxide

Composer のインストール後フックが、お使いのプラットフォーム (linux-x86_64linux-aarch64darwin-x86_64darwin-arm64windows-x64) に対応したビルド済みネイティブライブラリを vendor/oxide/pdf-oxide/lib/ にダウンロードします。

動作要件: ext-ffi を有効にした PHP 8.2 以降 (8.2、8.3、8.4、8.5)。php -m | grep -i ffi で確認できます。マネージドホストの中には ext-ffi を無効化しているものもあります。その場合は php:8.3-cli などの Docker イメージを利用してください。

PDF を開く

PdfDocument::open() でファイルを読み込み、メタデータを確認します。

use PdfOxide\PdfDocument;

$doc = PdfDocument::open('research-paper.pdf');
echo $doc->pageCount(), " pages\n";

$version = $doc->version();   // ['major' => int, 'minor' => int]
printf("PDF version: %d.%d\n", $version['major'], $version['minor']);

$doc->close();   // または __destruct() に任せる

テキスト抽出

単一ページ

任意のページから、ゼロ始まりのインデックスを指定してプレーンテキストを抽出します。

use PdfOxide\PdfDocument;

$doc = PdfDocument::open('report.pdf');
echo $doc->extractText(0);
$doc->close();

全ページ

use PdfOxide\PdfDocument;

$doc = PdfDocument::open('book.pdf');
for ($i = 0; $i < $doc->pageCount(); $i++) {
    echo "--- Page " . ($i + 1) . " ---\n";
    echo $doc->extractText($i), "\n";
}
$doc->close();

ワンショット抽出

extractTextOnce() は、ファイルを開いて 0 ページ目を抽出し、クローズまでを 1 回の呼び出しで行う静的ヘルパーです。

use PdfOxide\PdfDocument;

echo PdfDocument::extractTextOnce('report.pdf');

自動ルーティング抽出

extractTextAuto() は、ネイティブテキストがあればそれを返し、なければ復元可能なテキストへ穏当にフォールバックします。フォールバック経路で例外をスローすることはありません。

use PdfOxide\PdfDocument;

$doc = PdfDocument::open('mixed.pdf');
echo $doc->extractTextAuto(0);
$doc->close();

ページ API

pages()PdfPage ビューの配列を返し、pagesIter() はインデックス付きで遅延評価しながらページを返します。各ページは抽出処理をドキュメントへ委譲します。

use PdfOxide\PdfDocument;

$doc = PdfDocument::open('paper.pdf');

foreach ($doc->pagesIter() as $index => $page) {
    echo "Page {$index}:\n";
    echo $page->text(), "\n";
}

// 単一ページを直接取得することもできます:
$page = $doc->page(0);
echo $page->toMarkdown();

$doc->close();

PdfPage のメソッド: index()parent()text()textAuto()toMarkdown()toHtml()

Markdown / HTML への変換

単一ページまたはドキュメント全体を Markdown に変換したり、ページを HTML としてレンダリングしたりできます。

use PdfOxide\PdfDocument;

$doc = PdfDocument::open('paper.pdf');

echo $doc->toMarkdown(0);     // 1 ページ (デフォルトは 0 ページ目)
echo $doc->toMarkdownAll();   // ドキュメント全体
echo $doc->toHtml(0);         // 1 ページを HTML として

$doc->close();

静的な MarkdownConverter は、ドキュメント側の呼び出しでページインデックスを保持することなく、同じ変換を提供します。

use PdfOxide\PdfDocument;
use PdfOxide\MarkdownConverter;

$doc = PdfDocument::open('paper.pdf');

echo MarkdownConverter::toMarkdown($doc, 0);
echo MarkdownConverter::toMarkdownAll($doc);
echo MarkdownConverter::toHtml($doc, 0);
echo MarkdownConverter::toPlainText($doc, 0);

$doc->close();

構造化抽出

extractStructured() は、ページのレイアウトを考慮したビューを連想配列として返します。各リージョンの種別・テキスト・バウンディングボックス・カラムインデックスが含まれます。

use PdfOxide\PdfDocument;

$doc = PdfDocument::open('paper.pdf');
$structured = $doc->extractStructured(0);

printf("Page %d: %.0f x %.0f\n",
    $structured['page_index'],
    $structured['page_width'],
    $structured['page_height']);

foreach ($structured['regions'] as $region) {
    echo "[{$region['kind']}] {$region['text']}\n";
}

$doc->close();

バイト列から開く

メモリ上の文字列から PDF を開きます。S3・HTTP・データベースから取得したデータを扱うときに便利です。

use PdfOxide\PdfDocument;

$bytes = file_get_contents('report.pdf');
$doc = PdfDocument::openBytes($bytes);
echo $doc->extractText(0);
$doc->close();

ドキュメントの特性を調べる

処理に入る前にドキュメントを調べておきます。

use PdfOxide\PdfDocument;

$doc = PdfDocument::open('form.pdf');

var_dump($doc->hasStructureTree());   // タグ付き PDF か?
var_dump($doc->hasFormFields());      // AcroForm フィールドがあるか?
var_dump($doc->hasSignatures());      // デジタル署名があるか?

$doc->close();

PDF の生成

Pdf クラスは、Markdown・HTML・プレーンテキストから PDF を組み立てるためのファクトリメソッドを提供します。

use PdfOxide\Pdf;

$pdf = Pdf::fromMarkdown("# Invoice\n\n**Total:** \$42.00\n");
$pdf->saveTo('invoice.pdf');           // パスへ書き出す
$pdf->close();

$pdf = Pdf::fromHtml('<h1>Report</h1><p>Quarterly figures.</p>');
$bytes = $pdf->save();                 // または生のバイト列を取得する
file_put_contents('report.pdf', $bytes);
$pdf->close();

$pdf = Pdf::fromText("Plain text document.\n\nSecond paragraph.");
$pdf->saveTo('notes.pdf');
$pdf->close();

次のステップ