Пожалуйста, посоветуйте PHP.(Опыт Коханы - плюс)

StackOverflow https://stackoverflow.com/questions/2231505

  •  19-09-2019
  •  | 
  •  

Вопрос

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

В любом случае, я только начал использовать фреймворк (Kohana), и на самом деле существует не так уж много руководств, поэтому я не совсем уверен, правильно ли я все делаю.

У меня есть несколько фрагментов кода, которые я хотел бы опубликовать, чтобы получить некоторую обратную связь, относящуюся к тому, что я только что сказал.

Для начала

Пользовательский Контроллер

class User_Controller extends Template_Controller{

    public function register()
{
    // logged in users cant register
    if($this->logged_in)
    {
        url::redirect('user/profile');
    }

    // initially show an empty form
    $form = $errors = array
    (
        'username'      => '',
        'email'         => '',
        'password'      => '',
        'gender'        => '',
        'dob_month'     => '',
        'dob_day'       => '',
        'dob_year'      => '',
        'date_of_birth' => '',
        'captcha'       => '',
        'registration'  => ''
    );

    // check for a form submission
    if($this->input->post('register'))
    {
        // get the form
        $post = $this->input->post();

        // prepare the data for validation
        $post['date_of_birth'] = "{$post['dob_year']}-{$post['dob_month']}-{$post['dob_day']}";

        // create a new user
        $user = ORM::factory('user');

        // validate and register the user. 
        if($user->register($post, TRUE))
        {
            // SEND EMAIL

            // login using the collected data
            if(Auth::instance()->login($post->username, $post->password, TRUE))
            {
                // redirect the user to the profile page
                //url::redirect("user/profile/{$user->id}");
            }
        }

        // get validation errors and repopulate the form
        $form   = arr::overwrite($form,   $post->as_array());
        $errors = arr::overwrite($errors, $post->errors('registration_errors'));
    }

    // template variables
    $this->template->title = 'Sign Up';
    $this->template->body  = new View('layout_1');

    // layout variables
    $this->template->body->left  = new View('user/registration_form');
    $this->template->body->right = 'Right Side Content';

    // registration form variables
    $this->template->body->left->form    = $form;
    $this->template->body->left->errors  = $errors;
    $this->template->body->left->captcha = new Captcha('register');
}
}

Зарегистрировать функцию в User_Model

class User_Model extends ORM{

    public function register(array& $user, $save = FALSE)
{
    $user = new Validation($user);

    // logged in users cant register
    if(Auth::instance()->logged_in())
    {
        $user->add_error('registration', 'logged_in');
        return FALSE;
    }

    // trim everything
    $user->pre_filter('trim')

        // everything is required
        ->add_rules('*', 'required')

        // username must be 5 - 30 alphanumeric characters and available
        ->add_rules('username', 'length[5,30]', 'valid::alpha_numeric', array($this, 'username_available'))

        // email must be valid format and available
        ->add_rules('email', 'valid::email', array($this, 'email_available'))

        // password must be 5 - 15 characters and alpha dash
        ->add_rules('password', 'length[5,15]', 'valid::alpha_dash')

        // gender must be either male or female. capitalize first letter
        ->add_rules('gender', array($this, 'valid_gender'))
        ->post_filter('ucfirst', 'gender')

        // dob must be a valid date, and user must be old enough.
        ->add_callbacks('date_of_birth', array($this, 'check_dob'))

        // captcha must be entered correctly.
        ->add_rules('captcha', 'Captcha::valid');

    // add the registration date
    $this->registration_date = date::unix2mysql();  // helper function transforms the current unix to mysql datetime format

    // validate the information. an ORM function.
    $result = parent::validate($user, $save);

    // was the user info valid?
    if($result === TRUE)
    {
        // was the user saved?
        if($save === TRUE)
        {
            // add a login role
            $this->add(ORM::factory('role', 'login'));
            $this->save();
        }
    }
    else
    {
        $user->add_error('registration', 'failed');
    }

    return $result;
}
}

В основном все мои модели придерживаются одного и того же формата при проверке информации.

У меня есть еще кое-что, по чему я был бы признателен за обратную связь, но я не хочу никого перегружать.

Большое спасибо за ваше время

Редактировать: Извините, я должен был опубликовать и пользовательский контроллер, и модель.Я много читал о том, что модели должны быть толстыми, а контроллеры - худыми.Вот почему я создал функцию register в модели для проверки информации вместо того, чтобы делать это внутри контроллера.Функция register принимает массив, но превращает этот массив в объект проверки, чтобы я мог получить пользовательский ввод и ошибки.Я видел несколько руководств по Kohana, где это было сделано таким образом.

