【发布时间】:2019-01-14 12:01:45
【问题描述】:
我正在尝试使用 Slim3 框架和 Twig 模板系统在 php 中创建一个身份验证系统,而对于数据库,我正在使用带有 PDO 的 MySQL。我也在尝试使用模型视图控制器设计模式来实现它。但是,我很难理解如何将 MVC 结构用于 Web 应用程序。我在网上看了很多解释,似乎没有一个明确的答案。很多人说要使用 php 框架,例如 Laravel、Symfony 或 CodeIgniter,因为他们显然采用了类似 MVC 的结构。不过,我宁愿保持简单,手动编写代码,而不是使用框架。
目前我看到了两种对 MVC 的解释。此图中描绘的第一个:
我看到的另一种解释是这样的:(取自this YouTube video)
我已经完成了我的研究。 this 和 this 等问题和答案很有帮助。但我仍然不确定如何构建自己的应用程序,特别是识别和理解 MVC 的模型方面。我现在将解释我的身份验证应用程序的注册过程。所以你知道我的代码是如何工作的。
首先,我有一个 SQLQueries 类,它只是将一系列 SQL 语句放入函数中。然后我有一个 SQLWrapper 类,它具有例如可以在数据库中存储新用户详细信息的功能。此类还调用 SQLQueries 类中的函数。我还有一个 ValidateSanitize 类,它具有清理用户输入以及检查用户输入在表单中是否有效的功能。我认为这三个类是 MVC 模型方面的一部分,但我不确定。我看到很多使用“用户模型类”的其他教程,但我在我的应用程序中找不到需要一个。
我的视图只是显示 html 的 Twig 模板,例如主页、注册、登录等。然后我有控制器。我打算让多个控制器做不同的事情。目前我只实现了负责注册和登录用户的 AuthController。
所以 AuthController 所做的第一件事就是在一个名为 getRegisterForm 的函数中显示注册表单。一旦用户提交了表单,postRegisterForm 函数就会接受用户输入并将其分配给受污染的变量。
public function postRegisterForm($request, $response)
{
$arr_tainted_params = $request->getParsedBody();
$tainted_email = $arr_tainted_params['email']; it a variable
$tainted_username = $arr_tainted_params['username'];
$tainted_password = $arr_tainted_params['password'];
$tainted_password_confirm = $arr_tainted_params['password_confirm'];
接下来所有三个前面的类以及数据库详细信息都被实例化,因此它们的功能可以在 AuthController 中使用:
$sanitizer_validator = $this->container->ValidateSanitize;
$sql_wrapper = $this->container->SQLWrapper;
$sql_queries = $this->container->SQLQueries;
$db_handle = $this->container->get('dbase');
然后使用 sanitize_input 函数清除受污染的用户详细信息。然后将清理后的用户详细信息输入验证函数,以确保它们不会触发任何验证违规。密码也在这里散列:
$cleaned_email = $sanitizer_validator->sanitize_input($tainted_email, FILTER_SANITIZE_EMAIL);
$cleaned_username = $sanitizer_validator->sanitize_input($tainted_username, FILTER_SANITIZE_STRING);
$cleaned_password = $sanitizer_validator->sanitize_input($tainted_password, FILTER_SANITIZE_STRING);
$cleaned_password_confirm = $sanitizer_validator->sanitize_input($tainted_password_confirm, FILTER_SANITIZE_STRING);
$hashed_cleaned_password = password_hash($cleaned_password, PASSWORD_DEFAULT);
$sanitizer_validator->check_email_exists($cleaned_email);
$sanitizer_validator->validate_email($cleaned_email);
$sanitizer_validator->validate_username($cleaned_username);
$sanitizer_validator->validate_password($cleaned_password);
$sanitizer_validator→validate_password_confirm($cleaned_password_confirm);
最后有一个 if 语句检查所有验证错误消息是否为空。如果是,我们为 SQLWrapper 类提供数据库详细信息以及 SQLQueries 类对象。然后,我们通过调用 SQLWrapper 类的 store-details 函数将用户详细信息插入数据库。最后我们将用户引导到登录页面,这样用户就可以登录到他们新注册的帐户。
if ($sanitizer_validator->get_validate_messages('email_error') == ' ' && $sanitizer_validator->get_validate_messages('username_error') == ' '
&& $sanitizer_validator->get_validate_messages('password_error') == ' ' && $sanitizer_validator->check_passwords_match($cleaned_password, $cleaned_password_confirm ) == true
&& $sanitizer_validator->check_email_exists($cleaned_email) == false)
{
$sql_wrapper->set_db_handle($db_handle);
$sql_wrapper->set_sql_queries($sql_queries);
$sql_wrapper->store_details($cleaned_email, $cleaned_username, $hashed_cleaned_password);
return $response→withRedirect($this→container→router→pathFor('login'));
}
但是,如果任何验证错误消息不是空白的,那么我们调用 SanitiseValidate display_validate_messages,它只是将消息设置为要在注册枝模板上显示的会话。然后我们重定向回注册页面,以便用户可以看到验证错误消息。
else
{
$sanitizer_validator->display_validate_messages();
return $response->withRedirect($this->container->router->pathFor('register'));
}
}
所以基于用户注册帐户的这种结构。这是否遵循干净简单的 MVC 结构或是否需要进行一些更改?我的任何课程都扮演了模特的角色吗?任何有关我的结构的建议和提示将不胜感激。
full application can be seen on my GitHub 如果有帮助的话。请注意,此版本比我在此问题中使用的示例代码稍旧。
【问题讨论】:
-
我认为您在这里错过了@tereško 回答的重点:stackoverflow.com/questions/5863870/…。仔细阅读并特别注意“什么是模型”部分。您的控制器中到处都有域逻辑,更糟糕的是,您在整个过程中都充满了 SQL/映射逻辑。此外,Model 文件夹中的文件本身就是类,但它们并没有最好地遵守 OOP 原则
-
@jeremy 这就是我不知道我的应用程序应该去哪里的问题。尽管阅读了那个答案,但我仍然不明白这就是我要问的原因。你说我到处都有领域逻辑。我不知道那是什么意思。一个告诉我如何正确构建它的答案是我所追求的。而且它不是重复的。
-
@jeremy 我也不确定你所说的模型文件夹是什么意思。你是说 src 文件夹吗?
-
我说的是那个文件夹,抱歉。
标签: php model-view-controller design-patterns model slim-3