웹페이지 운영/워드프레스

워드프레스 API "PHP의 XML 확장이 가능하지 않습니다. 호스팅 회사에게 연락하여 PHP의 XML 확장을 활성화하세요."

공무원 봉급 2022. 5. 18. 16:07

본 페이지에서는 워드프레스의 API로 호출시에 "PHP의 XML 확장이 가능하지 않습니다. 호스팅 회사에게 연락하여 PHP의 XML 확장을 활성화하세요."라는 에러 메시지가 발생할 경우 조치하는 방법에 대해서 설명드리고자 합니다.

개요

전 세계 웹페이지의 약 절반 정도가 워드프레스로 만들어진다고 합니다. 그 정도로 널리 사용되어지고 있습니다. 간단한 웹페이지의 경우 손쉽게 워드프레스를 설치해서 구성할 수 있습니다. 네이버 블로그나 티스토리 블로그를 운영하다가 구글 애드센스 수익을 늘리기 위해서 워드프레스로 옮겨가는 경우가 제법 많이 있습니다.

특히, 하루에 발행할 수 있는 글의 제한이 없을 뿐더러, 티스토리 블로그에서 자주 발생하는 크롤링 오류를 피해서 워드프레스의 세계로 발을 담그는 경우가 제법 많이 있습니다. 또한 워드프레스의 API를 통해서 블로그를 자동화하거나 자동으로 글을 생성할 수 있어서 몹시 편리합니다.

간단한 API 예제

아래는 API 통신을 통해서 rpc로 호출 가능한 함수 목록들을 가져오는 간단한 php 예제입니다.

<?php
define( 'ABSPATH', __DIR__ . '/' );
define( 'WPINC', 'wp-includes' );
require ABSPATH . WPINC . "/class-IXR.php";

$rpc = new IXR_Client( "www.webpage.com", "/xmlrpc.php", 80 );
#$rpc = new IXR_Client( "https://www.webpage.com/xmlrpc.php" );
$status = $rpc->query(
    "system.listMethods"    // method name
);

if( !$status ) {
    print "Error ( " . $rpc->getErrorCode( ) . " ) : ";
    print $rpc->getErrorMessage( ) . "\n";
    exit;
}

$data = $rpc->getResponse( );
print_r( $data );

?>

위의 API가 동작하기 위해서는 로컬에 워드프레스가 설치되어 있어야 합니다. 워드프레스/wp-includes/class-IXR.php 파일을 include해야 합니다. 워드프레스의 절대 경로는 ABSPATH로 설정해주면 되고, 그 서브디렉토리에 위치한 wp-includes 디렉토리명은 WPINC로 디파인해주시면 됩니다.

예를 들어서 워드프레스가 /var/www/wordpress 경로에 설치되어 있다고 한다면, ABSPATH/var/www/wordpress 경로로 설정해주면 되고, WPINCwp-includes로 설정해주면 됩니다. 그러면, require ABSPATH . WPINC . "/class-IXR.php"; 구문에 의해서 /var/www/wordpress/wp-includes/class-IXR.php 파일이 include 되게 됩니다.

IXR_Client 객체는 $rpc = new IXR_Client( "https://www.website.com/xmlrpc.php"); 와 같은 형식으로 생성해도 되고, $rpc = new IXR_Client( "www.website.com", "/xmlrpc.php", 8080 ); 와 같은 형식으로 생성해도 됩니다. 이와 관련된 자세한 내용은 /wp-includes/IXR/class-IXR-client.php 파일에 잘 나와있기 때문에 해당 파일을 열어서 참조하시는 것도 괜찮습니다.

아래는 /wp-includes/IXR/class-IXR-client.php 파일 내용의 일부를 발췌한 것입니다.

    function __construct( $server, $path = false, $port = 80, $timeout = 15 )
    {
        if (!$path) {
            // Assume we have been given a URL instead
            $bits = parse_url($server);
            $this->server = $bits['host'];
            $this->port = isset($bits['port']) ? $bits['port'] : 80;
            $this->path = isset($bits['path']) ? $bits['path'] : '/';

            // Make absolutely sure we have a path
            if (!$this->path) {
                $this->path = '/';
            }

            if ( ! empty( $bits['query'] ) ) {
                $this->path .= '?' . $bits['query'];
            }
        } else {
            $this->server = $server;
            $this->path = $path;
            $this->port = $port;
        }
        print($this->server . "\n");
        print($this->path . "\n");
        print($this->port . "\n");
        $this->useragent = 'The Incutio XML-RPC PHP Library';
        $this->timeout = $timeout;
    }

 

