ぼやき

0

PHP 7 にすると処理が速くなるようなので、 PHP 5 から PHP 7 にしたら WordPress のプラグインの Ktai Style がエラーを吐いたので修正してみました。

Ktai Style はガラケー(フューチャーフォン)で WordPress のコンテンツを見られるようにするプラグインです。 PHP 7 でどんなエラーになるかというと、パソコンではコンテンツ部分が表示されず、ガラケー(フューチャーフォン)では何も表示されません。

原因を確かめるため Firefox にフューチャーフォンのエミュレータみたいなアドオンをインストールして確認しました。 i-mode でエラーを吐いたところは他のキャリアでもエラーをはずなので、同じように直しています。
→ FireMobileSimulator

まとまると Ktai Style が PHP 7 で動かないのには大きく 2 つの原因がありました。

  • クラス継承しているのに引数の数が違う
  • preg_replace() で e 修飾子を使い関数を呼び出している

どちらも PHP 4 のころの書き方で、上は PHP 5.4 から 下は PHP 5.5 で非推奨になり PHP 7 で廃止されました。

クラス継承しているのに引数の数が違う

クラス継承によりメソッドを上書きしているのに、親クラスと引数の数が違うことが原因でエラーを吐いています。 PHP 4 などで使われていた古い記述方法みたいです。対策として初期値をつけた引数をつけ加えました。 ( その解決方法で本当にいいのかわかりませんが。)
→ Shin x blog : PHP E_STRICT で表示されるエラーメッセージを調べてみた

operators/base.php 2454 行目ほか
[09-May-2017 08:11:51 UTC] PHP Warning:  Declaration of KtaiService_Other::in_network($allow_search_engine = false) should be compatible with KtaiServices::in_network($networks = NULL, $allow_search_engine = false) in /xxxx/wp-content/plugins/ktai-style/operators/base.php on line 2459

operators/base.php 2454 行目、 operators/i-mode.php 321 行目、 operators/emobile.php 363 行目、 operators/ezweb.php 1040 行目、 operators/softbank.php 549 行目、 operators/willcom.php 702 行目

変更前:

