2026年7月17日
2026年7月17日
WordPressにメンバーシップ機能を実装する方法
はじめに
「WordPressサイトに会員制コンテンツを追加したい」「特定のロールにのみ記事を公開したい」「会員登録フォームとログインページを独自にデザインしたい」——WordPressの標準機能とカスタムコードを組み合わせることで、シンプルなメンバーシップ機能を実装できます。
症状・原因
有料プラグイン(MemberPress・Paid Memberships Pro)を使わずに、独自のメンバーシップ機能を実装したい場合、ユーザー登録・ロール管理・コンテンツ保護・リダイレクト制御を組み合わせます。
解決手順
ステップ1:会員登録機能を設定する
// functions.php: 会員登録の基本設定
add_action( 'after_setup_theme', function(): void {
// 一般設定 → 会員登録を有効化(コードで制御する場合)
update_option( 'users_can_register', true );
// 新規会員のデフォルトロールを設定
update_option( 'default_role', 'subscriber' );
} );
// カスタム会員登録フォームを実装
add_shortcode( 'member_register_form', function(): string {
if ( is_user_logged_in() ) {
return '<p><a href="' . esc_url( home_url( '/member/' ) ) . '">マイページへ</a></p>';
}
$errors = [];
if ( 'POST' === $_SERVER['REQUEST_METHOD'] && isset( $_POST['register_nonce'] ) ) {
if ( ! wp_verify_nonce( sanitize_text_field( $_POST['register_nonce'] ), 'member_register' ) ) {
$errors[] = 'セキュリティチェックに失敗しました。';
} else {
$username = sanitize_user( $_POST['username'] ?? '' );
$email = sanitize_email( $_POST['email'] ?? '' );
$password = $_POST['password'] ?? '';
$password2 = $_POST['password2'] ?? '';
if ( empty( $username ) || empty( $email ) || empty( $password ) ) {
$errors[] = 'すべての項目を入力してください。';
} elseif ( $password !== $password2 ) {
$errors[] = 'パスワードが一致しません。';
} elseif ( strlen( $password ) < 8 ) {
$errors[] = 'パスワードは8文字以上で設定してください。';
} elseif ( username_exists( $username ) ) {
$errors[] = 'このユーザー名はすでに使用されています。';
} elseif ( email_exists( $email ) ) {
$errors[] = 'このメールアドレスはすでに登録されています。';
} else {
$user_id = wp_create_user( $username, $password, $email );
if ( ! is_wp_error( $user_id ) ) {
// 登録完了メールを送信
wp_new_user_notification( $user_id, null, 'user' );
wp_set_current_user( $user_id );
wp_set_auth_cookie( $user_id );
wp_redirect( home_url( '/member/' ) );
exit;
}
$errors[] = $user_id->get_error_message();
}
}
}
ob_start();
?>
<?php foreach ( $errors as $error ) : ?>
<div class="member-error"><?php echo esc_html( $error ); ?></div>
<?php endforeach; ?>
<form method="post" class="member-register-form">
<?php wp_nonce_field( 'member_register', 'register_nonce' ); ?>
<p>
<label>ユーザー名 <input type="text" name="username" required></label>
</p>
<p>
<label>メールアドレス <input type="email" name="email" required></label>
</p>
<p>
<label>パスワード <input type="password" name="password" minlength="8" required></label>
</p>
<p>
<label>パスワード(確認) <input type="password" name="password2" required></label>
</p>
<p>
<button type="submit">会員登録</button>
</p>
</form>
<?php
return ob_get_clean();
} );
ステップ2:コンテンツを会員限定に制限する
// functions.php: 投稿・固定ページを会員限定にする
// カスタムメタフィールドで会員限定を設定
add_action( 'add_meta_boxes', function(): void {
add_meta_box(
'member_only',
'会員限定設定',
function( WP_Post $post ): void {
wp_nonce_field( 'member_only_meta', 'member_only_nonce' );
$is_member_only = get_post_meta( $post->ID, '_member_only', true );
echo '<label><input type="checkbox" name="member_only" value="1" '
. checked( $is_member_only, '1', false ) . '> 会員のみ閲覧可能</label>';
},
[ 'post', 'page' ],
'side'
);
} );
add_action( 'save_post', function( int $post_id ): void {
if ( ! isset( $_POST['member_only_nonce'] )
|| ! wp_verify_nonce( sanitize_text_field( $_POST['member_only_nonce'] ), 'member_only_meta' )
|| ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
) {
return;
}
update_post_meta( $post_id, '_member_only', isset( $_POST['member_only'] ) ? '1' : '0' );
} );
// フロントエンドでのアクセス制限
add_action( 'template_redirect', function(): void {
if ( ! is_singular() ) {
return;
}
$post_id = get_queried_object_id();
if ( '1' !== get_post_meta( $post_id, '_member_only', true ) ) {
return;
}
if ( ! is_user_logged_in() ) {
wp_redirect( wp_login_url( get_permalink() ) );
exit;
}
// 特定ロール(premium_memberなど)に絞る場合
if ( ! current_user_can( 'read' ) ) {
wp_redirect( home_url( '/member-required/' ) );
exit;
}
} );
ステップ3:会員限定コンテンツのショートコードを実装する
// functions.php: 記事の一部だけを会員限定にする
// [member_only]会員限定コンテンツ[/member_only]
add_shortcode( 'member_only', function( array $atts, string $content = '' ): string {
$atts = shortcode_atts( [
'role' => '', // 特定ロールのみ(空=全会員)
'message' => '会員限定コンテンツです。<a href="' . wp_login_url() . '">ログイン</a>または<a href="' . home_url( '/register/' ) . '">会員登録</a>してください。',
], $atts );
if ( ! is_user_logged_in() ) {
return '<div class="member-only-message">' . wp_kses_post( $atts['message'] ) . '</div>';
}
if ( ! empty( $atts['role'] ) && ! current_user_can( $atts['role'] ) ) {
return '<div class="member-only-message">このコンテンツを閲覧する権限がありません。</div>';
}
return '<div class="member-only-content">' . do_shortcode( $content ) . '</div>';
} );
ステップ4:マイページを実装する
// functions.php: 会員マイページのショートコード
add_shortcode( 'member_mypage', function(): string {
if ( ! is_user_logged_in() ) {
wp_redirect( wp_login_url( get_permalink() ) );
exit;
}
$user = wp_get_current_user();
// プロフィール更新処理
$message = '';
if ( 'POST' === $_SERVER['REQUEST_METHOD'] && isset( $_POST['profile_nonce'] ) ) {
if ( wp_verify_nonce( sanitize_text_field( $_POST['profile_nonce'] ), 'update_profile' ) ) {
$display_name = sanitize_text_field( $_POST['display_name'] ?? '' );
$result = wp_update_user( [
'ID' => $user->ID,
'display_name' => $display_name,
] );
$message = is_wp_error( $result ) ? 'エラー: ' . $result->get_error_message() : 'プロフィールを更新しました。';
}
}
ob_start();
?>
<div class="member-mypage">
<h2><?php echo esc_html( $user->display_name ); ?> さん、こんにちは</h2>
<?php if ( $message ) : ?>
<p class="member-message"><?php echo esc_html( $message ); ?></p>
<?php endif; ?>
<form method="post" class="profile-form">
<?php wp_nonce_field( 'update_profile', 'profile_nonce' ); ?>
<p>
<label>表示名 <input type="text" name="display_name"
value="<?php echo esc_attr( $user->display_name ); ?>"></label>
</p>
<p>メールアドレス: <?php echo esc_html( $user->user_email ); ?></p>
<p><button type="submit">更新する</button></p>
</form>
<p><a href="<?php echo esc_url( wp_logout_url( home_url() ) ); ?>">ログアウト</a></p>
</div>
<?php
return ob_get_clean();
} );
ステップ5:プラグインを使う場合の選択基準
メンバーシッププラグインの比較:
【無料実装(カスタムコード)】
- 向き: シンプルな会員限定表示のみ
- メリット: 軽量・完全なカスタマイズ
- デメリット: 決済連携・複数プランが困難
【Paid Memberships Pro(無料版あり)】
- 向き: 複数の会員プランが必要
- メリット: PayPal/Stripe連携・詳細なコンテンツ制限
- デメリット: 高度な機能は有料
【MemberPress(有料)】
- 向き: 有料会員サイト・コース販売
- メリット: LMS連携・詳細な分析・Stripe/PayPal
- デメリット: 年間$179.50〜(最安プラン)
【WooCommerce Memberships(有料)】
- 向き: ECと会員制を組み合わせる
- メリット: WooCommerceと深い連携
- デメリット: WooCommerce必須・$199/年
注意事項
- 会員登録フォームは必ずnonceで検証し、
sanitize_user()・sanitize_email()でサニタイズしてください。XSSやSQLインジェクションに注意が必要です。 template_redirectでリダイレクトする際はexitを忘れないでください。忘れるとページが部分的に読み込まれます。- 有料コンテンツを提供する場合はカスタムコードではなくMemberPressやPaid Memberships Proの使用を強く推奨します。決済・返金処理は専用プラグインに任せるべきです。
まとめ
メンバーシップ機能の実装は「wp_create_user()で会員登録フォームを実装→カスタムメタフィールド_member_onlyで投稿ごとの制限を設定→template_redirectで未ログインをログインページにリダイレクト→member_only]ショートコードで記事内の一部を制限→マイページショートコードでプロフィール管理→決済が必要な場合はMemberPressを検討」の流れで整備します。関連記事:[WordPressのユーザーロールと権限をカスタマイズする方法、WordPressのログインページをカスタマイズする方法。