PHP MVC对话框验证流程-如何在不丢失上下文的情况下从view´s表单转到控制器


PHP MVC dialog validation flow - how to go from view´s form to controller without loosing the context

我正在构建一个基于PHP MVC的应用程序。我过去曾使用过MVC,并且了解其概念,尽管PHP对我来说是新的东西。

我在这里遵循这个教程来构建我的项目,有一些变化来反映我的需要…

我正面临一个问题,关于我从form提交回我的原始控制器的方式,保留上下文。(我的低级PHP技能可以解释这个误解…)

让我们进入代码:

这是我的index.php(每个客户端调用的入口点):

if (isset($_GET['controller']) && isset($_GET['action']))
{
    $controller = $_GET['controller'];
    $action = $_GET['action'];
}
else 
{
    $controller = 'Root';
    $action = 'home';
}
require_once('/view/layout.php');

layout.php:

<!DOCTYPE html>
<html lang="en-us">

<?php require_once("library/view/header.php"); ?> // Load header
<body>
        <?php 
            require_once("library/controller/routes.php"); // Route controller/action
            require_once("library/view/footer.php"); // Load footer
        ?>
</body>
routes.php:(将路径路由到正确的控制器和动作)
    function call($controller, $action)
    {
        $filename = 'controller/class.' . $controller . 'Controller.php';
        if (!file_exists($filename))
        {
            $errorMsg = "ERROR: File not found: " . $filename . " for Controller:" . $controller . " and Action:" . $action;
            throw new Exception($errorMsg);
        }
        require_once ($filename);
        switch ($controller)
        {
            case 'Root':
                $controllerObj = new RootController();
                break;
        }
        $controllerObj->{ $action }();
    }
    call ($controller, $action);

class.RootController.php: - Root的控制器

public function home () 
{
    if (session_status() == PHP_SESSION_NONE)
        require_once('library/view/root/login.php');
    else
        require_once('library/view/root/home.php');
}
public function authenticate ($username, $password) 
{
    $username = trim($_POST["username"]);
    $password = trim($_POST["password"]);
    // Authenticate logic
    if ($auth == true)
    {
        ==> Go to a different controller/view.
    }
    else
    {
       $errorMsg = "Problems authenticating.";
       return $errorMsg;
     }
}
public function error($controller, $action, $errorMessage)
{
    echo "Error in " . $controller  . ' Action" . $action;
    echo $errorMessge;
}
最后是登录视图(login.php):
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
    <label>Username:</label> 
    <br> 
    <input type="text" name="username" value="<?php echo $username;?>"> <br> <br> <label>Password:</label>
    <br> 
    <input type="password" name="password"> 
    <br> <br> 
    <input type="submit" name="submit" value="Submit"> 
    <br> <br> 
    <span style="color: red"><?php echo $errorMsg;?>&nbsp</span>
</form>
我的问题是:

它的方式是,当我点击提交按钮,它重定向到索引页,但没有$controller$action上下文。因此,没有办法路由到RootController()上的authenticate功能;

所以,这是我的问题:

  1. 如何检查输入的数据,如果错误返回错误消息或如果成功更改Controller和Action ?

  2. 我需要通过index.php对每个数据验证吗?

  3. 是否可以在已经加载的RootController()中直接从form转到authenticate函数,在失败的情况下返回错误消息?

  4. 有没有更好的方法来做这个表单验证?

我很确定我遗漏了一些非常基本的东西,但我不知道什么是…

非常感谢帮助和评论。

首先,创建自己的MVC很棒,这是学习编码的好方法。我打算有一天自己滚。

回答这些问题

1)如何检查输入的数据,如果错误返回错误消息,如果成功更改Controller和Action ?

这是使用头来完成的,这是与您设置内容类型相同的头,例如ajax, html或您所拥有的,即响应头。这里重要的一点是,您不能在执行输出之后调用header location,任何输出,甚至是空白。

 header('Location: www.yoursite.com/success?m=you failed!');
 ext;

这里的退出是必要的,因为您正在重定向,但页面的脚本将继续运行,通常会带来不幸的后果。

2)我需要通过index.php的每一个数据验证吗?

这不是MVC框架的重点吗?它被称为前端控制器或入口点。

3)是否有可能直接从表单转到已经加载的RootController()中的身份验证函数,在失败的情况下返回错误消息?

使用AJAX您可以接近,但这是值得怀疑的,因为有用户输入需要发生,所以没有办法绕过发出另一个请求。对不起,这就是工作方式。

4)是否有更好的方法来做这个表单验证?

见第二条。你可以做一个登录弹出窗口,但这应该是一个标准的登录表单。

通常它的工作方式是你会有一个登录控制器

 www.yoursite.com/index.php/login  ( you can hide the index.php with mod rewrite )

然后在你的$_SERVER超全局变量中,你会发现请求uri或类似的东西,将包含uri (uri是想象的,而不是真实的页面)。这将通过index.php到路由器,再到控制器进行登录。显示页面。然后在控制器中有另一个方法submit login..等。它在提交表单时运行,然后在处理后使用header将它们定向到另一个虚拟资源。登录的方法是在某个路径上有一个检查,当你把他们送到登录页面时,存储他们想要的页面。

例如我想进入这个页面

 www.yoursite.com/index.php/members

但是我没有登录,所以我到这里

www.yoursite.com/index.php/login?r={www.yoursite.com/index.php/} // urlencode between the { }

然后,在成功的时候,不要给他们一个固定的信息,而是给他们想要的页面,或者某种仪表板。如果他们失败了,把他们带回去,或者最好是在登录页面上留下适当的信息。

我应该注意,通常路由器和uri是这样设置的,
 {domain}/index.php/{controller class}/{controller method}/ ...additional input.

对于可扩展性,你会想这样,

 www.yoursite.com/index.php/members/login

通过一些基本的mod重写,你可以得到这个

www.yoursite.com/members/login

使用请求的uri部分很重要,因为它就像一种额外的方式来保持上下文,而不使用$_POST或$_GET方法。

我在这里看到的一个问题是,当您还不知道需要什么样的输出时,您正在从前端控制器(index.php)调用layout.php。例如,应该重定向用户吗?用JSON响应AJAX请求?如果你已经发送了HTML,你就不能做这些了。

如果可以的话,看看PHP mini。这是一个在PHP中使用MVC的非常简单的框架,但它为您提供了一个坚实的基础,您可以在其上工作甚至改进。它甚至与您当前的实现有一些相似之处,但是有相当多的事情已经完成,您不必从头开始编写。

相关文章: