На PHP - создание нового пользователя в БД с использованием MVC фреймворка


Я работаю на процесс регистрации новых пользователей из небольшой веб-приложение, и как это во многом учебного проекта, я делаю его с нуля.

Вот мой пользовательский класс: Class_user.php

<?php
    class User {
        // The class variables are the same and have the same name as the db fields.
        private $userID; // Must be incremental + unique.  Also used as salt.
        private $userName; // Must be unique.
        private $hashedPassword;
        private $userEmail;

        function __construct($userID, $userName, $hashedPassword, $userEmail){
            $this->userID=$userID;
            $this->userName=$userName;
            $this->hashedPassword=$hashedPassword;
            $this->userEmail=$userEmail;
        }
        function getUserID(){
            return $this->userID;
        }
        function getUserName() {
            return $this->userName;
        }
        function getHashedPassword() {
            return $this->hashedPassword;
        }
        function getUserEmail() {
            return $this->userEmail;
        }
    }
?>

Вот моя модель для пользователя - Model_User.php:

<?php
    require_once('Class_DB.php');
    require_once('Class_User.php');
    require_once('DAO_User.php');

    class Model_user{
    // Object that represents a connection to the user DB
        private $dbInstance;

        function __construct($dbInstance){ // Using Dependency Injection passing a Class_DB object rather than global variable.
            $this->dbInstance=$dbInstance;
        }
        function insertNewUser($user, $userPassword){ // INCOMPLETE
            $userDAO=new DAO_User($this->dbInstance);
            $insertedUser=$userDAO->createNewUser($user, $userPassword);
            $userPassword=""; // We clear the user's password from memory.
            if ($insertedUser){ // User was correctly inserted in db
                return true; // Should return the $user object.
            } else {
                return false;
            }
        }
    }
?>

Вот ключевой фрагмент из моей регистрации пользователя контроллера Controller_Register.php

<?php
    require_once("Controller.php");
    require_once("Model_User.php");
    require_once("General.php");

    class Controller_Register extends Controller {
        protected $page='UI_Register.php';
        function execute($view){
         // Several lines to make sure the form is filled adequately.
            While (!$userInserted){ // As long as the user isn't correctly inserted...
                $userName=$_POST["userName"];
                $userEmail=$_POST["userEmail"];
                $userPassword=$_POST["userPassword"];
                $_POST["userPassword"]=""; // We don't keep the pw in memory.
                $user=new user("", $userName, "", $userEmail); // User ID will be generated by the db, and the hashed pw has not been generated at this point.
                $userInserted=$userDBConnection->insertNewUser($user,$userPassword); // We insert the user name not knowing what the autoincremented user ID is.
                $userPassword=""; // We don't keep the pw in memory.
                }
            $_POST["password"]=""; // We clear the user's password from memory.
            if ($userInserted){// The value is true if the registration was succesful.
            $msg=new Message("Congratulations ".$_POST['userName']."! You are now registered."); 
            }
        }
    return $view;
    }
?>

Наконец, вот мой пользовательский код DAO, с ключевой пункт я хотел бы руководство по регистрации - DAO_User.php

<?php
    require_once('Class_User.php');
    require_once('Class_DB.php');
    require_once('General.php');

    class DAO_User {
        private $dbInstance; // This is an instance of Class_DB to be injected in the functions.

        function __construct($dbInstance){
            $this->dbInstance=$dbInstance; // Using Dependency Injection passing a Class_DB object rather than global variable.
        }

        function createNewUser($user, $userPassword){ // The $user object only has a userName and a userEmail at this point.
            $dbConnection=$this->dbInstance->createConnexion(); // This connection is local, so automatically closed after the function is completed.
            $inserted=false;
            while (!$inserted){ // This insert a new user, without any value for pw, and generates an autoincrement user ID on the db side.
                $query=$dbConnection->prepare("INSERT INTO users (userName, userEmail) VALUES (?,?)"); // userID is generated via autoincrement - therefore not known at time of insertion.
                $query->bindValue(1, $user->userName);
                $query->bindValue(2, $user->userEmail);
                $inserted=$query->execute(); //True if succesful, False if not.
            }
            $query=$dbConnection->prepare("SELECT LAST_INSERT_ID()"); // This allows us to retrieve the user ID as generated by the db.
            $userIDquery=$query->execute();
            $result=$userIDquery->fetch(PDO::FETCH_ASSOC); // returns an array indexed by column name as returned in result set - here column name is "userID" in the DB
            $userID=$result["userID"];
            $user->userID=$userID; // We modify the user ID of the $user object to be the autoincremented number generated by the db.
            $hashedPassword=stringHashing($userPassword,$user->userID);
            $userPassword="";
            $user->hashedPassword=hashedPassword;
            $hashedPWinserted=false;
            while (!$hashedPWinserted){ // This modifies the user table in db to add hashed PW.
                $query=$dbConnection->prepare("UPDATE users SET hashedPassword=? WHERE userID=?");
                $query->bindValue(1, $user->hashedPassword);
                $query->bindValue(2, $user->userID);
            }
            return $user;
        }
    }
