PHPのTCPDFで「TCPDF ERROR: Some data has already been output to browser, can’t send PDF file」って言われた件

2020年4月13日システムPHP

PHPのTCPDFで「TCPDF ERROR: Some data has already been output to browser, can't send PDF file」って言われた件
PHPのTCPDFで「TCPDF ERROR: Some data has already been output to browser, can’t send PDF file」って言われた件

PHPPDFを出力するライブラリの「TCPDF」で画像を出力した際にエラーとなりました。その事象のエラー対応を行ったので共有します。

あとTCPDFのサンプルコードも簡単に解説します。

TCPDFで発生したエラー

今回PHPPDFを出力するために利用しているライブラリーの「TCPDF」でエラーが発生しました。

TCPDFで「TCPDF ERROR: Some data has already been output to browser, can’t send PDF file」エラー

Warning (2): imagepng(/tmp/pdf/__tcpdf_****_imgmask_alpha_****): failed to open stream: No such file or directory [/***/tcpdf.php, line 7299]
Warning (2): imagepng(/tmp/pdf/__tcpdf_****_imgmask_plain_****) [<a href='http://php.net/function.imagepng'>function.imagepng</a>]: failed to open stream: No such file or directory [/***/tcpdf.php, line 7304]
Warning (2): imagecreatefrompng(/tmp/pdf/__tcpdf_****_imgmask_alpha_****) [<a href='http://php.net/function.imagecreatefrompng'>function.imagecreatefrompng</a>]: failed to open stream: No such file or directory [/***/tcpdf.php, line 7033]
Warning (2): imagecreatefrompng(/tmp/pdf/__tcpdf_****_imgmask_plain_****) [<a href='http://php.net/function.imagecreatefrompng'>function.imagecreatefrompng</a>]: failed to open stream: No such file or directory [/***/tcpdf.php, line 7033]
TCPDF ERROR: Some data has already been output to browser, can't send PDF file

エラー見ていると、TCPDFで画像を出力でエラーとなっているようです。

TCPDFのエラー原因と対応

TCPDFで発生したエラー原因と解消した対応を紹介します。

「PHP5からPHP7へバージョンアップしたこと」か「CentOS7へOSをアップデートしたこと」による影響でした。なので、TCPDFのバージョンもアップデートしたことでエラーは解消されました。

PHPのバージョンアップに合わせてライブラリもしっかりとバージョンアップしましょう!っということでした(汗)

TCPDFのバージョンアップはGitHubで公開されているので、こちらの「GitHub tecnickcom/tc-lib-pdf」より行いました。

TCPDFのエラー原因を解説

今回のTCPDFのエラーが発生した原因は、CentOS7系から「/tmp」への書き込みについて仕様変更されたことで起こったことだと思います。

Warning (2): imagepng(/tmp/pdf/__tcpdf_****_imgmask_alpha_****): failed to open stream: No such file or directory [/***/tcpdf.php, line 7299]

上記の様に「/tmp/pdf/~」で「failed to open stream: No such file or directory」となっています。

failed to open stream: No such file or directoryとは

failed to open stream: No such file or directoryは、「そのようなファイルやディレクトリはありません!」です。

CentOS7系以降からサービス(PHP)から/tmpへ書き込めない

CentOS7以降からは、systemdが採用されています。なので、systemdに登録されているサービスは、"/tmp“直下や"/var/tmp“直下をそのまま使用させないようになっています。

そのまま使用できないというのは、"/tmp“や"/var/tmp“にサービス固有の一時ディレクトリが作成されます。

/tmp直下の一時ディレクトリの例
→/tmp/systemd-private-****-php-fpm.service-****

この"/tmp"ディレクトリを共有するのは、セキュリティ面で危険なため、このようにサービス固有の一時ディレクトリが作成させる仕組みとなっています。

参考にしたサイトの「phpから /tmp にファイルが書き込めない」に詳しく解説されているので、ぜひご覧ください。

TCPDFでPDFをPHPで出力

TCPDFでPDFをPHPで出力
TCPDFでPDFをPHPで出力

TCPDFを使ったPHPのサンプルコードを紹介します。

TCPDFで画像を出力する際は、GDなどをインストールしておく必要があります。

TCPDFでPDFを出力するPHPサンプルコード

<?php
require_once('tcpdf/tcpdf.php');

$pdf = new TCPDF('P', 'pt', 'A4', true, 'UTF-8', false);

// PDF各種設定(ファイル情報)
$pdf->SetCreator('PDF Creator');
$pdf->SetAuthor('PDF Author');
$pdf->SetTitle('PDF Title');
$pdf->SetSubject('PDF Subject');
$pdf->SetKeywords('PDF Keywords');

// PDF各種設定(余白)
$pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);

// PDF各種設定(ヘッダ・フッタ)
$pdf->setPrintHeader(false);
$pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));
$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);

// PDF各種設定(フォント)
// Styleでフォント指定された場合は適用されない
$pdf->SetFont('kozgopromedium', '', 10, '', true);

// ページを追加
$pdf->AddPage();

// 画像を配置
//$pdf->Image('https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png', 500, 100, 70);

