2

我刚刚开始学习 php、javascript 等.. 尝试使用 ajax 做一个会员系统,今天刚刚完成,我检查了一下,我发现我只使用 if else 语句来完成所有代码.. .有更好的方法吗?

成员更新.js

$('#member_update_form').submit(false);

function check_member_update(){
    $.ajax({  
        type: "POST",  
        url: "../handlers/member_update_validation.php?do=update",  
        data: $("#member_update_form").serialize(),  
        dataType: "json", 
        success: function(msg){
            if(msg.status == 'error'){
                $("#error_dialog_box").html('出錯,請再嘗試');
                update_showWarning();
            }
            if(msg.status == 'cookie_error'){
                $("#error_dialog_box").html('帳號信息出錯,請重新登入');
                update_showWarning();
            }
            if(msg.status == 'captcha_error'){
                $("#error_dialog_box").html('請正確輸入驗證碼');
                update_showWarning();
            }
            if(msg.status == 'username_error'){
                $("#error_dialog_box").html('請別嘗試修改用戶名');
                update_showWarning();
            }
            if(msg.status == 'name_error'){
                $("#error_dialog_box").html('請輸入暱稱,1-10個字符');
                update_showWarning();
            }
            if(msg.status == 'email_empty'){
                $("#error_dialog_box").html('電子郵件地址不能為空');
                update_showWarning();
            }
            if(msg.status == 'email_format_error'){
                $("#error_dialog_box").html('電子郵件地址格式錯誤');
                update_showWarning();
            }
            if(msg.status == 'email_taken'){
                $("#error_dialog_box").html('輸入的電子郵件地址已被使用');
                update_showWarning();
            }
            if(msg.status == 'password_error'){
                $("#error_dialog_box").html('密碼錯誤!不可使用符號或中文!6-40字符');
                update_showWarning();
            }
            if(msg.status == 'update_password_error'){
                $("#error_dialog_box").html('新密碼錯誤!不可使用中文符號或中文!6-40字符');
                update_showWarning();
            }
            if(msg.status == 'update_password_not_match'){
                $("#error_dialog_box").html('新密碼與確認新密碼不一致');
                update_showWarning();
            }
            if(msg.status == 'update_wrong_password'){
                $("#error_dialog_box").html('當前密碼輸入錯誤,請再次確認');
                update_showWarning();
            }
            if(msg.status == 'update_success_all'){
                $("#success_dialog_box").html('已成功更改個人資料,請重新登入');
                update_showSuccessRelog();
            }
            if(msg.status == 'update_success'){
                $("#success_dialog_box").html('已成功更改個人資料');
                update_showSuccess();
            }
        },
        error: function(){  
            document.getElementById('update_captcha_img').src = '/securimage/securimage_show.php?' + Math.random();
            alert('未知錯誤,請聯絡管理員');
        }
    });
    //make sure the form doesn't post  
    return false;  
};

member_update_validation.php

<?php

include_once $_SERVER['DOCUMENT_ROOT'] . '/securimage/securimage.php';
$securimage = new Securimage();
$response_array = array();  
require $_SERVER['DOCUMENT_ROOT'] . '/common/db/main.db.php';

