我已经用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之后,您是否只需创建一个用于返回多个用户数组的“用户”类?
即
<?php
$getUsers = new Users('Tom');
// create 'Users' object where name is 'Tom'
print_r($users);
// prints the returned array of users?
?>
感谢您的帮助。希望这很清楚。
答案 0 :(得分:6)
我会这样做(使用另一个类):
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;
}
}
<强>增加:强> 以下示例提供了一个很好的想法,了解如何使类更易于测试,并且在将来需要时可以轻松修改:
UserRepositoryInterface
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
}
}
PDOUserRepository
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.
}
答案 1 :(得分:1)
我尝试将数据对象与数据库内容分开。在你的情况下,我会做出以下安排:
User
类的实例表示个人用户,无论是否在DB中。构造函数不会从DB中检索任何内容,只会填充类属性。
对于不在DB中的用户(例如,新创建的用户),userId
属性为NULL
(不是''
)。
执行DB填充的方法需要数据库接口(或至少一个对象)作为参数:
public function save(PDO $pdo){
}
有一些静态方法从DB中获取东西,其中类实例还没有意义;他们返回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);
答案 2 :(得分:0)
您可以使用方法来插入/检索用户,而不是使用构造来检索用户。
您可以创建插入新用户,更新特定用户,检索特定用户或检索用户对象数组中所有用户(有条件)等的方法