代码之家  ›  专栏  ›  技术社区  ›  BDuelz

PHP建议。(科哈纳经验优先)

  •  0
  • BDuelz  · 技术社区  · 16 年前

    我和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');
    }
    }
    

    用户模型中的注册函数

    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函数接受一个数组,但将该数组转换为一个验证对象,以便检索用户输入和错误。我看过一些关于科哈纳的教程,都是这样做的。

    2 回复  |  直到 16 年前
        1
  •  3
  •   wpjmurray    16 年前

    首先,我不会将register()方法放入用户模型中。模型应该是数据库中对象的表示,通常只包含“crud”方法(创建、检索、更新、删除)、getter和setter方法,以及一些与模型相关的静态助手方法。通过将register()方法放入模型中,您将使模型执行表示逻辑,这实际上应该由用户控制器执行,因为这是对用户操作的响应。控制器处理用户操作,验证这些用户操作,然后在验证成功时更新模型。

    在您的示例中,用户试图创建一个新帐户。他填写了一张表格,然后单击提交。表单的post操作应该指向控制器的方法,如/user/register,该方法将使用验证库来验证用户发送的表单数据。只有当该数据成功验证后,才能创建用户模型实例,将该模型的属性设置为用户输入的内容,然后使用模型的save()方法保存到数据库。如果验证失败,您将向用户报告错误,并且根本没有创建用户模型,因为您还没有有效的数据集来创建模型。

    接下来,您将检查用户是否已登录。同样,这应该在控制器中,而不是模型中。除此之外,如果用户已经登录,那么他就不能首先进入这个注册过程。创建用户注册表窗体视图的控制器方法应检查用户是否已登录,如果已登录,则应将其重定向到另一页。即使用户在耍花招并设法提交表单(可能他在旧窗口中打开表单时通过另一个窗口登录),您的注册方法也应该首先检查该表单,而不是创建$user验证对象。

    我可以在代码中看到,根据您的模型设置,有一些令人困惑的项。例如,您正在将$user数组传递到方法中,我假定该方法是表单数据。但是您使用的是“pass-by-reference”操作符(&),这在php5中是不必要的,因为现在所有对象都是通过引用传递的。但在这之后,您将重新将$user作为验证对象。您是否在其他地方使用$user验证对象并要求通过引用传递它?如果是这样,这是逻辑中的另一个缺陷,因为所有这些处理都需要在控制器中进行,并且可以直接在控制器中使用$_post值,而不必传递验证对象。

    稍后,您将使用parent::validate($user$save)验证用户信息。为什么对父级调用validate()方法作为静态方法?如果这是一个模型,那么它应该扩展Kohana的核心模型类,“parent”引用模型类。您的模型是否扩展了验证类?另外,为什么要将$user validation对象传递给validation()方法?如果需要执行递归(在对以前的过滤器进行更改后再次验证元素),则需要执行此操作,但看起来您没有执行任何需要递归的操作。您应该在$user validation对象上调用validate():

    $user->validate();
    

    没有任何争论。验证错误将成为$user对象的一部分,因此您可以使用

    $user->errors();
    

    最后,虽然Kohana允许您使用方法链接,但我不会使用一个长链来设置规则和其他验证项。这很混乱,可能会导致调试困难。将它们中的每一个放到自己的行中,并直接在$user对象上执行每一个。

        2
  •  1
  •   prodigitalson    16 年前

    我不知道Kohanna,所以我不确定他们的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();
    }
    
    推荐文章