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])*)'.'(:|:|&#[Xx]3[Aa];)\s*/e', 'self::kses_bad_protocol_once2("\\1")', $string);
変更後:
return preg_replace_callback('/^((&[^;]*;|[\sA-Za-z0-9])*)'.'(:|:|&#[Xx]3[Aa];)\s*/', function ($matches){ return self::kses_bad_protocol_once2($matches[1]); }, $string);
inc/kses.php 612 行目
変更前:
$string = preg_replace('/&#0*([0-9]{1,5});/e', 'self::kses_normalize_entities2("\\1")', $string);
変更後:
$string = preg_replace_callback('/&#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);
エミュレータでも実機でも確認しましたが、特に不具合はありませんでしたが、もしエラーが見つかったらコメントいただけるとありがたいです。