カテゴリー
IT

WordPress3.2.1をmysqli関数に対応させる

2011年にWordPressで構築したウェブサイトのメンテナンスを依頼された時の苦労話、というか対応の記録です。

mysql拡張モジュールがない!?

まずサイトをブラウザで開いてみると、以下のメッセージが表示されました。

お使いのサーバーの PHP では WordPress に必要な MySQL 拡張を利用できないようです。

このエラーメッセージは wp-includes/load.php [114行目] の以下の条件が原因です。

if ( !extension_loaded( 'mysql' ) && !file_exists( WP_CONTENT_DIR . '/db.php' ) )

・・・PHP7でmysql関数は削除されたので、mysql関数がなくて動かないことは古いサイトではよくあります。よくありますが、WordPressでは初めてでした。

これがめんどくさかった。

とりあえずこの箇所は以下のように書き換えてクリアしました。

// mysql拡張モジュールはmysqli拡張モジュールになりました。
if ( !extension_loaded( 'mysqli' ) && !file_exists( WP_CONTENT_DIR . '/db.php' ) )

ラッパー関数をたくさん作る

mysql_connect はPHP7から消滅して mysqli_connect しか使えなくなりました。同様に、mysql_query は mysqli_query になりました。こうした脱皮を繰り返して、PHPはずいぶん普通っぽい言語に近づいてきました。

mysql_******** という関数は結構あるのですが、幸い i がついて引数の順序が変わっただけ・・・めんどくさ・・・なので、ざっと作りました。wp-db.php の中のmysql関数を置換するだけではダメそうでした。

<?php

function mysql_connect($host, $user, $pw, $new_link = false, $client_flags = 0) {
    return mysqli_connect($host, $user, $pw);
}
function mysql_affected_rows($conn) {
    return mysqli_affected_rows($conn);
}
function mysql_autocommit($enable = true, $conn) {
    return mysqli_autocommit($conn, $enable);
}
function mysql_begin_transaction($conn) {
    return mysqli_begin_transaction($conn);
}
function mysql_change_user($user, $pw, $db, $conn) {
    return mysqli_change_user($conn, $user, $pw, $db);
}
function mysql_character_set_name($conn) {
    return mysqli_character_set_name($conn);
}
function mysql_close($conn) {
    return mysqli_close($conn);
}
function mysql_commit($flags = 0, $name = null, $conn) {
    return mysqli_commit($conn, $flags, $name);
}
function mysql_connect_errno() {
    return mysqli_connect_errno();
}
function mysql_connect_error() {
    return mysqli_connect_error();
}
function mysql_debug($options) {
    return mysqli_debug($options);
}
function mysql_dump_debug_info($conn) {
    return mysqli_dump_debug_info($conn);
}
function mysql_errno($conn) {
    return mysqli_errno($conn);
}
function mysql_error_list($conn) {
    return mysqli_error_list($conn);
}
function mysql_error($conn) {
    return mysqli_error($conn);
}
function mysql_field_count($conn) {
    return mysqli_field_count($conn);
}
function mysql_get_charset($conn) {
    return mysqli_get_charset($conn);
}
function mysql_client_info($conn) {
    return mysqli_client_info($conn);
}
function mysql_fetch_array($conn) {
    return mysqli_fetch_array($conn);
}
function mysql_fetch_assoc($conn) {
    return mysqli_fetch_assoc($conn);
}
function mysql_fetch_field($conn) {
    return mysqli_fetch_field($conn);
}
function mysql_fetch_lengths($conn) {
    return mysqli_fetch_lengths($conn);
}
function mysql_fetch_object($conn) {
    return mysqli_fetch_object($conn);
}
function mysql_fetch_row($conn) {
    return mysqli_fetch_row($conn);
}
function mysql_free_result($conn) {
    return mysqli_free_result($conn);
}
function mysql_get_client_version() {
    return mysqli_get_client_version();
}
function mysql_get_connection_stats($conn) {
    return mysqli_get_connection_stats($conn);
}
function mysql_get_host_info($conn) {
    return mysqli_get_host_info($conn);
}
function mysql_get_protocol_version($conn) {
    return mysqli_get_protocol_version($conn);
}
function mysql_get_server_info($conn) {
    return mysqli_get_server_info($conn);
}
function mysql_get_server_version($conn) {
    return mysqli_get_server_version($conn);
}
function mysql_get_warnings($conn) {
    return mysqli_get_warnings($conn);
}
function mysql_info($conn) {
    return mysqli_info($conn);
}
function mysql_init() {
    return mysqli_init();
}
function mysql_insert_id($conn) {
    return mysqli_insert_id($conn);
}
function mysql_kill($pid, $conn) {
    return mysqli_kill($conn, $pid);
}
function mysql_more_results($conn) {
    return mysqli_more_results($conn);
}
function mysql_multi_query($query, $conn) {
    return mysqli_multi_query($conn, $query);
}
function mysql_next_result($conn) {
    return mysqli_next_result($conn);
}
function mysql_num_fields($conn) {
    return mysqli_num_fields($conn);
}
function mysql_num_rows($conn) {
    return mysqli_num_rows($conn);
}
function mysql_options($option, $value, $conn) {
    return mysqli_options($conn, $option, $value);
}
function mysql_ping($conn) {
    return mysqli_ping($conn);
}
function mysql_poll(&$read, &$error, &$reject, $seconds, $msec = 0) {
    return mysqli_poll($read, $error, $reject, $seconds, $msec);
}
function mysql_prepare($query, $conn) {
    return mysqli_prepare($conn, $query);
}
function mysql_query($query, $conn) {
    return mysqli_query($conn, $query);
}
function mysql_real_connect($host, $user, $pw, $db, $port, $sock, $flags) {
    return mysqli_real_connect($host, $user, $pw, $db, $port, $sock, $flags);
}
function mysql_real_escape_string($str, $conn) {
    return mysqli_real_escape_string($conn, $str);
}
function mysql_real_query($query, $conn) {
    return mysqli_real_query($conn, $query);
}
function mysql_reap_async_query($conn) {
    return mysqli_reap_async_query($conn);
}
function mysql_refresh($flags, $conn) {
    return mysqli_refresh($conn, $flags);
}
function mysql_release_savepoint($name, $conn) {
    return mysqli_release_savepoint($conn, $name);
}
function mysql_rollback($flags = 0, $name = null, $conn) {
    return mysqli_rollback($conn, $flags, $name);
}
function mysql_savepoint($name, $conn) {
    return mysqli_savepoint($conn, $name);
}
function mysql_select_db($db, $conn) {
    return mysqli_select_db($conn, $db);
}
function mysql_set_charset($charset, $conn) {
    return mysqli_set_charset($conn, $charset);
}
function mysql_sqlstate($conn) {
    return mysqli_sqlstate($conn);
}
function mysql_stat($conn) {
    return mysqli_stat($conn);
}
function mysql_stmt_init($conn) {
    return mysqli_stmt_init($conn);
}
function mysql_store_result($mode = 0, $conn) {
    return mysqli_store_result($conn, $mode);
}
function mysql_thread_id($conn) {
    return mysqli_thread_id($conn);
}
function mysql_thread_safe() {
    return mysqli_thread_safe();
}
function mysql_use_result($conn) {
    return mysqli_use_result($conn);
}
function mysql_warning_count($conn) {
    return mysqli_warning_count($conn);
}