Это было полезно?

Решение

Во-первых, я бы не стал помещать метод register() в пользовательскую модель.Модель должна быть представлением объекта в базе данных и обычно содержать только ваши методы "CRUD" (create, retrieve, update, delete), методы getter и setter и, возможно, некоторые статические вспомогательные методы, связанные с моделью.Помещая свой метод register() в модель, вы заставляете модель выполнять логику представления, которая на самом деле должна выполняться пользовательским контроллером, поскольку это является ответом на действие пользователя.Контроллер обрабатывает действия пользователя, проверяет эти действия пользователя, затем обновляет модель, если проверка прошла успешно.

В вашем примере пользователь пытается создать новую учетную запись.Он заполняет форму и нажимает кнопку отправить.Действие POST формы должно указывать на метод контроллера, например /user/register , и этот метод будет использовать библиотеку проверки для проверки данных формы, отправленных пользователем.Только в случае успешной проверки этих данных следует создать экземпляр пользовательской модели, присвоить свойствам этой модели значение, указанное пользователем, а затем использовать метод save() модели для сохранения в базе данных.Если проверка завершается неудачей, вы сообщаете об ошибке пользователю и вообще не создаете пользовательскую модель, поскольку у вас еще нет допустимого набора данных для создания модели.

Далее вы проверяете, вошел ли пользователь в систему.Опять же, это должно быть в контроллере, а не в модели.Кроме того, пользователь не должен иметь возможности перейти к этому процессу регистрации в первую очередь, если он уже вошел в систему.Метод контроллера, который создает представление формы регистрации пользователя, должен проверять, вошел ли пользователь в систему, и если да, то его следует перенаправить на другую страницу.Даже если пользователь хитрит и ему удается отправить форму (возможно, он вошел в систему через другое окно, когда форма была открыта в старом окне), ваш метод register должен сначала проверить это и пока не создавать объект проверки $ user.

Я вижу в вашем коде, что есть некоторые сбивающие с толку элементы, основанные на настройке вашей модели.Например, вы передаете массив $user в метод, который, я полагаю, является данными формы.Но вы используете оператор "передавать по ссылке" (&), который не нужен в PHP5, поскольку все объекты теперь передаются по ссылке.Но после этого вы переделываете $user в качестве объекта проверки.Используете ли вы объект проверки $user в другом месте и требуете, чтобы он передавался по ссылке?Если это так, то это еще один недостаток в логике, поскольку вся эта обработка должна выполняться в контроллере, а значения $ _POST могут использоваться непосредственно в контроллере вместо того, чтобы передавать объект проверки.

Позже вы проверяете информацию о пользователе с помощью parent::validate($user, $save).Почему метод validate() вызывается в parent как статический метод?Если это модель, она должна расширять базовый класс модели Kohana, а "родительский" ссылается на класс модели.Расширяет ли ваша модель класс проверки?Кроме того, почему вы передаете объект проверки $user методу validation()?Выполнение этого требуется, если вам нужно выполнить рекурсию (для повторной проверки элементов после внесения изменений из предыдущих фильтров), но, похоже, вы ничего не делаете, чтобы потребовать рекурсии.Вы должны вызывать validate() для объекта проверки $user:

$user->validate();

без всяких аргументов.Ошибки проверки станут частью объекта $user, поэтому вы можете проверить наличие ошибок с помощью

$user->errors();

Наконец, хотя Kohana позволяет вам использовать цепочку методов, я бы не стал использовать одну длинную цепочку для настройки правил и других элементов для проверки.Это сбивает с толку и может затруднить отладку.Поместите каждый из них в отдельную строку и выполните каждый непосредственно над объектом $user .

Другие советы

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

Обычно я мог бы сделать что-то вроде следующего псевдокода:

// in my controller class for User or whatever

public function registerAction()
{
   // get the form data from the request if its POST, ortherwise a blank array
   $userData = $this->getRequest('user', array(), 'POST');

   // create a user
   $user = new User($userData);

   if(Auth::instance()->logged_in())
   {
      // we are logged in add an error to the user object for use by the view
      $user->getValidator()->add_error('registration', 'logged_in');
   }
   elseif($user->is_valid())
   {
     // user data is valid, set the view with the success message
     $user->save();
     $this->setView('register_success');
   }

   /**
    * render the designated view, by default this would be the one containing the
    * registration form which displays errors if they exist - however if we success-
    * fully registered then the view with the success message we set above will be
    * displayed.
    */
   $this->render();
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top