user_save

定義

user_save($account, $array = array(), $category = 'account')
modules/user/user.module, 第 106 行開始

描述

更新一個使用者帳號內容,或是建立一個新的帳號

參數

$account 一個 user 物件,如果 $user->uid(帳號 ID)為空,則建立新的帳號,如果有東西的話,就更新這個 uid 的帳號資料
$array 一個帶有帳號資訊的陣列。例如: array('name' => 'My name'); 值為 NULL 的話,就表示把這個欄位清空。
(註: 在更新中,沒有列在這個陣列裡的欄位會保持不變)
$category (選擇性參數) 用來作註記的參數。在這個函數中並沒有用到,主要是用來當參數傳給相關的 hook 函數。

範例

第一個參數要求的是一個 user 物件,但是其實只用到裡面的 uid 屬性。
所以要新增一個帳號的時候,並不用費心去建立一個"空的 user 物件",給它一個 '' (空字串)就好了。
如:

$roles = array(
'3' => '角色名稱',
'4' => '角色名稱',
'5' => '角色名稱',
);
user_save('', array("name" => '納格髓', "pass" => 'unknow', "status" => 1, 'roles' => $roles , 'profile_tel' => '0800 123456'));;

name: 帳號名稱
pass: 密碼 (不需要作加密動作)
status: 狀態(1 表示啟用中)
roles: 權限,也許叫它"群組"比較適合,這裡要放array。(例子中,是加入編號3, 4, 5 的群組)
profile_tel: 這個是自訂的使用者欄位,名字叫作"tel"

註:
在 Drupal 的群組(roles)中,1 表示訪客,2 表示已註冊帳號。這兩個資訊在記錄的時候會"自動跳過"。因為有沒有帳號就已經足以作為這兩者的區分。所以就算你在roles放入 1 或 2 也不會被記入資料庫中。
(原來文章的例子是直接打 array(3, 4, 5) 來加入編號 3, 4, 5的角色,這種寫法是錯誤的)

原始碼

<?php
function user_save($account, $array = array(), $category = 'account') {
// Dynamically compose a SQL query:
$user_fields = user_fields();
if ($account->uid) {
user_module_invoke('update', $array, $account, $category);

$data = unserialize(db_result(db_query('SELECT data FROM {users} WHERE uid = %d', $account->uid)));
foreach ($array as $key => $value) {
if ($key == 'pass' && !empty($value)) {
$query .= "$key = '%s', ";
$v[] = md5($value);
}
else if ((substr($key, 0, 4) !== 'auth') && ($key != 'pass')) {
if (in_array($key, $user_fields)) {
// Save standard fields
$query .= "$key = '%s', ";
$v[] = $value;
}
else if ($key != 'roles') {
// Roles is a special case: it used below.
if ($value === NULL) {
unset($data[$key]);
}
else {
$data[$key] = $value;
}
}
}
}
$query .= "data = '%s' ";
$v[] = serialize($data);

db_query("UPDATE {users} SET $query WHERE uid = %d", array_merge($v, array($account->uid)));

// Reload user roles if provided
if (is_array($array['roles'])) {
db_query('DELETE FROM {users_roles} WHERE uid = %d', $account->uid);

foreach (array_keys($array['roles']) as $rid) {
if (!in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) {
db_query('INSERT INTO {users_roles} (uid, rid) VALUES (%d, %d)', $account->uid, $rid);
}
}
}

// Delete a blocked user's sessions to kick them if they are online.
if (isset($array['status']) && $array['status'] == 0) {
sess_destroy_uid($account->uid);
}

// If the password changed, delete all open sessions and recreate
// the current one.
if (isset($array['pass'])) {
sess_destroy_uid($account->uid);
sess_regenerate();
}

// Refresh user object
$user = user_load(array('uid' => $account->uid));
user_module_invoke('after_update', $array, $user, $category);
}
else {
$array['uid'] = db_next_id('{users}_uid');

if (!isset($array['created'])) { // Allow 'created' to be set by hook_auth
$array['created'] = time();
}

// Note, we wait with saving the data column to prevent module-handled
// fields from being saved there. We cannot invoke hook_user('insert') here
// because we don't have a fully initialized user object yet.
foreach ($array as $key => $value) {
switch ($key) {
case 'pass':
$fields[] = $key;
$values[] = md5($value);
$s[] = "'%s'";
break;
case 'uid': case 'mode': case 'sort':
case 'threshold': case 'created': case 'access':
case 'login': case 'status':
$fields[] = $key;
$values[] = $value;
$s[] = "%d";
break;
default:
if (substr($key, 0, 4) !== 'auth' && in_array($key, $user_fields)) {
$fields[] = $key;
$values[] = $value;
$s[] = "'%s'";
}
break;
}
}
db_query('INSERT INTO {users} ('. implode(', ', $fields) .') VALUES ('. implode(', ', $s) .')', $values);

// Build the initial user object.
$user = user_load(array('uid' => $array['uid']));

user_module_invoke('insert', $array, $user, $category);

// Build and save the serialized data field now
$data = array();
foreach ($array as $key => $value) {
if ((substr($key, 0, 4) !== 'auth') && ($key != 'roles') && (!in_array($key, $user_fields)) && ($value !== NULL)) {
$data[$key] = $value;
}
}
db_query("UPDATE {users} SET data = '%s' WHERE uid = %d", serialize($data), $user->uid);

// Save user roles (delete just to be safe).
if (is_array($array['roles'])) {
db_query('DELETE FROM {users_roles} WHERE uid = %d', $array['uid']);
foreach (array_keys($array['roles']) as $rid) {
if (!in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) {
db_query('INSERT INTO {users_roles} (uid, rid) VALUES (%d, %d)', $array['uid'], $rid);
}
}
}

// Build the finished user object.
$user = user_load(array('uid' => $array['uid']));
}

// Save distributed authentication mappings
$authmaps = array();
foreach ($array as $key => $value) {
if (substr($key, 0, 4) == 'auth') {
$authmaps[$key] = $value;
}
}
if (sizeof($authmaps) > 0) {
user_set_authmaps($user, $authmaps);
}

return $user;
}
?>

Drupal版本: