PHP8.XでもPHPExcelが使いたい

本当は後継のPHPSpreadsheetを使う

PHPExcelは、もはや説明が不要なほどよく知られたライブラリです。
phpでExcelの読み書きをするなら、まず選択肢に入ってきます。
でも、PHPSpreadsheetという後継のライブラリが登場し、PHPExcelは非推奨となりました。
確かに、PHPExcelと比べてバグも減り使いやすくはなったのですが、互換性はありません。
PHPExcelで動いていたプログラムは、それなりに修正が必要となります。

ただ、php7.4までなら非推奨ながらも動作はしているようでしたが、php8.X以降では完全に使えなくなってしまいました。

PHPExcelをphp8.Xでも動作するように修正したほうが良さそうな場合・・・(非推奨)

のっぴきならない事情で、「PHPSpreadsheetは導入せずにPHPExcelをphp8.X以降でも使いたい!」そんな方のための記事です。そして忘備録。

修正点1

ほとんど、いくつかのファイルで以下のように修正するだけです。{}ではなく[]を使う。

$test{$i} // php8.X以降では Fatal Errorとなる。
$test[$i] // こっちに修正

修正点2

countの部分を修正(場合によっては修正必要ないかも?)

//  修正前
count($columns)

//  修正後
if(is_countable($columns)){
    count($columns)
}

修正点3

PHPExcel/Calculation/Functions.php内のbreak

// 修正前
public static function TYPE($value = NULL) {
		$value	= self::flattenArrayIndexed($value);
		if (is_array($value) && (count($value) > 1)) {
			$a = array_keys($value);
			$a = array_pop($a);
			//	Range of cells is an error
			if (self::isCellValue($a)) {
				return 16;
			//	Test for Matrix
			} elseif (self::isMatrixValue($a)) {
				return 64;
			}
		} elseif(empty($value)) {
			//	Empty Cell
			return 1;
		}
		$value	= self::flattenSingleValue($value);

		if (($value === NULL) || (is_float($value)) || (is_int($value))) {
				return 1;
		} elseif(is_bool($value)) {
				return 4;
		} elseif(is_array($value)) {
				return 64;
				break;
		} elseif(is_string($value)) {
			//	Errors
			if ((strlen($value) > 0) && ($value{0} == '#')) {
				return 16;
			}
			return 2;
		}
		return 0;
	}	//	function TYPE()

// 修正後
public static function TYPE($value = NULL) {
		$value	= self::flattenArrayIndexed($value);
		if (is_array($value) && (count($value) > 1)) {
			$a = array_keys($value);
			$a = array_pop($a);
			//	Range of cells is an error
			if (self::isCellValue($a)) {
				return 16;
			//	Test for Matrix
			} elseif (self::isMatrixValue($a)) {
				return 64;
			}
		} elseif(empty($value)) {
			//	Empty Cell
			return 1;
		}
		$value	= self::flattenSingleValue($value);

		if (($value === NULL) || (is_float($value)) || (is_int($value))) {
				return 1;
		} elseif(is_bool($value)) {
				return 4;
		} elseif(is_array($value)) {
				return 64;
				// break;   ★ここのbreakは不要★
		} elseif(is_string($value)) {
			//	Errors
			if ((strlen($value) > 0) && ($value{0} == '#')) {
				return 16;
			}
			return 2;
		}
		return 0;
	}	//	function TYPE()

修正ファイル

  • PHPExcel/Worksheet/AutoFilter.php
  • PHPExcel/Worksheet/Writer/Excel2007/Worksheet.php
  • PHPExcel/Shared/String.php
  • PHPExcel/ReferenceHelper.php
  • PHPExcel/IOFactory.php
  • PHPExcel/Cell.php
  • PHPExcel/Cell/DefaultValueBinder.php
  • PHPExcel/Calculation.php
  • PHPExcel/Calculation/Functions.php

データをDBから取得してExcel出力したり、Excelからインポートする機能ぐらいしか使用していなかったので、自分の環境ではこれで動作するようになりましたが、使用方法によってはもう少し修正が必要となるかも?