近期不少WordPress项目后台升级到了最新的4.9以后,发现主题模版编辑器只能保存CSS样式表,凡是PHP类的摸吧一律无法保存了,经过google发现是新版WP的一个BUG,修复方案如下:

    打开wp-admin/includes/file.php文件,删除492-599行的如下代码:

    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 = __( 'An unidentified error has occurred.' );
    			} else {
    				$message = $result['message'];
    				unset( $result['message'] );
    			}
    			return new WP_Error( 'php_error', $message, $result );
    		}
    	}

    当然这个方法仅仅是WordPress官方出更新前的一个临时替代方式,永久的解决还是稍安勿躁等官方的fix的update吧。