nyanco! ブログ

nyanco! ブログ

ほぼ日刊ペースで、主にIT・PCネタ・便利グッズ・猫などについてお役立ちの精神で書き連ねていく雑記ブログです。

nyanco! ブログは下記URLに移転いたしました。

https://blog.nyanco.me/

約 5 秒後に自動的にリダイレクトします。

【WordPress】管理画面から「functions.php」などを更新できるようにする方法

とっちゃん@nyanco! です。

WordPressのテーマなどが管理画面から更新できない時の対処法の覚書です。

重要なファイルは管理画面で更新ができない安全装置がかかっている

WordPressの管理画面でテーマの「functions.php」を編集して更新しようとすると…

致命的なエラーをチェックするためにサイトと通信できないため、PHP の変更は取り消されました。SFTP を使うなど、他の手段で PHP ファイルの変更をアップロードする必要があります。

致命的なエラーとか言われるとドキッとします。

これ、要はWordPressの安全装置みたいなもので、「functions.php」など下手に触らない方が良いファイルは簡単には編集できなくしている仕様のようです(致命的なエラーにはなりにくいCSSファイルなんかは問題なく更新できました)。

重要なファイルは一度ローカルで編集してその都度FTPソフトでアップロードしてね、ということなんでしょうが、FTPソフト使うのって地味に面倒くさいし、子テーマで作業していればエラーで画面真っ白になっても管理画面にさえ入れるなら復帰も早そうだし…

何より、管理画面のエディターがショートカットキーも使えて結構使いやすいのでなんとか管理画面で編集できないものかなぁと思って調べてると方法がありました!

安全装置の外し方

下記サイト様の記事がズバリな内容でした。

qiita.com

やり方紹介の前に注意点

こちらの記事にも書かれてますが、安全装置(ファイルチェック機能)を解除するのでリスクがあるという点と、WordPressがバージョンアップすると元に戻るという点に注意です。

作業する場合、あくまで自己責任でお願いします!特に「functions.php」の編集はバックアップ必須です!

ちなみにこの安全装置はWordPressバージョン4.9からの仕様のようですね。

やり方

  1. wp-admin > includes フォルダの中にある「file.phpphpが編集できるテキストエディタで開く。

  2. 下記の494~602行(行数はWordPressのバージョンで微妙に異なります)をコメントアウトする(/**/で囲む)。

/*
   if ( $is_active && 'php' === $extension ) {
       $scrape_key   = md5( rand() );
       $transient    = 'scrape_key_' . $scrape_key;
       $scrape_nonce = strval( rand() );
       set_transient( $transient, $scrape_nonce, 60 ); // It shouldn't take more than 60 seconds to make the two loopback requests.

       $cookies       = wp_unslash( $_COOKIE );
       $scrape_params = array(
           'wp_scrape_key'   => $scrape_key,
           'wp_scrape_nonce' => $scrape_nonce,
       );
       $headers       = array(
           'Cache-Control' => 'no-cache',
       );

       // Include Basic auth in loopback requests.
       if ( isset( $_SERVER['PHP_AUTH_USER'] ) && isset( $_SERVER['PHP_AUTH_PW'] ) ) {
           $headers['Authorization'] = 'Basic ' . base64_encode( wp_unslash( $_SERVER['PHP_AUTH_USER'] ) . ':' . wp_unslash( $_SERVER['PHP_AUTH_PW'] ) );
       }

       // Make sure PHP process doesn't die before loopback requests complete.
       @set_time_limit( 300 );

       // Time to wait for loopback requests to finish.
       $timeout = 100;

       $needle_start = "###### wp_scraping_result_start:$scrape_key ######";
       $needle_end   = "###### wp_scraping_result_end:$scrape_key ######";

       // Attempt loopback request to editor to see if user just whitescreened themselves.
       if ( $plugin ) {
           $url = add_query_arg( compact( 'plugin', 'file' ), admin_url( 'plugin-editor.php' ) );
       } elseif ( isset( $stylesheet ) ) {
           $url = add_query_arg(
               array(
                   'theme' => $stylesheet,
                   'file'  => $file,
               ),
               admin_url( 'theme-editor.php' )
           );
       } else {
           $url = admin_url();
       }
       $url                    = add_query_arg( $scrape_params, $url );
       $r                      = wp_remote_get( $url, compact( 'cookies', 'headers', 'timeout' ) );
       $body                   = wp_remote_retrieve_body( $r );
       $scrape_result_position = strpos( $body, $needle_start );

       $loopback_request_failure = array(
           'code'    => 'loopback_request_failed',
           'message' => __( 'Unable to communicate back with site to check for fatal errors, so the PHP change was reverted. You will need to upload your PHP file change by some other means, such as by using SFTP.' ),
       );
       $json_parse_failure       = array(
           'code' => 'json_parse_error',
       );

       $result = null;
       if ( false === $scrape_result_position ) {
           $result = $loopback_request_failure;
       } else {
           $error_output = substr( $body, $scrape_result_position + strlen( $needle_start ) );
           $error_output = substr( $error_output, 0, strpos( $error_output, $needle_end ) );
           $result       = json_decode( trim( $error_output ), true );
           if ( empty( $result ) ) {
               $result = $json_parse_failure;
           }
       }

       // Try making request to homepage as well to see if visitors have been whitescreened.
       if ( true === $result ) {
           $url                    = home_url( '/' );
           $url                    = add_query_arg( $scrape_params, $url );
           $r                      = wp_remote_get( $url, compact( 'cookies', 'headers', 'timeout' ) );
           $body                   = wp_remote_retrieve_body( $r );
           $scrape_result_position = strpos( $body, $needle_start );

           if ( false === $scrape_result_position ) {
               $result = $loopback_request_failure;
           } else {
               $error_output = substr( $body, $scrape_result_position + strlen( $needle_start ) );
               $error_output = substr( $error_output, 0, strpos( $error_output, $needle_end ) );
               $result       = json_decode( trim( $error_output ), true );
               if ( empty( $result ) ) {
                   $result = $json_parse_failure;
               }
           }
       }

       delete_transient( $transient );

       if ( true !== $result ) {

           // Roll-back file change.
           file_put_contents( $real_file, $previous_content );
           if ( function_exists( 'opcache_invalidate' ) ) {
               opcache_invalidate( $real_file, true );
           }

           if ( ! isset( $result['message'] ) ) {
               $message = __( 'Something went wrong.' );
           } else {
               $message = $result['message'];
               unset( $result['message'] );
           }
           return new WP_Error( 'php_error', $message, $result );
       }
   }
*/
  1. 保存した「file.php」をFTPソフトでサーバーに上書きしたらOK!

これで無事に管理画面から「functions.php」が編集・更新できるようになりました。

やはり便利です♪

本記事がどなたかの参考になれば幸いです。  

今回は以上となります。
最後まで読んでいただきましてありがとうございました!
それではまた〜✧٩(ˊωˋ*)و✧