我最近开始阅读课程和功能,以便为我所参与的在线游戏社区创建用户系统。我目前有三个表格可以向我提供用户数据: 部门 , 排名 和 用户
用户 表格如下:
user_id | user_name | char_name | email | password | rank_id
排名 表格如下:
rank_id | rank_name | div_id
分部 表格如下:
div_id | div_name
将有大约100个排名,每个排名都在特定部门。例如,等级1-5是分区1,等级6-10是分区2,依此类推。
旧法规如下
我创建了一个 用户 类,其中的函数可以获取我需要的数据,但我觉得我做错了,因为有很多SELECT语句正在使用,我在测试页面上调用所有三个函数来获取数据。
我的 用户 类如下:
require_once('dbcon.php');
class User {
public static function all_users() {
global $conn;
$records = $conn->prepare('SELECT * FROM users');
$records->execute();
$results = $records->fetchAll(PDO::FETCH_ASSOC);
return $results;
}
public static function by_id($userid=0) {
global $conn;
$records = $conn->prepare('SELECT * FROM users WHERE user_id = :userid');
$records->bindParam(':userid', $userid);
$records->execute();
$results = $records->fetch(PDO::FETCH_ASSOC);
return $results;
}
public static function get_rank($userid=0) {
global $conn;
$records = $conn->prepare('SELECT * FROM users WHERE user_id = :userid');
$records->bindParam(':userid', $userid);
$records->execute();
$results = $records->fetch(PDO::FETCH_ASSOC);
$rankid = $results['rank_id'];
$records2 = $conn->prepare('SELECT * FROM ranks WHERE rank_id=:rankid');
$records2->bindParam(':rankid', $rankid);
$records2->execute();
$results2 = $records2->fetch(PDO::FETCH_ASSOC);
return $results2['rank_name'];
}
public static function get_div($userid=0) {
global $conn;
$records = $conn->prepare('SELECT * FROM users WHERE user_id = :userid');
$records->bindParam(':userid', $userid);
$records->execute();
$results = $records->fetch(PDO::FETCH_ASSOC);
$rankid = $results['rank_id'];
$records2 = $conn->prepare('SELECT * FROM ranks WHERE rank_id=:rankid');
$records2->bindParam(':rankid', $rankid);
$records2->execute();
$results2 = $records2->fetch(PDO::FETCH_ASSOC);
$divid = $results2['div_id'];
$records3 = $conn->prepare('SELECT * FROM divisions WHERE div_id = :divid');
$records3->bindParam(':divid', $divid);
$records3->execute();
$results3 = $records3->fetch(PDO::FETCH_ASSOC);
return $results3['div_name'];
}
}
我的测试页面是:
require_once('inc/dbcon.php');
require_once('inc/user.php');
echo "<strong>ALL USERS</strong><br><br>";
$users = User::all_users();
foreach ($users as $user) {
$rank = User::get_rank($user['user_id']);
$div = User::get_div($user['user_id']);
echo "User Name: " . $user['user_name'] . ".<br>";
echo "Character Name: " . $user['char_name'] . ".<br>";
echo "Rank: " . $rank . ".<br>";
echo "Division: " . $div . ".<br>";
echo "<br><br>";
}
echo "<strong>USER 1</strong><br><br>";
$singleuser = User::by_id(1);
$rank = User::get_rank($singleuser['user_id']);
$div = User::get_div($singleuser['user_id']);
echo "User Name: " . $singleuser['user_name'] . ".<br>";
echo "Character Name: " . $singleuser['char_name'] . ".<br>";
echo "Rank: " . $rank . ".<br>";
echo "Division: " . $div . ".<br>";
我怎样才能改善这个?
有没有办法在JOIN语句中执行get_rank和get_div,可能是在all_users和by_id中,这会阻止多个语句?
上面的旧代码
编辑1
我研究了为什么使用全局变量是坏的,所以我将根据我读到的内容设置函数来使用构造函数。
有没有人对如何通过将get_rank和get_div加入all_users和by_id来进一步压缩它有任何想法?
编辑2
在研究为什么全局变量不好用之后,我改变了一些事情。我设法将所有SELECT语句组合成一个合适的INNER JOIN。
CONFIG.PHP
include 'db.class.php';
include 'user.class.php';
define("DB_HOST", "127.0.0.1");
define("DB_USER", "root");
define("DB_PASS", "");
define("DB_NAME", "agency");
$database = new Database();
$user = new User();
DB.CLASS.PHP
class Database {
private $host = DB_HOST;
private $user = DB_USER;
private $pass = DB_PASS;
private $dbname = DB_NAME;
private $dbh, $error, $stmt;
public function __construct(){
$dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;
$options = array(
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
try {
$this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
} catch (PDOException $e) {
$this->error = $e->getMessage();
}
}
public function query($query){
$this->stmt = $this->dbh->prepare($query);
}
public function bind($param, $value, $type = null){
if (is_null($type)) {
switch (true) {
case is_int($value):
$type = PDO::PARAM_INT;
break;
case is_bool($value):
$type = PDO::PARAM_BOOL;
break;
case is_null($value):
$type = PDO::PARAM_NULL;
break;
default:
$type = PDO::PARAM_STR;
}
}
$this->stmt->bindValue($param, $value, $type);
}
public function execute(){
return $this->stmt->execute();
}
public function resultset(){
$this->execute();
return $this->stmt->fetchAll(PDO::FETCH_ASSOC);
}
}
USER.CLASS.PHP
class User extends Database {
public function test3($id){
$this->query('SELECT * FROM users INNER JOIN ranks ON users.rank_id = ranks.rank_id INNER JOIN divisions ON ranks.div_id=divisions.div_id WHERE users.user_id=:id');
$this->bind(':id', $id);
$rows = $this->resultset();
return $rows;
}
}
我在测试文件中测试了上述内容。
test.php的
include 'assets/config/config.php';
foreach($user->test3(1) as $row){
echo $row['user_name'] . " has a rank of: " . $row['rank_name'] . ". This rank has an ID of: " . $row['rank_id'] . ".";
echo "<br>";
echo $row['user_name'] . " is in division: " . $row['div_name'] . ". This division has an ID of: " . $row['div_id'] . ".";
}
新问题
表格和示例数据
CREATE TABLE `divisions` (
`div_id` int(11) NOT NULL,
`div_name` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `divisions` (`div_id`, `div_name`) VALUES
(1, 'Div 1 Name'),
(2, 'Div 2 Name'),
(3, 'Div 3 Name');
CREATE TABLE `ranks` (
`rank_id` int(11) NOT NULL,
`rank_name` varchar(255) NOT NULL,
`div_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `ranks` (`rank_id`, `rank_name`, `div_id`) VALUES
(1, 'Rank 1 Div 1', 1),
(2, 'Rank 2 Div 1', 1),
(3, 'Rank 3 Div 1', 1),
(4, 'Rank 4 Div 1', 1),
(5, 'Rank 5 Div 1', 1),
(6, 'Rank 6 Div 2', 2),
(7, 'Rank 7 Div 2', 2),
(8, 'Rank 8 Div 2', 2),
(9, 'Rank 9 Div 2', 2),
(10, 'Rank 10 Div 2', 2),
(11, 'Rank 11 Div 3', 3),
(12, 'Rank 12 Div 3', 3);
CREATE TABLE `users` (
`user_id` int(11) NOT NULL,
`user_name` varchar(255) NOT NULL,
`char_name` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`rank_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `users` (`user_id`, `user_name`, `char_name`, `email`, `password`, `rank_id`) VALUES
(1, 'UserA', 'CharA', 'EmailA', 'PassA', 2),
(2, 'UserB', 'CharB', 'EmailB', 'PassB', 10);
ALTER TABLE `divisions`
ADD PRIMARY KEY (`div_id`);
ALTER TABLE `ranks`
ADD PRIMARY KEY (`rank_id`);
ALTER TABLE `users`
ADD PRIMARY KEY (`user_id`);
ALTER TABLE `users`
MODIFY `user_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;
根据其中一条评论的要求,以下是表格和一些示例数据。同样,一切都按预期工作。我只是想回答问题1和2,看看这个设置是否正确。这是有限的测试数据。大约有100个排名,将有大约100个用户。
根据用户的排名ID,他们将拥有相应的排名,并且位于相应的部门。