mPDFで作成したPDFのファイル名がおかしい

PHPで簡単にPDFが作成できる「mPDF」では、作成したPDFをAcrobat readerまたはFirefox等のビューアでブラウザ上に表示させることもできるが、ダウンロードダイアログを表示してPDFファイルをダウンロードさせることもできる。
もちろんPDFファイルのファイル名は指定できるが、場合によってはおかしくなる。

基本的な使い方と問題

mPDFを使用するには、mPDFを任意のディレクトリに設置し、呼び出し元でincludeして下記の様に処理する。

include('./MPDF57/mpdf.php'); // パスは環境に応じて変える

$mpdf = new mPDF('ja', 'A4'); // 出力ファイル設定
$mpdf->writeHTML($data);      // pdf内容をhtmlで突っ込む

// 'sample.pdf'というファイル名でダウンロードさせる
$mpdf->Output('sample.pdf', 'D');

このとき、$mpdf->Output();で指定するファイル名が一時ファイルのパスとなる為、同一ディレクトリのpermissionによって上手くいかないことがある(特に何らかのフレームワークを使用している場合)。
その為フルパス指定で任意のディレクトリに書き出すと安全だが・・・

$mpdf->Output('/var/www/html/pdf/sample.pdf', 'D');

などとした場合、ダウンロードされるpdfのファイル名は、
_var_www_html_pdf_sample.pdf
の様にパスを含んだものになってしまう。

原因

mpdf.phpの7480行付近(※バージョンによる)に、ファイル名の設定(レスポンスヘッダ)がある。

			if (!isset($_SERVER['HTTP_ACCEPT_ENCODING']) OR empty($_SERVER['HTTP_ACCEPT_ENCODING'])) {
				// don't use length if server using compression
				header('Content-Length: '.strlen($this->buffer));
			}
			header('Content-disposition: attachment; filename="'.$name.'"');
 			echo $this->buffer;
			break;

この$nameは$mpdf->Output();の第一引数をそのまま使用している為、ファイル名にパスが含まれてしまう。
ファイル名に関するオプションなどは無さそうなので、この部分の処理を変更するしかない。

パスを含まないように修正する

ヘッダのfilenameに期待するファイル名を記述すればいいので、次のようにした。

			if (!isset($_SERVER['HTTP_ACCEPT_ENCODING']) OR empty($_SERVER['HTTP_ACCEPT_ENCODING'])) {
				// don't use length if server using compression
				header('Content-Length: '.strlen($this->buffer));
			}
			/* --- ここから --- */
			$wk_name = explode('/', $name);
			if (count($wk_name) > 1) {
				$name = $wk_name[count($wk_name) - 1];
			}
			/* --- ここまで --- */
			header('Content-disposition: attachment; filename="'.$name.'"');
 			echo $this->buffer;
			break;

入力されたパスを’/’でexplodeし、末尾の文字列をファイル名としている。
これでどの階層にあってもフルパス指定でダウンロードできる。