2

我已经用 PHP 编程很多年了,但是直到最近才开始使用类进行编程。我有以下 - 基本 - 用户类如下:

<?php
/* The class for constructing any user's information
 */

    class User {

        protected $userId, $email, $userGroup;

        protected function getEmail() {
            return $this->email;
        }

        protected function getUserId() {
            return $this->userId;
        }

        protected function getUserGroup() {
            return $this->userId;
        }


        public function __construct($userId='') {
            if($userId) {
                $select = mysql_query("SELECT userId, email, user_group FROM user WHERE userId = '$userId'");
                while($user==mysql_fetch_array($select)) {
                $this->email = $user[email];
                    $this->userId = $userId;
                    $this->userGroup = $user[user_group];
                }
            }
        }

}?>

所以我知道我可以执行以下操作

<?php
$user = new User($userId);
echo $user->getEmail();
?>

显示给定 userId 的用户电子邮件地址。我想知道的是,什么是最好的方式——使用 OOP——来显示,比如说,40 个用户的电子邮件。显然创建 40 个用户对象会很愚蠢,因为那是 40 个 SQL 查询。在给定各种参数执行 SQL 之后,您是否会简单地创建一个用于返回多个用户数组的“用户”类?

IE

<?php
$getUsers = new Users('Tom');
// create 'Users' object where name is 'Tom'
print_r($users);
// prints the returned array of users?
?>

谢谢你的帮助。希望这很清楚。

4

3 回答 3

7

我会这样做(使用另一个类):

class UserRepository {
    public function getByName($name) {
        $result = mysql_query("SELECT userId, email, user_group FROM user WHERE name = '$name'");

        $users = [];

        while ($row = mysql_fetch_assoc($result)) {
            $user = new User;
            $user->email     = $row['email'];
            $user->userId    = $row['userId'];
            $user->userGroup = $row['user_group'];

            $users[] = $user;
        }

        return $users;
    }
}

补充: 下面的例子很好地说明了如何使这些类在未来需要时更可测试和更容易修改:

用户存储库接口

interface UserRepositoryInterface {
    public function getByName($name);
    public function getByUserId($id);
}

MySqliUserRepository

class MySqliUserRepository implements UserRepositoryInterface {
    public function getByName($name) {
        // Get by name using mysqli methods here
    }

    public function getByUserId($id) {
        // Get by user id using mysqli methods here
    }
}

PDO用户存储库

class PDOUserRepository implements UserRepositoryInterface {
    public function getByName($name) {
        // Get by name using PDO methods here
    }

    public function getByUserId($id) {
        // Get by user id using PDO methods here
    }
}

用法

class Foo {

    protected $userRepository;

    public function __construct(UserRepositoryInterface $userRepository) {
        $this->userRepository = $userRepository;
    }

    public function bar() {
        $user = $this->userRepository->getByUserId(10);
    }
}

关于使用mysql_

它可能不完全是你如何做到的,但它会给你一个想法。也mysql_已贬值,因此最好使用mysqli_PDO(我的个人建议)。PDO对 OOP 也更加友好。

PDO: http: //php.net/manual/en/book.pdo.php

mysqli_: http: //php.net/manual/en/book.mysqli.php

更新:

您的个人用户类别将仅包含与用户相关的信息。用户类不应该包含任何检索用户的方法,这是存储库的工作。因此,如果您想检索 1 个用户,而不是User __construct像当前那样在 中进行操作,请向 中添加一个UserRepository看起来像这样的方法:

public function getByUserId($id) {
    // Select user from db, check only 1 exists, make user object, return.
}
于 2013-10-14T10:59:53.840 回答
1

我尝试将我的数据对象与数据库内容分开。在你的情况下,我会做出以下安排:

  • 该类的一个实例User代表一个单独的用户,无论是否在 DB 中。构造函数不会从 DB 中检索任何内容,它只是填充类属性。

  • 对于不在 DB 中的用户(例如,新创建的用户),该userId属性为NULL(not '')。

  • 执行数据库操作的方法需要一个数据库接口(或至少一个对象)作为参数:

    public function save(PDO $pdo){
    }
    
  • 有一些静态方法可以从数据库中获取类实例还没有意义的东西;它们返回一个User实例或一个User集合:

    public static function fetchById(PDO $pdo, $id){
    }
    
    public static function fetchAll(PDO $pdo){
    }
    
  • 如果有意义,我会编写一个私有方法来共享公共代码:

    private static function fetch(PDO $pdo, array $filter=array()){
        $sql = 'SELECT id, email, group
             FROM user' . PHP_EOL;
        $params = array();
    
       if( isset($filter['id']) ){
           $sql .= 'WHERE id=:id';
           $params['id'] = $filter['id'];
       }
    
       //...
    }
    
    public static function fetchById(PDO $pdo, $id){
        $data = self::fetch($pdo, array('id' => $id));
        if( empty($data) ){
            return NULL;
        }else{
            reset($data);
            return curren($data);
        }
    }
    
    public static function fetchAll(PDO $pdo){
        return self::fetch($pdo);
    }
    
  • 我提到的User集合User可以像实例数组一样简单,也可以像您自己的泛型实现一样复杂。

这样,典型的脚本如下所示:

// Fetch my details
$me = User::fetchById(1);

// Create a new user
$you = new User(NULL, 'Joe', 'Guests');
$you->save($pdo);
$message = sprintf('User created with ID=%d', $you->userId);
于 2013-10-14T11:43:57.520 回答
0

您可以使用方法来插入/检索用户,而不是使用构造来检索用户。

您可以创建方法来插入新用户、更新特定用户、检索特定用户或检索用户对象数组中的所有(带条件)等

于 2013-10-14T11:00:45.050 回答