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」って言われた件

どうも、UT(@ut_1029)です。

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サンプルコード

  • TCPDFでPDFをブラウザへ出力
  • PDFの出力内容は、HTMLで記載(style調整やHTMLタグには使えないものもある)
  • 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を出力する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」におけるエラーとサンプルコードの解説を行いました。

プログラミング解説講座

UT
UTの日常

当ブログ(UTの日常)を運営しているUTは「プログラミング関係の仕事をしている30代1児の父親」です。詳しくは「UTのプロフィール」をご覧ください。

UTの日常では、システム開発における LinuxPHPJavaScriptJQueryMySQLなどの知識やプログラミング技術、サーバ構築や運用などAWSをメインに知識を紹介しています。

内容としては、Webシステムの開発中や運用中に発生したトラブルやエラーの対応や解決方法をまとめた備忘録やWebシステム開発の方法を未経験者の人を対象に説明したプログラム教科書を記事にしています。
Webシステム開発の知識やプログラム技術の備忘録

2020年4月13日システムPHP