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

<?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」におけるエラーとサンプルコードの解説を行いました。

\今なら/Amazonギフト券チャージでポイントが貯まる

Amazonチャージでギフト券をチャージするとお得
Amazonチャージでギフト券をチャージするとポイントが貯まる

Amazonチャージでギフト券をチャージしておくとポイントが貯まるのでめっちゃお得です。

UT

Amazonを利用している人ならお得な情報です。

Amazonチャージとは

Amazonギフト券を事前にチャージしておけるサービスです。特典としてチャージする度にポイントが付与されるのでお得です!

  • 5,000円以上:0.5%
  • 20,000円以上:1%
  • 40,000円以上:1.5%
  • 90,000円以上:2%

※Amazonギフト券の有効期限は10年間と長いので、9万円チャージしたとしても1年に9,000円以上使うのであれば無理なく使い切れます。

リンク:Amazonチャージはこちらから。

クレジットカードでチャージすると0.5%ポイントが貯まるキャンペーンが開催中

さらにAmazonプライム会員ならクレジットカードでチャージすると0.5%ポイントが貯まるキャンペーンが開催中
クレジットカードチャージで0.5%ポイントが貯まる

さらにAmazonプライム会員ならクレジットカードでチャージすると0.5%ポイントが貯まるキャンペーンが開催中です。

UT

以下のリンクからキャンペーンにエントリーする必要があるので注意が必要です。

リンク:Amazonチャージのキャンペーンエントリーはこちらから。

ブラックフライデー連動のスタンプラリー

ブラックフライデー連動のスタンプラリー
ブラックフライデー連動のスタンプラリー

Amazonでは、2021年12月17日までにスタンプを5つ集めると「10人に1人最大50,000~500ポイント」が当たるチャンス!なスタンプラリーが開催しています。

  • ポイントアップキャンペーンにエントリーする
  • Amazonプライム配送特典の対象商品を購入する
  • Prime Videoを観る
  • Amazon Music Primeを聴く
  • Prime Readingの本を読む
UT

スタンプの1つである「ポイントアップキャンペーン」へのエントリーは、2021年12月02日23時59分までに完了する必要があります。

リンク:Amazonプライムスタンプラリーはこちらから。

UT
UTの日常

1985年生まれ1児の父親です。ブログとか副業で収入を得る手段を模索中であります。(無理しない程度が理想wだから実績が出ないorz)
UTのプロフィール
Amazon欲しいものリスト

2020年4月13日システムPHP

Posted by UT