PDFが1ページかどうかファイルの内容から判断する
問題
PDFが1ページかどうかを、なるべく簡単に判定したい。
どうするとよい?

答え
PDFファイルをテキストエディタで開いてみると、文字化けしつつも、ある程度内部の構造を見ることができる。
このあたりが「ページ一覧オブジェクト」。
2 0 obj << /Type /Pages /Kids [ 5 0 R 23 0 R ] /Count 2 /ProcSet [/PDF /Text /ImageB /ImageC] >> endobj
2ページだと上のようになっているし、1ページだと下のようになっている。
2 0 obj << /Type /Pages /Kids [ 5 0 R ] /Count 1 /ProcSet [/PDF /Text /ImageB /ImageC] >> endobj
/Kids に続くページ一覧を数えるのが一番正確そうだが、/Count に続く数字を見させてもらって楽をするのもよいか。
phpの正規表現で1ページかどうか調べるとこんな感じでしょうか。
/**
* こんな感じの部分が存在すれば1ページだと判断する
* <<
* /Type /Pages
* 何か
* /Count 1
* 何か
* >>
*/
$pdf = file_get_contents('test.pdf');
if (preg_match('|\n<<\n/Type /Pages\n[^<]*/Count 1\n[^<]*\n>>\n|s', $pdf)) {
echo '1ページです';
} else {
echo '1ページではないです';
}
改行の入り方や空白の入り方、要素の登場する順番などは、PDFの作り方によって若干異なるかもしれないので、雰囲気としては大体こんな感じで、後は状況に応じて調整する。
下のようになっていたり、<< >>が入れ子になっていたりするので、どこまで考慮するか。
2 0 obj
<< /Type /Pages
/Kids [ 4 0 R
10 0 R
24 0 R
]
/Count 3
>>
endobj
サーバー側で特定のソフトウェアを使用して生成しているPDFをチェックする場合などなら、対応するべきパターンは限定できると思う。
他の方法としては、ページオブジェクトの個数を数える案も考えられる。以下のような「/Type /Page」の数を数える。
5 0 obj
<<
/Type /Page
/Parent 2 0 R
/Contents 19 0 R
/Resources 21 0 R
/Annots 22 0 R
/MediaBox [0 0 420 283]
>>
endobj
参考
http://www.kobu.com/docs/pdf/pdfxhand.htm