0%

正威網路行銷工作室,專注於基隆、台北與全台客製化網頁設計,提供專業 RWD 響應式、SEO 搜尋引擎優化、品牌形象設計與網站維護託管服務。

搜尋文章
聯絡資訊
地址基隆市仁二路 220 號 5 樓
追蹤我們

WordPress 註冊表單自訂:多問幾個欄位、讓使用者自己設密碼(含 WooCommerce 我的帳號)

WordPress 註冊表單自訂:多問幾個欄位、讓使用者自己設密碼(含 WooCommerce 我的帳號) 封面

WordPress 內建的會員註冊表單只有兩格:使用者名稱和電子郵件地址。按下註冊後,會員還要去收信、點連結設定密碼,才能登入。很多人卡在收信這一步,信跑到垃圾郵件匣,就再也沒回來了。

這篇不用外掛,把註冊表單改成:

  • 多問姓名和手機,送出時檢查格式。
  • 會員自己設定密碼,還要再輸入一次確認,註冊完就能直接登入。
  • 後台的使用者「個人資料」頁看得到手機,管理員也能修改。
  • 有用 WooCommerce 的話,「我的帳號」頁面的註冊表單也一起處理。

程式碼放在子佈景主題的 functions.php,或用 Code Snippets 這類外掛新增。

先打開註冊功能

到 設定 → 一般:

  • 「成員資格」勾選「任何人均可註冊」。
  • 「新使用者的預設使用者角色」選「訂閱者」。不要選編輯或管理員,任何人都能註冊的話,這個角色就是陌生人拿到的權限。

註冊頁的網址是 你的網址/wp-login.php?action=register。

一、WordPress 註冊表單加欄位、自己設密碼

PHP
// 1. 註冊表單多三個欄位:姓名、手機、自己設定密碼
add_action( 'register_form', function () {
	$name  = sanitize_text_field( wp_unslash( $_POST['zw_name'] ?? '' ) );
	$phone = sanitize_text_field( wp_unslash( $_POST['zw_phone'] ?? '' ) );
	?>
	<p>
		<label for="zw_name">姓名</label>
		<input type="text" name="zw_name" id="zw_name" class="input" value="<?php echo esc_attr( $name ); ?>" autocomplete="name">
	</p>
	<p>
		<label for="zw_phone">手機(選填)</label>
		<input type="tel" name="zw_phone" id="zw_phone" class="input" value="<?php echo esc_attr( $phone ); ?>" autocomplete="tel" placeholder="0912345678">
	</p>
	<p>
		<label for="zw_pass1">密碼(至少 8 個字元)</label>
		<input type="password" name="zw_pass1" id="zw_pass1" class="input" autocomplete="new-password">
	</p>
	<p>
		<label for="zw_pass2">再輸入一次密碼</label>
		<input type="password" name="zw_pass2" id="zw_pass2" class="input" autocomplete="new-password">
	</p>
	<?php
} );

// 2. 送出時檢查欄位,有錯就擋下來
add_filter( 'registration_errors', function ( $errors ) {
	$name  = trim( sanitize_text_field( wp_unslash( $_POST['zw_name'] ?? '' ) ) );
	$phone = trim( sanitize_text_field( wp_unslash( $_POST['zw_phone'] ?? '' ) ) );
	$pass1 = wp_unslash( $_POST['zw_pass1'] ?? '' );
	$pass2 = wp_unslash( $_POST['zw_pass2'] ?? '' );
	if ( '' === $name ) {
		$errors->add( 'zw_name', '<strong>錯誤</strong>:請填寫姓名。' );
	}
	if ( '' !== $phone && ! preg_match( '/^09\d{8}$/', $phone ) ) {
		$errors->add( 'zw_phone', '<strong>錯誤</strong>:手機請填 09 開頭的 10 位數字。' );
	}
	if ( strlen( $pass1 ) < 8 ) {
		$errors->add( 'zw_pass', '<strong>錯誤</strong>:密碼至少要 8 個字元。' );
	} elseif ( $pass1 !== $pass2 ) {
		$errors->add( 'zw_pass', '<strong>錯誤</strong>:兩次輸入的密碼不一樣。' );
	}
	return $errors;
} );

// 3. 註冊成功:存姓名、手機,改成使用者自己設的密碼
add_action( 'register_new_user', function ( $user_id ) {
	wp_update_user( array(
		'ID'           => $user_id,
		'first_name'   => sanitize_text_field( wp_unslash( $_POST['zw_name'] ?? '' ) ),
		'display_name' => sanitize_text_field( wp_unslash( $_POST['zw_name'] ?? '' ) ),
	) );
	update_user_meta( $user_id, 'zw_phone', sanitize_text_field( wp_unslash( $_POST['zw_phone'] ?? '' ) ) );
	wp_set_password( wp_unslash( $_POST['zw_pass1'] ), $user_id );
}, 5 );