API 실행

php로 작성한 API 스크립트를 로컬에서 실행시켜 봅니다.

$ php api.php
Error ( -32300 ) : transport error - HTTP status code was not 200

만약,Error ( -32300 ) : transport error - HTTP status code was not 200와 같은 메시지가 발생한다면, 디버깅이 필요합니다. 다른 디버깅과 달리 통신 관련 디버깅은 다소 번거로운 편입니다. service-side와 client-side 모두 디버깅을 해줘야 하기 때문입니다. 물론 워드프레스 서버측의 문제일 가능성은 낮지만, 서버 설정의 문제일 가능성도 배제할 수 없습니다. 실제로 제 경우는 서버쪽의 PHP 모듈이 누락되어 발생한 문제였습니다.

API 디버깅

서버측인 워드프레스쪽과 클라이언트 스크립트쪽의 디버깅 모두가 필요한 상황입니다. 우선 워드프레스 서버의 로그를 살펴보도록 하겠습니다.

선호하는 편집기로 워드프레스 설정 파일을 오픈합니다.

$ vi /var/www/wordpress/wp-config.php

아래와 같이 설정을 변경해줍니다.

define( 'WP_DEBUG', true );

/* Add any custom values between this line and the "stop editing" line. */

// Enable Debug logging to the /wp-content/debug.log file
define( 'WP_DEBUG_LOG', true );

// Disable display of errors and warnings
define( 'WP_DEBUG_DISPLAY', false );
@ini_set( 'display_errors', 0 );

// Use dev versions of core JS and CSS files (only needed if you are modifying these core files)
define( 'SCRIPT_DEBUG', true );

/* That's all, stop editing! Happy publishing. */

주의할 점은 사용자가 변경해주는 부분은 /* Add any custom values between this line and the "stop editing" line. *//* That's all, stop editing! Happy publishing. */ 사이에만 편집하도록 주의합니다. 그 이유는 기본적으로 생성된 설정 부분에 영향을 주지 않도록 하기 위함입니다.

위와 같이 설정을 변경해준 이후에 API를 다시 시도한 후에 선호하는 편집기로 wp-content/debug.log 파일을 살펴봅니다.

$ vi /var/www/wordpress/wp-content/debug.log

만약 로그에 아래와 같은 내용이 있으면 php-xml 패키지가 누락되어서 발생하는 문제입니다.

[17-May-2022 06:00:05 UTC] PHP Notice: PHP의 XML 확장이 가능하지 않습니다. 호스팅 회사에게 연락하여 PHP의 XML 확장을 활성화하세요. in /var/www/wordpress/wp-includes/IXR/class-IXR-message.php on line 48

만약 웹서버를 직접 운영하지 않는다면 서버 담당자나 클라우드 호스팅 회사에 연락이 필요합니다만, 왠만한 호스팅 회사에서 제공하는 서비스는 거의 설정이 완벽합니다. 저는 서버를 직접 운영하는데 php-xml 패키지가 설치되어 있지 않아서 발생한 문제였습니다.

문제의 진단

우선 xml 관련 모듈들을 살펴봅니다.

$ php -m | grep xml

 

정상적인 경우라면 아래와 같은 모듈이 표시되어야 합니다.

$ php -m | grep xml
libxml
xml
xmlreader
xmlwriter

 

하지만 문제의 상황에서는 아래의 모듈만 존재했습니다.

$ php -m | grep xml
libxml

 

문제의 해결

필자의 경우는 php-xml 패키지를 추가로 설치해준 후에 깔끔하게 문제가 해결되었습니다.

$ sudo apt-get install php-xml

 

결론

만약 워드프레스 API 호출시에 클라이언트측에 HTTP 400 에러가 발생하고, 워드프레스 서버측에 "PHP의 XML 확장이 가능하지 않습니다. 호스팅 회사에게 연락하여 PHP의 XML 확장을 활성화하세요." 로그가 확인된다면 php-xml 패키지가 제대로 설치되었는지 확인하시기 바랍니다.