1

我曾经以程序方式编写 php。因为我想了解更多关于 OOP 的信息,所以我决定为我的新项目以 OOP 方式编写 php。

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

之前,我是如何做到这一点的,在 login.php 中我将拥有以下代码:

登录.php

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

索引.php

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

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

登录.php

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

索引.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 不支持会话。

请指教

4

1 回答 1

1

快速解答

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

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

代码审查

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

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

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

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

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

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

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

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

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

$products = new Products();

在命名方面,我会说这Products不是描述对象集合的好选择。一个更好的名字,比如ProductListor ProductCollection

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

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

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

于 2013-09-09T06:20:01.703 回答