// 4. 密碼已經自己設了,就不要再寄「設定密碼」的連結給新會員,只通知管理員
remove_action( 'register_new_user', 'wp_send_new_user_notifications' );
add_action( 'register_new_user', function ( $user_id ) {
	wp_new_user_notification( $user_id, null, 'admin' );
} );

// 5. 註冊完成的提示改成「可以直接登入」
add_filter( 'registration_redirect', function () {
	return add_query_arg( 'zw-registered', '1', wp_login_url() );
} );
add_filter( 'login_message', function ( $message ) {
	if ( isset( $_GET['zw-registered'] ) ) {
		$message .= '<p class="message">註冊完成,請用剛才設定的密碼登入。</p>';
	}
	return $message;
} );

逐段說明:

  1. register_form:在註冊表單裡印出四個欄位。送出後有錯被擋下來時,value 會帶回剛才填的姓名和手機,不用重填;密碼欄則不帶回。
  2. registration_errors:檢查欄位,有錯就加一條錯誤訊息,WordPress 會顯示在表單上方,並且不建立帳號。手機是選填,有填才檢查是不是 09 開頭的 10 位數字。
  3. register_new_user:帳號建立後執行。把姓名存到「名字」和「公開顯示名稱」,手機存成使用者的自訂欄位 zw_phone,再用 wp_set_password() 換成會員自己設的密碼。
  4. WordPress 原本註冊後會寄兩封信:一封給管理員,一封給新會員(內容是設定密碼的連結)。密碼已經自己設了,第二封就不需要,所以拿掉原本的寄信,改成只通知管理員。
  5. 註冊完原本顯示「請檢查電子郵件收件匣」,改成導回登入頁,顯示「註冊完成,請用剛才設定的密碼登入」。

在測試網站上實際試過:

  • 沒填姓名、手機填 02-1234、密碼只有 3 個字、兩次密碼不一樣,四種情況都被擋下來,顯示對應的錯誤訊息。
  • 正確填寫後,導回登入頁顯示「註冊完成」,用剛才設的密碼就能登入。
  • 只寄出一封「新使用者註冊」通知給管理員,會員沒有收到設定密碼的信。
  • 管理員在後台「使用者 → 新增使用者」新增帳號,一樣正常,這段程式碼只影響前台的註冊表單。

讓會員自己設密碼之前,要知道的事

原本「收信設定密碼」的流程,順便確認了這個 Email 真的是本人的。改成直接設密碼,任何人都可以拿別人的 Email 來註冊。

二、後台個人資料頁顯示手機

PHP
// 後台「個人資料」頁顯示手機,管理員也可以修改
function zw_profile_phone_field( $user ) {
	?>
	<h2>聯絡資料</h2>
	<table class="form-table" role="presentation">
		<tr>
			<th><label for="zw_phone">手機</label></th>
			<td><input type="tel" name="zw_phone" id="zw_phone" class="regular-text" value="<?php echo esc_attr( get_user_meta( $user->ID, 'zw_phone', true ) ); ?>"></td>
		</tr>
	</table>
	<?php
}
add_action( 'show_user_profile', 'zw_profile_phone_field' );
add_action( 'edit_user_profile', 'zw_profile_phone_field' );

function zw_profile_phone_save( $user_id ) {
	if ( current_user_can( 'edit_user', $user_id ) && isset( $_POST['zw_phone'] ) ) {
		update_user_meta( $user_id, 'zw_phone', sanitize_text_field( wp_unslash( $_POST['zw_phone'] ) ) );
	}
}
add_action( 'personal_options_update', 'zw_profile_phone_save' );
add_action( 'edit_user_profile_update', 'zw_profile_phone_save' );
  • show_user_profile 是自己看自己的個人資料頁,edit_user_profile 是管理員看別人的。兩個都掛上,同一個欄位兩邊都出現。
  • 存檔時用 current_user_can( 'edit_user', ... ) 確認有權限修改這個人。WordPress 在執行這兩個存檔動作之前,已經檢查過表單的安全碼(nonce)。

測試時,管理員打開會員的「編輯使用者」頁,看得到註冊時填的手機;改成另一個號碼按「更新使用者」,資料就換掉了。

三、WooCommerce「我的帳號」註冊表單

WooCommerce 的「我的帳號」頁面有自己的註冊表單,不是用上面那套。先到 WooCommerce → 設定 → 帳號與隱私權:

  • 「建立帳號」勾選「「我的帳號」頁面」,註冊表單才會出現。
  • 「帳號建立選項」的「傳送密碼設定連結 (建議)」:勾選時,顧客不用設密碼,WooCommerce 會寄設定密碼的信;取消勾選,註冊表單才會出現密碼欄,讓顧客自己設。

接著加欄位:

