I've been using CodeIgniter for a while, and have a decent knowledge of MVC, PHP etc.
我使用CodeIgniter已经有一段时间了,并且对MVC、PHP等有相当的了解。
However, I'm finding it hard to adhere to the Fat Model Skinny Controller ethos.
然而,我发现很难坚持瘦型控制器的原则。
I've seen a lot about it; including what pseudo code to include in each file, but no actual examples. (Please link to some articles if I've missed any obvious ones!)
我看到了很多;包含要包含在每个文件中的伪代码,但是没有实际的示例。(如果我错过了一些明显的文章,请链接到一些文章!)
I'm finding it hard to move the form logic to a model. For instance, I am using a custom library for my auth system, which has it's own model. Should I then make a site user Model to log users in? Or should I just make a site Model to do that? Or a form Model?
我发现很难将表单逻辑移动到模型中。例如,我正在为我的auth系统使用一个自定义库,它有自己的模型。那么我是否应该创建一个站点用户模型来登录用户呢?或者我应该做一个网站模型来做这个吗?或一种形式模型?
To help me out, can anyone advise me on how to skinnify this Controller? I realise it's a lot of code, but simple pointers would be great. (Please note, I've only just written this code, so it hasn't been refactored much, but it should give a good example of how some of my methods are getting out of hand.)
为了帮助我,谁能给我建议如何去皮肤这个控制器?我意识到它有很多代码,但是简单的指针会很棒。(请注意,我只是编写了这段代码,所以它还没有被重构,但它应该给出一个很好的例子,说明我的一些方法是如何失控的。)
public function register()
{
session_start();
if ($this->tf_login->logged_in())
{
redirect('profile');
}
if ($_GET['oauth'] == 'true')
{
$type = $_GET['type'];
try
{
$token = $this->tf_login->oauth($type, '', 'email');
}
catch (TFLoginCSRFMismatchException $e)
{
$this->tf_assets->add_data('error_message', $e->getMessage());
}
catch (TFLoginOAuthErrorException $e)
{
$this->tf_assets->add_data('error_message', $e->getMessage());
}
if ($token)
{
$user_details = $this->tf_login->call('https://graph.facebook.com/me?fields=email,first_name,last_name,username&access_token=' . $token);
$user_details_decoded = json_decode($user_details);
if ($user_details_decoded->email)
{
try
{
$id = $this->tf_login->create_user($user_details_decoded->username,
md5($user_details_decoded->username . time()),
$user_details_decoded->email,
'',
TRUE,
TRUE);
}
catch (TFLoginUserExistsException $e)
{
try
{
if ($this->tf_login->oauth_login($type, $user_details_decoded->email, $token))
{
$this->session->set_flashdata('success_message', 'You have successfully logged in.');
redirect('profile');
}
else
{
$this->session->set_flashdata('error_message', 'An account with these details exists, but currently isn\'t synced with ' . $type . '. Please log in to sync the account.');
}
}
catch (Exception $e)
{
$this->session->set_flashdata('error_message', $e->getMessage());
}
}
catch (TFLoginUserNotCreated $e)
{
$this->tf_assets->add_data('error_message', 'You could not be registered, please try again.');
}
if ($id)
{
$this->tf_login->add_user_meta($id, 'first_name', $user_details_decoded->first_name);
$this->tf_login->add_user_meta($id, 'surname', $user_details_decoded->last_name);
$this->tf_login->sync_accounts($id, $type, $token);
$this->session->set_flashdata('success_message', 'Welcome ' . $this->input->post('first_name', TRUE) . ' ' . $this->input->post('surname', TRUE) . '. Your account has been sucessfully created. You will shortly receive an email with a verification link in.');
redirect('login');
}
}
else
{
$this->session->set_flash_data('error_message', 'You could not be logged in, please try again.');
}
}
// Redirect to clear URL
redirect(current_url());
}
if ($this->form_validation->run() !== FALSE)
{
try
{
$id = $this->tf_login->create_user($_POST['username'], $_POST['password'], $_POST['email'], '', FALSE);
}
catch (Exception $e)
{
$this->tf_assets->add_data('error_message', $e->getMessage());
}
if ($id)
{
$this->tf_login->add_user_meta($id, 'first_name', $_POST['first_name']);
$this->tf_login->add_user_meta($id, 'surname', $_POST['surname']);
if ($this->tf_login->register_verification_email())
{
$this->session->set_flashdata('success_message', 'Welcome ' . $this->input->post('first_name', TRUE) . ' ' . $this->input->post('surname', TRUE) . '. Your account has been sucessfully created. You will shortly receive an email with a verification link in.');
redirect('login');
}
else
{
$this->tf_login->login_user($id);
$this->session->set_flashdata('success_message','Your account has been sucessfully created.');
redirect('profile');
}
}
else
{
$this->tf_assets->add_data('error_message', $this->tf_login->get_errors());
}
}
if (validation_errors())
{
$this->tf_assets->add_data('error_message', validation_errors());
}
$this->tf_assets->set_content('public/register');
$this->tf_assets->add_data('page_title', "Register");
$this->tf_assets->render_layout();
}
Thanks in advance!
提前谢谢!
1 个解决方案
#1
3
From what I can tell, most or all of this code belongs in a controller or component, so I don't think your problem is Model/Controller confusion.
据我所知,大部分或全部代码都属于控制器或组件,所以我不认为您的问题是模型/控制器混淆。
The code is difficult to read, however, because of the deep nested structures and the failure to break out specific tasks into their own methods. The main refactoring you would benefit from here is creating new private methods to separate out the discrete subtasks that you are performing. This is has the additional important benefit of clarifying the high-level structure of your current method. So you would end up with something that looked like (just to give you a rough example):
但是,代码很难读懂,因为嵌套结构太深,而且无法将特定的任务分解为自己的方法。您将从中受益的主要重构是创建新的私有方法来分离您正在执行的离散子任务。这对澄清当前方法的高级结构有额外的重要好处。所以你会得到一个看起来像的东西(给你一个粗略的例子):
public function register()
{
session_start();
if ($this->tf_login->logged_in())
{
redirect('profile');
}
if ($_GET['oauth'] == 'true')
{
$this->oauthRegister();
}
$this->normalRegister();
}
Similarly, the oatuhRegister
method and normalRegister
methods would be broken down into smaller methods themselves, so that when you were completely finished each method would be adhering to the SRP and would probably be fewer than 10 lines of code. This will drastically improve the readability and maintainability of your code. I'd also recommend checking out Clean Code, which makes a strong argument for keeping your method short.
类似地,oatuhRegister方法和normalRegister方法本身会被分解为更小的方法,这样当你完成所有的工作时,每个方法都将遵循SRP,并且可能少于10行代码。这将极大地提高代码的可读性和可维护性。我还建议您检查干净的代码,这对于保持方法的简短来说是一个强有力的论据。
#1
3
From what I can tell, most or all of this code belongs in a controller or component, so I don't think your problem is Model/Controller confusion.
据我所知,大部分或全部代码都属于控制器或组件,所以我不认为您的问题是模型/控制器混淆。
The code is difficult to read, however, because of the deep nested structures and the failure to break out specific tasks into their own methods. The main refactoring you would benefit from here is creating new private methods to separate out the discrete subtasks that you are performing. This is has the additional important benefit of clarifying the high-level structure of your current method. So you would end up with something that looked like (just to give you a rough example):
但是,代码很难读懂,因为嵌套结构太深,而且无法将特定的任务分解为自己的方法。您将从中受益的主要重构是创建新的私有方法来分离您正在执行的离散子任务。这对澄清当前方法的高级结构有额外的重要好处。所以你会得到一个看起来像的东西(给你一个粗略的例子):
public function register()
{
session_start();
if ($this->tf_login->logged_in())
{
redirect('profile');
}
if ($_GET['oauth'] == 'true')
{
$this->oauthRegister();
}
$this->normalRegister();
}
Similarly, the oatuhRegister
method and normalRegister
methods would be broken down into smaller methods themselves, so that when you were completely finished each method would be adhering to the SRP and would probably be fewer than 10 lines of code. This will drastically improve the readability and maintainability of your code. I'd also recommend checking out Clean Code, which makes a strong argument for keeping your method short.
类似地,oatuhRegister方法和normalRegister方法本身会被分解为更小的方法,这样当你完成所有的工作时,每个方法都将遵循SRP,并且可能少于10行代码。这将极大地提高代码的可读性和可维护性。我还建议您检查干净的代码,这对于保持方法的简短来说是一个强有力的论据。