?>

呼び出されない関数もあると思いますが、まとめて作りました。

さて、これをどこに入れる?

wp-config.php か wp-settings.php だろうと思ったら wp-load.php の先頭でないと管理画面にログインできませんでした。何だこのシステム??

ログインを実行したら真っ白

さぁログインして更新してやろう!とログインを試みると、案の定、ログインが途中で止まります。エラーログを見ると wp-includes/user.php [41行目] でエラーが出ていました。ファイルを開いて見てみたら・・・あまりに酷いコードだったので晒します。

function wp_signon( $credentials = '', $secure_cookie = '' ) {
	if ( empty($credentials) ) {
		if ( ! empty($_POST['log']) )
			$credentials['user_login'] = $_POST['log'];
		if ( ! empty($_POST['pwd']) )
			$credentials['user_password'] = $_POST['pwd'];
		if ( ! empty($_POST['rememberme']) )
			$credentials['remember'] = $_POST['rememberme'];
	}

	if ( !empty($credentials['remember']) )
		$credentials['remember'] = true;
	else
		$credentials['remember'] = false;

	// TODO do we deprecate the wp_authentication action?
	do_action_ref_array('wp_authenticate', array(&$credentials['user_login'], &$credentials['user_password']));

エラー箇所は最終行ですが、 $credentials を文字列で宣言しておきながら常に配列として使っているところに狂気を感じます。よく読むと各キーは初期化されそうに見えますが、 PHP Fatal error: Uncaught Error: Cannot create references to/from string offsets ということなので、直さないといけません。

wp_signon を呼び出している wp-login.php [572行目] の以下の箇所を直します。

$user = wp_signon('', $secure_cookie);

string offsets という言葉は文字列変数を配列扱いした時に使われるので、空配列を渡せばOKです。

$user = wp_signon([], $secure_cookie);

これでログインができました。WordPressも最新版にアップグレードして、無事用件を果たせました。

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください