dtdfj08626 2015-06-30 08:37 采纳率: 0%
浏览 27

MVC服务层内的限制

I have recently dived into OOP & PHP MVC Application Design. At the moment I am learning a lot but I have one thing that is currently bugging me.

I read and now understand why it isn't wise to place http redirects within a service layer. We do not know what the controller will need to do once the service is complete, etc. etc. I also read that the service should not do anything outside of its purpose. Example: User Registration should only create a new user, using input passed by controller, but I am wondering if it is also fine to set flash messages within the service layer.

My application displays a lot of flash messages session based notifications for users. All of them are based on service related input validation checks, and produce alerts similar to the following

The username xxxxxx is already in use

Usernames Should be > 5 Characters

Should/can this be defined/set within the service class or is there something wrong with that? I have a Alert Helper function that handles setting the alerts. I can easily use my dependency injector to make it available I am just wondering if there is an issue with doing that.

I made the mistake of implementing all redirects within the services and I just finished removing all of them and placing them in the controllers, I don't want to make the same time consuming mistake so I am looking for advice here.

Thank you in advance for the help.

EDIT - CODE EXAMPLE

<?php

/**
 *-----------------------------------------------------------------
 * 
 *  LOGIN CONTROLLER
 * 
 */
namespace Controller\www;
use \Helper\Controller;

class Login extends Controller {
    public $dependencies = ['arena', 'login', 'site'];

    /**
     *  Login
     * 
     *  Login Runs Through Various Checks Including If User is Banned, Account is Locked, 
     *  or Forgot Password Request Is Active. Then the Entered Password is Matched & if Valid
     *  User is Logged In
     */
    public function index() {

        // Define Default
        $username = '';                                                                     


        /** 
         *  User Login
         * 
         *  If      Successful, Login User, Redirect Home
         *  Else    Set Error Alerts 
         */
        if ($this->form->post('login')) { 

            // Define and Sanitize Post Data
            $username = $this->input->get('username');
            $password = $this->input->get('password');


            // Login Service Layer
            $login = $this->factory->make('user/login');

            // If Successful Redirect Home - Else Set Errors
            if ($login->user($username, $password) === true) {
                $this->redirect->home();
            }
            $this->alert->error($login->get('errors'));
        }


        /**
         *  Define Site Title & Display Page
         */
        $this->view->sitetitle('login');
        $this->view->display('www/login', [
            'video'     => $this->arena->video(),
            'username'  => $this->input->set($username)
        ], ['notifications' => 'user/forgotpassword']);
    }
}

Service Layer

/**
 *-----------------------------------------------------------------
 * 
 *  USER LOGIN SERVICE LAYER
 * 
 */
namespace Service\User;
use \Helper\Service;

class Login extends Service {
    public $dependencies = ['login', 'mail', 'time', 'user', 'vars'];

    /**
     *  Handles Entire Login Process For Site Users
     *  
     *  @params all         User Submitted Form Data
     */
    public function user($username = '', $password = '') {

        // Validate $_POST Form Data
        $this->validateInput($username, $password);


        /**
         *  No Errors Produced - Complete Form Submission
         * 
         *  We Are Not Using `elseif` Between Forgot Password & Normal Login
         *  After a Forgot Password Code is Generated User May Remember Old Passwords
         *  We Need to Ensure Users Can Still Login Using Account Password As Well
         */
        if (!$this->errors()) {


            /** 
             *  User Input Password Matches Account Password
             */
            if ($this->input->verifyhash($password, $this->user->get('info.password'))) {
                $this->login->user();
                return true;                                                                    
            }


            /** 
             *  If We Have Not Been Redirected Login Was Unsuccessful
             */
            $message = $forgotPW ? 'Forgot Password Code Invalid - Login Lost Incorrect' : 'Login Unsuccessful - Incorrect Username or Password';
            $this->log->error($message, ['Username' => $username, 'Password' => $password]);

            $this->error('Incorrect Username or Password');
        }

        /** 
         *  If We Have Made It This Far Login Was Unsuccessful - Log Unsuccessful Attempt
         */
        $this->login->logAttempt();


        return false;
    }


    /**
     *  Validate $_POST Data
     * 
     *  @params all         User Submitted Form Data
     */
    private function validateInput($username = '', $password = '') {

        // Display Error if Username is Empty 
        if (!$username) {                                                                                           
            $this->error('Please enter a username');                                        
        }
        // Display Error if Password is Empty
        elseif (!$password) {                                                                                       
            $this->error('Please enter a password');                                        
        } 
        // Search DB For User With Matching Username - If User Not Found Display/Log Error, Else Set User
        else {
            $user = $this->user->info($username, 'username', '', '`userid`');
            if (!$user) {
                $this->error('The username ' . $username . ' does not exist'); 
                $this->log->error('User Not Found When Attempting to Login', ['username' => $username]);   
            } else {
                $this->user->set('user', $user['userid']);
            } 
        }
    }
}
  • 写回答

2条回答 默认 最新

  • duandu2159 2015-06-30 08:55
    关注

    In order to answer your question, I think it's best to break down the concept of MVC into a very basic form, and its individual parts. I apologise in advance if this comes across as being somewhat condescending.

    View
    The view of the application displays anything and everything. If something is going to be displayed, it should be done in this layer

    Controller
    The controller is a mediator between the view and the model. It takes input from the view, applies logic/rules to it (where required), and interacts with the model to then get data to pass back to the view.

    Model
    This is where the loading and saving of data are done. The majority of the validation should have been done as part of the rules in the controller, and this should only pass details of any errors during loading or saving back to the controller should the arise. If there are no errors, it should return the relevant data, or a success status back to the controller.

    With those points in mind, the model should not set flash messages to the session, that should be done within the controller depending on the result from the model.

    评论

报告相同问题?

悬赏问题

  • ¥20 simulink单相桥式整流电路
  • ¥35 问问51单片机流水灯的代码该怎么写
  • ¥15 关于#百度#的问题:感觉已经将字体段落、字体、页边距、纸张大小、文档网络调成与论文模板一致,为什么黄色部分字体左右的间距还是不一样啊,求私信发文件接收看一下
  • ¥15 stata webuse报错
  • ¥15 TypeError: Cannot read properties of undefined (reading 'status')
  • ¥15 如何利用AI去除图片中的竹架子
  • ¥15 python 写个基金爬取的代码,自动卖出功能
  • ¥15 Linux系统启动不起来
  • ¥15 为什么运行仿真数码管不亮(语言-c语言)
  • ¥15 陈仁良《直升机飞行动力学》小扰动线化方程如何推导