if(!empty($_GET['do']) && $_SESSION['loggedIn'] == 1 && isset($_COOKIE['logintoken'])){
    if($_GET['do'] == 'update'){

        if($_SESSION['logintoken'] != $_COOKIE['logintoken']){
            $response_array['status'] = 'cookie_error';
        }else{
            $logintoken = $_COOKIE['logintoken'];

            $database = new Database();
            $database->query('SELECT * FROM member_info WHERE logintoken = :logintoken');
            $database->bind(':logintoken',$logintoken);
            $check_user = $database->single();

            $username = mysql_real_escape_string(strtolower($check_user['username']));
            $name = mysql_real_escape_string($_POST['update_name']);
            $email = mysql_real_escape_string($_POST['update_email']);
            if(!empty($_POST['update_contact'])){
                $contact = mysql_real_escape_string($_POST['update_contact']);
            }else{
                $contact = '';
            }
            if(!empty($_POST['update_bday'])){
                $bdate = mysql_real_escape_string($_POST['update_bday']);
            }else{
                $bdate = '';
            }
            $password = mysql_real_escape_string($_POST['password']);
            if(!empty($_POST['update_password'])){
                $update_password = mysql_real_escape_string($_POST['update_password']);
            }else{
                $update_password = '';
            }
            if(!empty($_POST['update_confirm_password'])){
                $update_confirm_password = mysql_real_escape_string($_POST['update_confirm_password']);
            }else{
                $update_confirm_password = '';
            }
            $captcha = mysql_real_escape_string($_POST['update_captcha']);
            unset($_POST);

            if(empty($captcha) || $securimage->check($captcha) == false){
                $response_array['status'] = 'captcha_error';
            }
            if($username != $check_user['username']){
                $response_array['status'] = 'username_error';
            }
            if(strlen($name) < 1 || strlen($name) > 10){
                $response_array['status'] = 'name_error';
            }
            if(empty($email)){
                $response_array['status'] = 'email_empty';
            }
            if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE){
                $response_array['status'] = 'email_format_error';
            }
            if($email != $check_user['email']){

                $database = new Database();
                $database->query('SELECT * FROM member_info WHERE email = :email');
                $database->bind(':email',$email);
                $exmail = $database->single();

                if(!empty($exmail)){
                    $response_array['status'] = 'email_taken';
                    unset($exmail);
                }
            }
            if(strlen($password) < 6 || strlen($password) > 40){
                $response_array['status'] = 'password_error';
            }
            if(!empty($update_password) && !empty($update_confirm_password)){
                if(strlen($update_password) < 6 || strlen($update_password) > 40){
                    $response_array['status'] = 'update_password_error';
                }
                if($update_password != $update_confirm_password){
                    $response_array['status'] = 'update_password_not_match';
                }
            }

            if(empty($response_array['status'])){

                $check_password = hash('sha256', $password . $check_user['salt']); 
                for($round = 0; $round < 65536; $round++){ 
                    $check_password = hash('sha256', $check_password . $check_user['salt']); 
                }
                if($check_password === $check_user['password']){
                    $login_ok = true;
                }else{
                    $login_ok = false;
                    $response_array['status'] = 'update_wrong_password';
                }
                if($login_ok == true){
                    if(!empty($update_password)){

                        $salt = dechex(mt_rand(0, 2147483647)) . dechex(mt_rand(0, 2147483647));
                        $update_password = hash('sha256', $update_password . $salt);
                        for($round = 0; $round < 65536; $round++){ 
                            $update_password = hash('sha256', $update_password . $salt); 
                        }

                        $database = new Database();
                        $database->query('UPDATE member_info SET email = :email, name = :name, contact = :contact, birthdate = :bdate, password = :update_password, salt = :salt WHERE username = :username');
                        $database->bind(':username', $check_user['username']);
                        $database->bind(':email', $email);
                        $database->bind(':name', $name);
                        $database->bind(':contact', $contact);
                        $database->bind(':bdate', $bdate);
                        $database->bind(':update_password', $update_password);
                        $database->bind(':salt', $salt);
                        $database->execute();

                        $response_array['status'] = 'update_success_all';
                    }else{
                        $database = new Database();
                        $database->query('UPDATE member_info SET email = :email, name = :name, contact = :contact, birthdate = :bdate WHERE username = :username');
                        $database->bind(':username', $check_user['username']);
                        $database->bind(':email', $email);
                        $database->bind(':name', $name);
                        $database->bind(':contact', $contact);
                        $database->bind(':bdate', $bdate);
                        $database->execute();

                        $response_array['status'] = 'update_success';
                    }
                }
            }

        }

    }else{
        $response_array['status'] = 'error';
    }
    unset($check_user);
    echo json_encode($response_array);
    unset($response_array);
    return false;
}else{
    header('Location: index.php');
}

?>

member-update.jsajax 发布member_update_validation.php$response_array['status']返回并根据状态运行一些 jquery 代码......这只是更新代码,我还有 4 个几乎相同的文件用于登录和注册......有人能指出我正确的方法吗除了 if else 语句?

4

3 回答 3

3

您可以通过使用对象文字在消息之间切换来大大缩短 ajax 回调中的 if 语句:

var errors = {
    'error': '出錯,請再嘗試',
    'cookie_error': '帳號信息出錯,請重新登入',
    'captcha_error': '請正確輸入驗證碼',
    'username_error': '請別嘗試修改用戶名',
    'name_error': '請輸入暱稱,1-10個字符',
    'email_empty': '電子郵件地址不能為空',
    'email_format_error': '電子郵件地址格式錯誤',
    'email_taken': '輸入的電子郵件地址已被使用',
    'password_error': '密碼錯誤!不可使用符號或中文!6-40字符',
    'update_password_error': '新密碼錯誤!不可使用中文符號或中文!6-40字符',
    'update_password_not_match': '新密碼與確認新密碼不一致',
    'update_wrong_password': '當前密碼輸入錯誤,請再次確認'
};
var successes = {    
    'update_success_all': '已成功更改個人資料,請重新登入',
    'update_success': '已成功更改個人資料'
};
var status = msg.status;
if (status in errors) {
    $("#error_dialog_box").html(errors[status]);
    update_showWarning(); // maybe you can avoid this function call and inline it
} else if(status in successes) {
    $("#success_dialog_box").html(successes[status]);
    update_showSuccess(); // maybe you can avoid this function call and inline it
}

至少,您应该使用else-if语句,以便在发现您的状态时停止与所有其他可能性进行比较。