$html = '
<html>
<head>
</head>
<body>
    <h1>Sample PDF</h1>
    <p>ほげほげ</p>
    <br>
    <span>ふがふが</span>

    <h2>Sample List</h2>
    <ul>
        <li>あいうえお</li>
        <li>かきくけこ</li>
    </ul>

    <h2>Sample DataList</h2>
    <dl>
        <dt>タイトル</dt>
        <dd>データ</dd>
    </dl>

    <h2>Sample Table</h2>
    <table>
        <thead>
            <tr>
                <th style="border:1px solid #000;">番号</th>
                <th style="border:1px solid #000;">名前</th>
                <th style="border:1px solid #000;">誕生日</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td style="border:1px solid #000;">1</td>
                <td style="border:1px solid #000;">山田太郎</td>
                <td style="border:1px solid #000;">1900年1月1日</td>
            </tr>
            <tr>
                <td style="border:1px solid #000;">2</td>
                <td style="border:1px solid #000;">佐藤花子</td>
                <td style="border:1px solid #000;">2000年1月1日</td>
            </tr>
        </tbody>
    </table>
</body>
</html>
';

$pdf->writeHTML($html, true, false, false, false, '');

// PDFを表示
$pdf->Output('option_sheet.pdf', 'I');

exit;
  • TCPDFでPDFをブラウザへ出力
  • PDFの出力内容は、HTMLで記載(style調整やHTMLタグには使えないものもある)
  • PDFへの画像を出力は、PHPで座標を指定

TCPDFでPDFを出力するPHPサンプルコードの解説

TCPDFでPDF出力するPHPサンプルコードを1つ1つ簡単にですが解説します。

TCPDFを読み込む

tcpdfのライブラリーを読み込みます。

require_once('tcpdf/tcpdf.php');

PDFの出力フォーマット

PDFの出力フォーマットを指定します。

$pdf = new TCPDF('P', 'pt', 'A4', true, 'UTF-8', false);
  • new TCPDF()
    • 第1引数:ページの向き
      • P:縦向き
      • L:横向き
    • 第2引数:単位
      • pt:ポイント
      • mm:ミリメートル
      • cm:センチメートル
      • in:インチ
    • 第3引数:ページフォーマット
      • A4:デフォルト

PDFのファイル情報

PDFファイルの各種情報を設定します。

$pdf->SetCreator('PDF Creator');
$pdf->SetAuthor('PDF Author');
$pdf->SetTitle('PDF Title');
$pdf->SetSubject('PDF Subject');
$pdf->SetKeywords('PDF Keywords');

PDFの余白

PDFの余白を設定します。

$pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);

PDFのヘッダとフッタ

PDFのヘッダとフッタを設定します。

$pdf->setPrintHeader(false);
$pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));
$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);

PDFのフォント

PDFで出力するフォントの設定をします。

$pdf->SetFont('kozgopromedium', '', 10, '', true);

ページを追加

PDFページを追加します。

$pdf->AddPage();

画像を出力

PDFへ画像を出力します。座標とサイズを指定します。

$pdf->Image('https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png', 500, 100, 70);

PDF出力内容をHTMLで記載

PDFに出力する内容をHTMLで記載します。

><html>
<head>
</head>
<body>
    <h1>Sample PDF</h1>
    <p>ほげほげ</p>
    <br>
    <span>ふがふが</span>

    <h2>Sample List</h2>
    <ul>
        <li>あいうえお</li>
        <li>かきくけこ</li>
    </ul>

    <h2>Sample DataList</h2>
    <dl>
        <dt>タイトル</dt>
        <dd>データ</dd>
    </dl>

    <h2>Sample Table</h2>
    <table>
        <thead>
            <tr>
                <th style="border:1px solid #000;">番号</th>
                <th style="border:1px solid #000;">名前</th>
                <th style="border:1px solid #000;">誕生日</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td style="border:1px solid #000;">1</td>
                <td style="border:1px solid #000;">山田太郎</td>
                <td style="border:1px solid #000;">1900年1月1日</td>
            </tr>
            <tr>
                <td style="border:1px solid #000;">2</td>
                <td style="border:1px solid #000;">佐藤花子</td>
                <td style="border:1px solid #000;">2000年1月1日</td>
            </tr>
        </tbody>
    </table>
</body>
</html>

PDF出力

PDFを出力する設定をします。

$pdf->writeHTML($html, true, false, false, false, '');
  • writeHTML()
    • 第1引数:HTMLタグ
    • 第2引数:改行
      • true:する
    • 第3引数:背景の塗りつぶし
      • 0:透明
      • 1:塗りつぶす
    • 第4引数:高さ設定
      • true:前回の高さ設定をリセット
      • false:前回の高さ設定を引き継ぐ
    • 第5引数:スペースの自動挿入
      • true:各行にスペースを挿入
    • 第6引数:テキスト整列
      • L:左端
      • C:中央
      • R:右端
      • false:

PDFを出力

PDFを出力します。

$pdf->Output('option_sheet.pdf', 'I');

おわり

今回はPHPPDFを出力する際に利用するライブラリの「TCPDF」におけるエラーとサンプルコードの解説を行いました。

プログラミングスクール受講メリット

・メンターにすぐ聞けるので分からないところでつまづかない
・受講生同士で学び合いモチベーション維持しやすい
・就学後に就職支援や進路サポートを受けることが出来る

ユート
ユート

Webプログラマ兼ブロガー | プログラミング基礎知識を発信|Webプログラマ歴は10年以上|JavaScript,PHP.HTML | 「人生の時間は有限。悪いことをしている時間はない」
プロフィール

2020年4月13日システムPHP

Posted by ユート