启动PHP类时是否必须检查登录会话?

时间:2013-09-06 18:42:39

标签: php oop session

我曾经以程序的方式编写php。由于我想了解更多有关OOP的知识,我决定以OOP方式为我的新项目编写php。

无论如何,假设我有一个需要用户登录的项目。这意味着在login.php中,一旦用户输入正确的用户名和密码,它将被重定向到index.php并开始加载产品表中的所有产品并在index.php中很好地显示它们。

之前,我是怎么做到的,在login.php中我会有以下代码:

的login.php

session_start();
...
if (loggedCorrect($user, $password)) {
     $_SESSION['loggedinuser'] = $user;
     //redirect to index.php
}

的index.php

session_start();
if (isset($_SESSION['loggedinuser']) {
      //select fields from products table and display them
      ...
}

所以在OOP中它会是这样的:

的login.php

session_start();
$user = new User($user, $password);
if ($user->hasCorrectLogin()) {
     $_SESSION['loggedinuser'] = $user->getUsername();
     //redirect to index.php
}

的index.php

session_start();
if (isset($_SESSION['loggedinuser']) {
     $products = new Products();
     //display all products
}

产品类

class Products {
    private $productArray;
    ...
    __construct() {
         //select all products from mySQL table then put every product in productArray
    }
...
}

我的问题是:

  1. 启动对象时(就像我的情况下的产品一样)。我必须检查登录会话吗?如果是的话,我应该在__contruct中进行吗?或者我应该在“类产品”行之前这样做?

  2. 我还有一个cronjob.php,每隔x分钟执行一次。当它正在执行时,它将创建一些像Products这样的对象并对它们进行分析。因此,如果需要登录会话检查,那么我不知道如何使其工作,因为cronjob不支持会话。

  3. 请告知

1 个答案:

答案 0 :(得分:1)

快速回答

  1. 没有。您的域对象本身不应该依赖于登录的会话;但是,他们可能需要一个User实例来执行某些职责,例如只显示特定用户能够看到的产品。

  2. 由于#1,现在这是微不足道的。

  3. 代码审核

    首先让我们考虑您的登录页面代码:

    $user = new User($user, $password);
    if ($user->hasCorrectLogin()) {
    

    在此代码中,似乎用户与数据库交互并且知道如何验证凭据。对于单个班级来说,这似乎有点太多了。

    它可以通过在对象中保留散列密码来执行密码验证,但是您只需要验证一次密码,因此实际上不需要保留该字段。不在此处完成此操作的另一个原因是,您需要考虑即时加强密码,这可能是随着硬件增长而扩展的网站策略(例如,当您使用bcrypt时)。

    绝对不应该进行数据库交互;要将数据库交互和密码验证与用户类分开,您可以考虑添加身份验证服务。

    try {
        $user = $authService->login($userName, $password);
        $_SESSION['loggedinuser'] = $user;
        // redirect to index.php
    } catch (InvalidLoginException $e) {
        // oops, username or password invalid
    }
    

    在身份验证服务中,您可以添加另一个抽象层来加载用户记录(例如,使用数据映射器)。

    您不仅可以在会话中存储用户名,还可以存储整个User对象。在某些情况下,这可能会导致不一致,但它可以节省到数据库的往返行程。

    现在,让我们观察产品概述页面:

    $products = new Products();
    

    就命名而言,我会说Products不适合描述对象集合。 ProductListProductCollection等名称更好。

    与上面的身份验证一样,不清楚Products类是如何填充的;它应该来自某个存储,所以让我们介绍一下将提供产品列表的存储库:

    $productRepository = new ProductRepository($db);
    $products = $productRepository->getAll();
    

    在最简单的场景中,使用数据库实例初始化存储库;必要时可以应用更多抽象级别。