于 2013-05-20T12:03:31.600 回答
1

JavaScript 改进

您可以减少常见部分,例如错误总是附加到 error_dialog_box,然后调用 update_showWarning 方法。此外,无论类型如何,消息总是添加到元素中,然后调用方法:

success: function(msg){

    var el, next

        // Looks up the real message text in the
        // object literal containing status labels
        // for the current localization
      , message = L10n[msg.status]

        // Looks up the type of the message in a
        // object literal that maps the message
        // to a type regardless of locale
      , type = types[msg.status];

    if(message && type) {

        // If the type is an error, use the error dialog box
        // and the showWarning function 
        if(type === "error") {
            el = $("#error_dialog_box");
            next = update_showWarning;

        // If the type is a success, use the success dialog box
        // and the showSuccess function
        } else if(type === "success") {
            el = $("#success_dialog_box");
            next = update_showSuccess;

        } else if(type === "successRelog")
            el = $("#success_dialog_box");
            next = update_showSuccessRelog;
        }

        // The message type was found and a
        // label exists for the current locale
        // display the message          
        if(el && next) {
            el.html(message);
            next();
        }
    }

},

然后,您将维护一个对象文字,将 msg.status 映射到标签,并将 msg.status 映射到类型:

var L10n = 
    { "error" : "xyz"
    , "cookie_error" : "abc"
    /*...*/ };

var types = {
    { "error" : "error"
    /*...*/ };

我认为@Bergi 的方法可能更好,因为在这种方法中,您总是有可能忘记将类型添加到类型数组中......

PHP 修改

此构造检查表单数据以将其分配给变量,否则留空:

if(!empty($_POST['update_contact'])){
    $contact = mysql_real_escape_string($_POST['update_contact']);
}else{
    $contact = '';
}

可以变成:

// The default value is blank
$contact = '';
// This is only overwritten if the update_contact field
// was posted and non empty
if(!empty($_POST['update_contact']))
    $contact = mysql_real_escape_string($_POST['update_contact']);

这样,您可以将默认值组合在一起。

我很想将输入集合、验证和数据库交互分离到他们自己的方法中。

您还可以对所有输入变量使用 assoc 数组,以便更轻松地对其进行操作:

// Default values, if they are all blank by default
// you could just loop over an array of keys instead
$data = array(
    "update_contact" => ""
    , "update_bday" => ""
    , "password" => ""
    , "update_password" => ""
    , "update_confirm_password" => ""
);

// The mysql_real_escape_string function is applied
// to all of the fields that were posted (it would be
// appropriate to filter the $_POST array to fields
// we are interested in first) and then these modified
// values are merged into the default values
$data = array_merge($data, array_map(mysql_real_escape_string, $_POST));
于 2013-05-20T11:55:31.077 回答
0

第一个片段是本地化问题:您通常希望从代码中提取界面消息,以便可以轻松编辑和翻译它们。然后,您可以使用一个键来引用每条消息,并利用这些键来简化您的控制流:

var messages = {
    error: '出錯,請再嘗試',
    cookie_error: '帳號信息出錯,請重新登入',
    ...
};

function onUpdateSuccess(msg) {
    var errorMessage = messages[msg.status];
    $("#success_dialog_box").html(errorMessage);
    update_showSuccessRelog();
}

稍后您可以messages在服务器端生成对象,将其存储在数据库中,使其依赖于当前选择的站点语言等。

在服务器端,您可能希望分离验证逻辑并使其可重用:

class Validate {
    public static function length($input, $min, $max) {
        $length = strlen($input);
        return $length >= min && $length <= $max;
    }

    public static function notEmpty($input) {
        return !empty($input);
    }

    public static function email($input) {
        return filter_var($input, FILTER_VALIDATE_EMAIL);
    }
    ...
}

然后,您可以使用您的验证器组件从控制逻辑中提取验证条件:

$validationRules = array(
    'username' => array(
        array('length', 1, 10, 'name_error'),
    ),
    'email' => array(
        array('notEmpty', 'email_empty'),
        array('email', 'email_format_error'),
    ),
    ...
);

$formData = array();
foreach (array('username', 'email', ...) as $input) {
    $formData[$input] = empty($_POST[$input]) ? '' : $_POST[$input];
    // if Database::bind() is sanely written, mysql_real_escape_string is unnecessary
}

$errors = array();
foreach ($formData as $field => $value) {
    if (isset($validationRules[$field]) {
        foreach ($validationRules[$field] as $rule) {
            $ruleName = $rule[0];
            $error = end($rule);
            $arguments = array_slice($rule, 1, -1);
            array_unshift($arguments, $value);
            $valid = call_user_func_array(array('Validate', $ruleName), $arguments);
            if (!valid) {
                $errors[$field] = $error;
                break;
            }
        }
    }
}
于 2013-05-20T12:13:43.313 回答