PHP
// WooCommerce「我的帳號」註冊表單:最上面加姓名、手機
add_action( 'woocommerce_register_form_start', function () {
	$name  = sanitize_text_field( wp_unslash( $_POST['billing_first_name'] ?? '' ) );
	$phone = sanitize_text_field( wp_unslash( $_POST['billing_phone'] ?? '' ) );
	?>
	<p class="form-row form-row-wide">
		<label for="reg_billing_first_name">姓名&nbsp;<span class="required">*</span></label>
		<input type="text" class="input-text" name="billing_first_name" id="reg_billing_first_name" value="<?php echo esc_attr( $name ); ?>" autocomplete="name">
	</p>
	<p class="form-row form-row-wide">
		<label for="reg_billing_phone">手機</label>
		<input type="tel" class="input-text" name="billing_phone" id="reg_billing_phone" value="<?php echo esc_attr( $phone ); ?>" autocomplete="tel" placeholder="0912345678">
	</p>
	<?php
} );

// 密碼欄位下面加「再輸入一次密碼」(後台設定讓顧客自己設密碼時才會有密碼欄)
add_action( 'woocommerce_register_form', function () {
	if ( 'no' !== get_option( 'woocommerce_registration_generate_password' ) ) {
		return;
	}
	?>
	<p class="form-row form-row-wide">
		<label for="reg_password2">再輸入一次密碼&nbsp;<span class="required">*</span></label>
		<input type="password" class="input-text" name="zw_password2" id="reg_password2" autocomplete="new-password">
	</p>
	<?php
} );

// 檢查欄位
add_action( 'woocommerce_register_post', function ( $username, $email, $errors ) {
	$name  = trim( sanitize_text_field( wp_unslash( $_POST['billing_first_name'] ?? '' ) ) );
	$phone = trim( sanitize_text_field( wp_unslash( $_POST['billing_phone'] ?? '' ) ) );
	if ( '' === $name ) {
		$errors->add( 'zw_name', '請填寫姓名。' );
	}
	if ( '' !== $phone && ! preg_match( '/^09\d{8}$/', $phone ) ) {
		$errors->add( 'zw_phone', '手機請填 09 開頭的 10 位數字。' );
	}
	if ( 'no' === get_option( 'woocommerce_registration_generate_password' )
		&& wp_unslash( $_POST['password'] ?? '' ) !== wp_unslash( $_POST['zw_password2'] ?? '' ) ) {
		$errors->add( 'zw_password2', '兩次輸入的密碼不一樣。' );
	}
}, 10, 3 );

// 存成 WooCommerce 的帳單姓名、電話,結帳時會自動帶入
add_action( 'woocommerce_created_customer', function ( $customer_id ) {
	$customer = new WC_Customer( $customer_id );
	$name     = sanitize_text_field( wp_unslash( $_POST['billing_first_name'] ?? '' ) );
	$customer->set_first_name( $name );
	$customer->set_display_name( $name );
	$customer->set_billing_first_name( $name );
	$customer->set_billing_phone( sanitize_text_field( wp_unslash( $_POST['billing_phone'] ?? '' ) ) );
	$customer->save();
} );
  • woocommerce_register_form_start 在表單最上面加姓名、手機;woocommerce_register_form 在密碼欄下面加「再輸入一次密碼」。只有設定成讓顧客自己設密碼時,才會出現確認密碼欄。
  • woocommerce_register_post 檢查欄位,錯誤訊息會用 WooCommerce 的紅色提示框顯示。
  • woocommerce_created_customer 把姓名、手機存成 WooCommerce 的帳單姓名和電話。用這兩個欄位的好處是,顧客第一次結帳時就會自動帶入,不用再填一次。

測試兩種設定都註冊過:讓顧客自己設密碼時,兩次密碼不同、手機格式不對都被擋下;正確註冊後直接登入,顧客資料裡的帳單姓名、電話都有存進去。改回「傳送密碼設定連結」時,表單只剩姓名、手機和 Email,一樣可以註冊。

使用時要注意

  • 欄位不要問太多。每多一個必填欄位,就有人填到一半放棄。只問真的會用到的資料。
  • 手機、姓名是個人資料。隱私權政策要寫清楚收集哪些資料、用來做什麼。
  • 網站有快取外掛的話,註冊頁、「我的帳號」頁要排除在快取之外,大部分快取外掛預設已經排除,換外掛時記得確認。

延伸閱讀

會員註冊流程順不順,直接影響有多少人願意加入。正威網路行銷是 25 年經驗的基隆網頁設計工作室,會員註冊、購物網站的流程都能依你的需求規劃,台北與全台客戶也歡迎來聊聊。

分享這篇文章

返回文章列表更多「Wordpress代碼教學」文章

發表留言

還沒有人留言,歡迎第一個分享你的想法或問題。留言經審核後才會顯示,Email 不會公開。

讓我們一起打造
您的專屬網站!