PHP8でのエラー、reCAPTCHA for MW WP Formも

ワードプレスPHPカスタムフィールド

PHPをバージョン8.02に切り替えたところ、大量の「Warning」。

メッセージを見ればだいたいわかるようなものばかりでしたが、量が多いので往生、、、

2022/10/27

変数の処理でエラーが出る場合、if( is_page() || is_single() ){ ~ } で切り分けると不都合が起きるケースがある。

ので、if( !empty( 該当変数 ) ){ ~ } でスルーした方が良さそう。

変数を初期化してない

「Undefined variable $〇〇〇 in /~」

if( is_page() ){
	$main_class = 'page';
}

「こういうのは処理できないよ」ということで、

if( is_page() ){
	$main_class = ' page';
}else{
	$main_class = '';
}

$main_class = '';
if( is_page() ){
	$main_class = ' page';
}

などに修正。入門書で最初に出てくるヤツ!

悪癖だとわかったので今後はちゃんと。

そういえば、ループのなかでコレをやって、おかしな動作になって悩んだこと多々あり。

値を取得できない

「Attempt to read property “ID” on null in /」

if( get_post_meta( $post->ID, '○○○', true ) ){
	何らかの処理;
}

ページレイアウトに使うカスタムフィールド値を拾うため、こういうのをヘッダーなどに書いていてエラーが出た。(ヘッダー周りをコントロールしたいので、page.phpやsingle.phpには記述出来ない)

 

固定ページやシングルではもちろんエラーは出ないが、アーカイブ等でもループ中の最初の投稿IDを拾うのでエラーが出ない。(多くの場合、誤作動っぽくなると思うけど。)

 

が、「ポストID」が一切存在しない場合、例えば404状態等だとエラーが出る。

ので「$post->ID」を必ず取得できる場合に限定して回避。

if( is_page() || is_single() ){
	if( get_post_meta( $post->ID, '○○○', true ) ){
		何らかの処理;
	}
}

 

IDを取得しようとすること自体がエラーなので、

if( get_post_meta( $post->ID, '〇〇〇', true ) ){
	なんらかの処理;
}else{
	エラー処理;
}

こういうことをしてもダメ。

 

配列を取得できない場合もこんな感じの警告が出るので、取得できない場合を想定して書いておく。

reCAPTCHA for MW WP Form

よく使うプラグインでは、reCAPTCHA for MW WP Formが404状態でエラーを出す。

「Warning: Attempt to read property “post_content” on null in /~/wp-content/plugins/recaptcha-for-mw-wp-form/controllers/EnqueueController.php on line 20」

if (has_shortcode($post->post_content, 'mwform_formkey') && !empty($site_key)) {
            wp_enqueue_script('jquery');
            wp_enqueue_script("recaptcha-script", 'https://www.google.com/recaptcha/api.js?render=' . $site_key, array('jquery'), array(), true);

            $data = <<< EOL
grecaptcha.ready(function() {
    grecaptcha.execute('$site_key', {
            action: 'homepage'
        }).then(function(token) {
            var recaptchaResponse = jQuery('input[name="recaptcha-v3"]');
            recaptchaResponse.val(token);
        });
    });
EOL;
            wp_add_inline_script('recaptcha-script', $data);
        }

フォームの設置場所は固定ページかシングルだろう、ということで、

if( is_page() || is_single() ){
			if (has_shortcode($post->post_content, 'mwform_formkey') && !empty($site_key)) {
				wp_enqueue_script('jquery');
				wp_enqueue_script("recaptcha-script", 'https://www.google.com/recaptcha/api.js?render=' . $site_key, array('jquery'), array(), true);

				$data = <<< EOL
grecaptcha.ready(function() {
    grecaptcha.execute('$site_key', {
            action: 'homepage'
        }).then(function(token) {
            var recaptchaResponse = jQuery('input[name="recaptcha-v3"]');
            recaptchaResponse.val(token);
        });
    });
EOL;
				wp_add_inline_script('recaptcha-script', $data);
			}
		}

と、場所を限定すればエラーは出なくなり、一応送受信テストもOKな模様。

そのうち修正されるだろうけど。

同じくフォーム関係

以前の記事「MW WP Formのカスタマイズをslugで指定する」で紹介したコードもエラー。

function ag_get_mwwpform_id( $slug='' ){
	global $wpdb;
	$table = $wpdb->prefix . 'posts';
	$query  = "SELECT * FROM $table WHERE post_type='mw-wp-form' AND post_status='publish' AND post_name= %s";
	$result = $wpdb->get_row( $wpdb->prepare( $query, $slug ) );
	return ( int )$result->ID;
}

これはサイトによって出たり出なかったりする。データベースに書き込む前と後?

回避策

function ag_get_mwwpform_id( $slug = '' ){
	global $wpdb;
	$table = $wpdb->prefix . 'posts';
	$query  = "SELECT * FROM $table WHERE post_type='mw-wp-form' AND post_status='publish' AND post_name= %s";
	$result = $wpdb->get_row( $wpdb->prepare( $query, $slug ) );
	if( !empty( $result ) ){
		return ( int )$result->ID;
	}
}

ダメな例

function ag_get_mwwpform_id( $slug = '' ){
	if( is_page() || is_single() ){
		global $wpdb;
		$table = $wpdb->prefix . 'posts';
		$query  = "SELECT * FROM $table WHERE post_type='mw-wp-form' AND post_status='publish' AND post_name= %s";
		$result = $wpdb->get_row( $wpdb->prepare( $query, $slug ) );
		return ( int )$result->ID;
	}
}

エラーは消えるけど、この関数を使うコードが死にます。

ひとまず

以上は警告なので、以下をfunctions.phpに記述しとけばとりあえず黙る。

/* ---------- PHPエラーを出力しない ---------- */
error_reporting(0);

見た目、動作に異常が無い状態ならひとまずこれで。

 

開発中だけに使うもの、例えば「テーマ、ブラウザ、デバイスの情報を一覧表示する」みたいなものとセットにしておけば、

  • 開発中はエラー潰しに血眼になる
  • 納品時は万が一を考えて警告をストップ

という感じに。

出たり出なかったり

以上の警告は、全く同じテーマ、同じPHPバージョン(8.02)でも、サーバーによって違う挙動になる。

  • さくらでは一切警告は出ない。(バージョン設定画面で推奨されてる)
  • Xサーバーでは警告が出まくる。(バージョン設定画面で推奨されてない)

両サーバーとも、PHP.iniには何も特別なことはしてない。

テストサイトは、厳しい?サーバーに置くのが良いかも。

PHP8の恩恵

一番の恩恵は処理スピードアップだと思うけど、、、

  • 同じサーバー内(Xサーバー)
  • 全く同じコンテンツ、テーマ
  • PHP7.4.25 vs PHP8.0.12

PageSpeed Insightsで比べてみたところ、違いは誤差程度。

両者とも、PC = 100、携帯電話 = 90、といったところ。

十分に速いサーバーだと効果は感じられないみたい。

 

さくらのPHP8.0.12は

PC = 92、携帯電話 = 81

とちょっと分が悪いけど、設備増強のお知らせがあったから、そのうち巻き返すかも。