public function in_network($allow_search_engine = false) {

変更後:

public function in_network($allow_search_engine = false, $n = null) {
operators/i-mode.php 330 行目ほか
[22-May-2017 05:09:27 UTC] PHP Warning:  Declaration of KtaiService_imode::replace_smiley($buffer) should be compatible with KtaiServices::replace_smiley($buffer, $smiles = NULL) in /xxxx/wp-content/plugins/ktai-style/operators/i-mode.php on line 1804

これもクラスを継承しているのに引数の数が違うので、同じの数になるように初期値ありで追加しました。

operators/i-mode.php 330 行目、 operators/emobile.php 372 行目、 operators/ezweb.php 1049 行目、 operators/softbank.php 557 行目、 operators/willcom.php 712 行目

変更前:

public function replace_smiley($buffer) {

変更後:

public function replace_smiley($buffer, $smiles = array() ) {
inc/template-tags.php の KS_Walker_Comment クラス内
[22-May-2017 05:09:28 UTC] PHP Warning:  Declaration of KS_Walker_Comment::start_lvl(&$output, $depth, $args) should be compatible with Walker::start_lvl(&$output, $depth = 0, $args = Array) in /xxxx/wp-content/plugins/ktai-style/inc/template-tags.php on line 2309
[22-May-2017 05:09:28 UTC] PHP Warning:  Declaration of KS_Walker_Comment::end_lvl(&$output, $depth, $args) should be compatible with Walker::end_lvl(&$output, $depth = 0, $args = Array) in /xxxx/wp-content/plugins/ktai-style/inc/template-tags.php on line 2309
[22-May-2017 05:09:28 UTC] PHP Warning:  Declaration of KS_Walker_Comment::start_el(&$output, $comment, $depth, $args) should be compatible with Walker::start_el(&$output, $object, $depth = 0, $args = Array, $current_object_id = 0) in /xxxx/wp-content/plugins/ktai-style/inc/template-tags.php on line 2309
[22-May-2017 05:09:28 UTC] PHP Warning:  Declaration of KS_Walker_Comment::end_el(&$output, $comment, $depth, $args) should be compatible with Walker::end_el(&$output, $object, $depth = 0, $args = Array) in /xxxx/theme.1010uzu.com/wp/wp-content/plugins/ktai-style/inc/template-tags.php on line 2309

このエラーは KS_Walker_Comment クラスが WordPress のコアの関数である wp-includes/class-wp-walker.php の Walker を拡張しているにも関わらず、 start_lvl() などの関数と引数の数が異なるためエラーを吐いています。これも元の関数と同じ数の引数を初期値で追加しました。
→ WordPress.org : Walker::start_lvl()

inc/template-tags.php 2313 行目

変更前:

	public function start_lvl(&$output, $depth, $args) {

変更後:

	public function start_lvl(&$output, $depth = 0, $args = array() ) {

inc/template-tags.php 2332 行目

変更前:

	public function end_lvl(&$output, $depth, $args) {

変更後:

	public function end_lvl(&$output, $depth = 0, $args = array() ) {

inc/template-tags.php 2351 行目

変更前:

	public function start_el(&$output, $comment, $depth, $args) {

変更後:

	public function start_el(&$output, $comment, $depth = 0, $args = array(), $current_object_id = 0) {

inc/template-tags.php 2404 行目

変更前:

	public function end_el(&$output, $comment, $depth, $args) {

変更後:

	public function end_el(&$output, $comment, $depth = 0, $args = array() ) {
admin/templates.php の KtaiCategory_Checklist クラス内

エラーログは確認していませんが、すべてのファイルを検索して Walker を拡張しているクラス部分を書き換えました。

admin/templates.php 413 行目

変更前:

	function start_lvl(&$output, $depth, $args) {

変更後:

	function start_lvl(&$output, $depth = 0, $args = array() ) {

admin/templates.php 417 行目

変更前:

	function end_lvl(&$output, $depth, $args) {

変更後:

	function end_lvl(&$output, $depth = 0, $args = array() ) {	

admin/templates.php 421 行目

変更前:

	function start_el(&$output, $category, $depth, $args) {

変更後:

	function start_el(&$output, $category, $depth = 0, $args = array(), $current_object_id = 0) {

admin/templates.php 430 行目

変更前:

	function end_el(&$output, $category, $depth, $args) {

変更後:

	function end_el(&$output, $category, $depth = 0, $args = array() ) {

preg_replace() で e 修飾子を使い関数を呼び出している

[09-May-2017 08:12:07 UTC] PHP Warning:  preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in /xxxx/wp-content/plugins/ktai-style/operators/base.php on line 2017

上記のようなエラーがでます。 preg_replace() で e 修飾子を使い関数を呼び出していたことが原因でした。 e 修飾子は PHP 7.0.0 で廃止されました。代わりに preg_replace_callback() を使用して無名関数を呼び出して書き直しました。

operators/base.php 2017 行目

マッチした配列以外の引数を self::pict_replace() に渡していたので、一度 use を使った無名関数でラップしてから、 self::pict_replace() に引数を渡しました。
→脱力系備忘録 BloG : preg_replace_callback のコールバック関数に複数引数を指定したい

operators/base.php 2017 行目

変更前:

	 $buffer = preg_replace(
 		'!<img localsrc="([^"]+)"( alt="(' . KtaiStyle::DOUBLE_QUOTED_STRING_REGEX . ')")?[^/>]*/?>!se', // <?php /* syntax hilighting fix */
 		'self::pict_replace("$1", "$2", "$3", $charset)', 
 		$buffer);

変更後:

	$buffer = preg_replace_callback(
		'!<img localsrc="([^"]+)"( alt="(' . KtaiStyle::DOUBLE_QUOTED_STRING_REGEX . ')")?[^/>]*/?>!s', // <?php /* syntax hilighting fix */
		function ($matches) use ($charset) { return self::pict_replace($matches[1], $matches[2], $matches[3], $charset); },
		$buffer);
operators/base.php 1964 行目

変更前:

	$buffer = preg_replace('/\376\376\376(\d+)\376\376\376/e', '$pre[$1]', $buffer);

変更後:

	$buffer = preg_replace_callback('/\376\376\376(\d+)\376\376\376/', function ($matches) { return $pre[$matches[1]]; }, $buffer);
operators/base.php 2436 行目

変更前:

	$buffer = preg_replace(
		'!<img localsrc="([^"]+)"( alt="(' . KtaiStyle::DOUBLE_QUOTED_STRING_REGEX . ')")? ?/?>!se', // <?php /* syntax hilighting fix */
		'parent::pict_replace("$1", "$2", "$3", $this->charset)', 
		$buffer);
	return $buffer;

変更後:

	$buffer = preg_replace_callback(
		'!<img localsrc="([^"]+)"( alt="(' . KtaiStyle::DOUBLE_QUOTED_STRING_REGEX . ')")? ?/?>!s', // <?php /* syntax hilighting fix */
		function ($matches) { return parent::pict_replace($matches[1], $matches[2], $matches[3], $this->charset); },
		$buffer);
	return $buffer;
operators/i-mode.php 1745 行目ほか

これもマッチした配列以外を引数で渡しているので、 use を使いました。

operators/i-mode.php 1745 行目、 operators/emobile.php 1761 行目、 operators/ezweb.php 2076 行目、 operators/softbank.php 1741 行目、 operators/willcom.php 1709 行目

変更前:

	$buffer = preg_replace(
		'!<img localsrc="([^"]+)"( alt="(' . KtaiStyle::DOUBLE_QUOTED_STRING_REGEX . ')")?[^/>]*/?>!se', // <?php /* syntax hilighting fix */
		'isset($translated["$1"]) ? $translated["$1"] : ("$3" ? "$3" : "〓")', 
		$buffer);

変更後:

	$buffer = preg_replace_callback(
		'!<img localsrc="([^"]+)"( alt="(' . KtaiStyle::DOUBLE_QUOTED_STRING_REGEX . ')")?[^/>]*/?>!s', // <?php /* syntax hilighting fix */
		function ($matches) use ($translated) { return isset($translated[$matches[1]]) ? $translated[$matches[1]] : ($matches[3] ? $matches[3] : '〓'); },
		$buffer);
patches/mobile.php 17 行目

変更前:

	return preg_replace('!\s*<div class="([-. \w]+ +)?locationurl( +[-. \w]+)?">.*?</div>!se', '"$1$2" ? "<div class=\"$1$2\">$3</div>" : ""', $content);

変更後:

	return preg_replace_callback('!\s*<div class="([-. \w]+ +)?locationurl( +[-. \w]+)?">.*?</div>!s', function ($matches) { return $matches[1] . $matches[2] ? '<div class="' . $matches[1] . $matches[2] . '">' . $matches[3] . '</div>' : '' ; }, $content);
inc/kses.php 206 行目

これもマッチした配列以外を引数として渡しているので、 use を使いました。

変更前:

	return preg_replace('%((<!--.*?(-->|$))|(<[^\015>]*(>|$)|>))%e',
	"self::kses_split2('\\1', \$allowed_html)", $string);

変更後:

	return preg_replace_callback('%((<!--.*?(-->|$))|(<[^\015>]*(>|$)|>))%',
	function ($matches) use ($allowed_html) { return self::kses_split2($matches[1], $allowed_html); }, $string);
inc/kses.php 580 行目

変更前:

	return preg_replace('/^((&[^;]*;|[\sA-Za-z0-9])*)'.'(:|&#58;|&#[Xx]3[Aa];)\s*/e', 'self::kses_bad_protocol_once2("\\1")', $string);

変更後:

	return preg_replace_callback('/^((&[^;]*;|[\sA-Za-z0-9])*)'.'(:|&#58;|&#[Xx]3[Aa];)\s*/', function ($matches){ return self::kses_bad_protocol_once2($matches[1]); }, $string);
inc/kses.php 612 行目

変更前:

	$string = preg_replace('/&amp;#0*([0-9]{1,5});/e', 'self::kses_normalize_entities2("\\1")', $string);

変更後:

	$string = preg_replace_callback('/&amp;#0*([0-9]{1,5});/', function ($matches) { return self::kses_normalize_entities2($matches[1]); }, $string);
inc/kses.php 635 行目

変更前:

	$string = preg_replace('/&#([0-9]+);/e', 'chr("\\1")', $string);
	$string = preg_replace('/&#[Xx]([0-9A-Fa-f]+);/e', 'chr(hexdec("\\1"))', $string);

変更後:

	$string = preg_replace_callback('/&#([0-9]+);/', function ($matches) { return chr($matches[1]); }, $string);
	$string = preg_replace_callback('/&#[Xx]([0-9A-Fa-f]+);/', function ($matches) { return hexdec($matches[1]); }, $string);
inc/shrinkage.php 918 行目

変更前:

	$text = preg_replace('!<img ([^>]+?)(\blocalsrc="\w+")?([^>]+?)>!e', '"$2" ? "<img $2 />" : ""', $text);

変更後:

	$text = preg_replace_callback('!<img ([^>]+?)(\blocalsrc="\w+")?([^>]+?)>!', function ($matches) { return $matches[2] ? '<img ' . $matches[2] . ' />' : ''; }, $text);

エミュレータでも実機でも確認しましたが、特に不具合はありませんでしたが、もしエラーが見つかったらコメントいただけるとありがたいです。

関連記事