?>

В General.php код содержит stringHashing функцию, которая получает строку и соли в качестве параметра и возвращает строку подсоленной. Я не уверен, где она должна жить в рамках MVC.

Мои пользователи таблица в MySQL таблица с 4 полями:
- идентификатор (типа int(10), не нуль, автоувеличение, ПК) - также используется как соль для хэширования ПВ
- имя пользователя (тип varchar(50), не нуль)
- hashedPassword (тип char(128), может быть null)
- userEmail (тип varchar(255), может быть null)

Несколько конкретных вопросов у меня, в основном, на createNewUser функции:
- Транзакции БД правильно и эффективно сделать?
- Я должен разделить некоторые функции вне этой функции?
- Я должен ограничить использование промежуточных переменных?
- Выполняет функцию достижения поставленных целей, я хочу это делать, т. е. вставить в БД нового пользователя с несколькими идентификатор пользователя, генерируемый в БД, а затем хешированный пароль?

Также интересует любая другая часть обратной связи, которую человек может иметь, особенно касаемо читабельности (например, мои комментарии слишком многословно и понятно) и понятность кода, а также лучшей практике предмет программирование (например, я предполагаю, что я должен изменить свою $пользователей объекта с легавой, а не $пользователь->имя пользователя=$имя пользователя;).

Обновление когда я запускаю этот код, я не получаю ошибки, но я также не получаю никаких записей в БД.



19485
2
задан 8 июня 2011 в 11:06 Источник Поделиться
Комментарии
2 ответа

В пользовательском классе : добавить сеттеры !

Вы не можете изменять значение за пределами класса (например: $пользователь->имя пользователя = $имя пользователя)

Попробуйте это : http://ideone.com/We2Lh

В конце Model_User.на PHP, замену

if ($insertedUser){ // User was correctly inserted in db
return true; // Should return the $user object.
} else {
return false;
}

По

return $insertedUser;

В ваш контроллер :

Снять пока (!$userInserted) {. Что appened если метод insertNewUser всегда терпят неудачу ? бесконечный цикл, что может быть, вы можете разбить ваш сервер.

Мой способ написания этого кода :

function execute($view) {

// check and sanitize values
$user = new user($userName, $userEmail); // Create a specific constructor. Empty values are ...
$userInserted=$userDBConnection->insertNewUser($user,$userPassword);

if ($userInserted) {
$msg = new Message("Congratulations ".$_POST['userName']."! You are now registered.");
} else {
$msg = new Message("Erreur during subscription. Please retry.");
}

// send $msg to the view
// ...
}

Если есть ошибка, это не стоит повторить сейчас. Ошибки не чудом выиграл исправить себя !

$_POST, где["пароль"]=""; : бесполезно, параметров будут сброшены при следующем запросе.

Ваше Дао - это очень сложно.

Удалить все время, и обрабатывать возможные ошибки (вы можете использовать boolean, исключения ...).

Вы можете использовать две собственные методы, чтобы создать и установить пароль.

В общем, твой код слишком много комментировал для меня.

Пример :

private $userName; // Must be unique.
=> Check this in your DB, a comment is useless

Не пишите очевидные комментарий :

if ($insertedUser){ // User was correctly inserted in db

Не пытайтесь объяснить, как или что, комментировать почему. "Как" и " что " можно понять, читая ваш код, но вы не можете понять цель фрагменты если это сложно.

Добавить уникальный индекс на имя пользователя.

Наконец, подумайте о газирования код ! Новые линии будут бесплатно ^^

2
ответ дан 9 августа 2011 в 08:08 Источник Поделиться

Слишком много кода для такой простой вещи...почему бы вам не рассмотреть возможность работы с фреймворков, таких как Codeigniter с?

Попробуйте установить какие-то отголоски на код и увидеть, где он останавливается. Это будет легче помочь вам.

0
ответ дан 9 июня 2011 в 07:06 Источник Поделиться