Php PDO 返回相关 table 数据
Php PDO returning related table data
我正在绞尽脑汁思考如何让我的用户在访问主页时登录(有效)的场景,他们会看到从我的网站中提取的 'categories' 列表cat_list table 但他们只看到 'categories' 他们与之关联。例如,user1 可以访问 cat1,user2 可以访问 cat2,user3 可以访问 cat1 和 cat2 - 我需要一种方法来存储这些 cat 值并允许用户查看它们。所以 cat1 的 id 可以是 1 而 cat 2 的 id 可以是 2 但我不确定这如何转化为使用 SQL 命令获取数据。
这是我目前显示类别的方式。
<?php
try{
// Selecting entire row from doc_list table
$results = $dbh->query("SELECT * FROM cat_list ORDER BY cat_title ASC ");
}catch(Exception $e) {
echo $e->getMessage();
die();
}
$docs = $results->fetchAll(PDO::FETCH_ASSOC);
foreach($docs as $docs){
echo '
<a href="catView.php?cat_id='.$docs["cat_id"].'">
<div class="indexBox">
<div class="indexBoxHeader"><i class="fa fa-phone" style="font-size: 2em;"></i></div>
<div class="indexBoxFooter">
<p>
'.$docs["cat_title"].'
</p>
</div>
</div>
</a>';}
?>
我的 table 是这样组成的:
CREATE TABLE `cat_list` (
`cat_id` int(11) NOT NULL,
`cat_title` varchar(32) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf16 AUTO_INCREMENT=5 ;
CREATE TABLE `user_login` (
`id` int(11) NOT NULL,
`username` text NOT NULL,
`firstname` varchar(30) NOT NULL,
`lastname` varchar(50) NOT NULL,
`password` varchar(64) NOT NULL,
`psalt` text NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=12 ;
我真的很难理解或找出 link 它们的最佳方式并指定谁能看到什么?我已经研究了 JOINS 以及 tables 与外键之间的关系,甚至研究了一个单独的新 table al 在一起(规范化) - 但是从我上面我需要得到传递的用户 $_SESSION id从登录然后获取该值并检查他们可以看到哪些类别。
更新
<?
session_start();
if(isset($_SESSION['user'])){
header("Location:home.php");
exit;
}
$dbh=new PDO('mysql:dbname=dashboardr;host=******', '******', '******');
$email=$_POST['username'];
$password=$_POST['pass'];
if(isset($_POST) && $email!='' && $password!=''){
$sql=$dbh->prepare("SELECT * FROM user_login WHERE username=?");
$sql->execute(array($email));
while($r=$sql->fetch()){
$p=$r['password'];
$p_salt=$r['psalt'];
$id=$r['id'];
}
$site_salt="subinsblogsalt";
$salted_hash = hash('sha256',$password.$site_salt.$p_salt);
if($p==$salted_hash){
$_SESSION['user']=$id;
$_SESSION['username']=$email;
$_SESSION['firstname']=$firstname;
header("Location:home.php");
}else{
echo "<h2>Username/Password is Incorrect.</h2>";
}
}
?>
** 更新 2**
这是需要查看类别的 home.php 文件:
<?php include 'header.php'; ?>
<?php
if(isset($_SESSION['user'])){ $_SESSION['user']=$id;
$results = $dbh->query("SELECT * FROM cat_list JOIN user_cats ON cat_id = cat_id WHERE user_id = ? ORDER BY cat_title ASC");
?>
根据您的需求描述,用户和类别具有一对多关系(一个用户可以访问多个类别)- 但是用户实际上 "own" 类别(多个用户可能有访问同一个类别),所以你必须有一个中间table来定义两者之间的关系。
这就是你所缺少的!
table应该是这样的(我的mySQL有点生疏,如果有语法错误请见谅):
CREATE TABLE `user_cats` (
`user_id` int(11) NOT NULL,
`cat_id` int(11) NOT NULL,
);
如何填充这取决于您!请注意,给定用户的 cat_ids 不应重复,否则您将在列表中获得重复的类别。
您的结果查询应该如下所示:
$sql=$dbh->prepare(("SELECT A.* FROM cat_list A JOIN user_cats B ON A.cat_id = B.cat_id WHERE B.user_id = ? ORDER BY A.cat_title ASC");
$sql->execute(array($id));
其中 $id 是您从成功登录中获得的 user_id。
对更新 2 的响应
抱歉,我的 mySQL 和 PHP 有点生疏了,我复制并粘贴了您上面的代码中的一些内容,您说它可以正常工作。
首先,我查询中的 "A" 和 "B" 是 table 别名 - 它们只是使查询更易于阅读,因此您可以写 "A.column_name" 而不是 "my_long_table_name.column_name"。有一个可选的“[AS]”,为了清楚起见,我可能应该包括它,但我习惯于省略它。
有关 mySQL 中别名的一些信息,请参见此处:http://www.techonthenet.com/mysql/alias.php
"$id" 是您的登录代码中的变量,但当然它只存在于该页面。您已经将其存储在会话变量中,因此您只需要从 home.php 中的会话中检索它。您似乎有点倒退,并且正在将一个不存在的变量分配回会话。
我会让 home.php 看起来更像这样:
<?php
include('header.php');
if(isset($_SESSION['user'])){
try {
/* Note: I would put stuff like this in a common include for all your pages that need DB access */
$dbh=new PDO('mysql:dbname=dashboardr;host=******', '******', '******');
$sql=$dbh->prepare(("SELECT A.* FROM cat_list AS A JOIN user_cats AS B ON A.cat_id = B.cat_id WHERE B.user_id = ? ORDER BY A.cat_title ASC");
$sql->execute(array($_SESSION['user']));
} catch(Exception $e) {
echo $e->getMessage();
die();
}
$docs = $sql->fetchAll(PDO::FETCH_ASSOC);
foreach($docs as $doc_item) {
echo '
<a href="catView.php?cat_id='.$doc_item["cat_id"].'">
<div class="indexBox">
<div class="indexBoxHeader"><i class="fa fa-phone" style="font-size: 2em;"></i></div>
<div class="indexBoxFooter">
<p>
'.$doc_item["cat_title"].'
</p>
</div>
</div>
</a>';
}
}
?>
请注意,我已将 foreach 循环中的迭代器变量更改为“$doc_item”,因为使用与数组相同的变量对我来说是个错误!
我正在绞尽脑汁思考如何让我的用户在访问主页时登录(有效)的场景,他们会看到从我的网站中提取的 'categories' 列表cat_list table 但他们只看到 'categories' 他们与之关联。例如,user1 可以访问 cat1,user2 可以访问 cat2,user3 可以访问 cat1 和 cat2 - 我需要一种方法来存储这些 cat 值并允许用户查看它们。所以 cat1 的 id 可以是 1 而 cat 2 的 id 可以是 2 但我不确定这如何转化为使用 SQL 命令获取数据。
这是我目前显示类别的方式。
<?php
try{
// Selecting entire row from doc_list table
$results = $dbh->query("SELECT * FROM cat_list ORDER BY cat_title ASC ");
}catch(Exception $e) {
echo $e->getMessage();
die();
}
$docs = $results->fetchAll(PDO::FETCH_ASSOC);
foreach($docs as $docs){
echo '
<a href="catView.php?cat_id='.$docs["cat_id"].'">
<div class="indexBox">
<div class="indexBoxHeader"><i class="fa fa-phone" style="font-size: 2em;"></i></div>
<div class="indexBoxFooter">
<p>
'.$docs["cat_title"].'
</p>
</div>
</div>
</a>';}
?>
我的 table 是这样组成的:
CREATE TABLE `cat_list` (
`cat_id` int(11) NOT NULL,
`cat_title` varchar(32) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf16 AUTO_INCREMENT=5 ;
CREATE TABLE `user_login` (
`id` int(11) NOT NULL,
`username` text NOT NULL,
`firstname` varchar(30) NOT NULL,
`lastname` varchar(50) NOT NULL,
`password` varchar(64) NOT NULL,
`psalt` text NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=12 ;
我真的很难理解或找出 link 它们的最佳方式并指定谁能看到什么?我已经研究了 JOINS 以及 tables 与外键之间的关系,甚至研究了一个单独的新 table al 在一起(规范化) - 但是从我上面我需要得到传递的用户 $_SESSION id从登录然后获取该值并检查他们可以看到哪些类别。
更新
<?
session_start();
if(isset($_SESSION['user'])){
header("Location:home.php");
exit;
}
$dbh=new PDO('mysql:dbname=dashboardr;host=******', '******', '******');
$email=$_POST['username'];
$password=$_POST['pass'];
if(isset($_POST) && $email!='' && $password!=''){
$sql=$dbh->prepare("SELECT * FROM user_login WHERE username=?");
$sql->execute(array($email));
while($r=$sql->fetch()){
$p=$r['password'];
$p_salt=$r['psalt'];
$id=$r['id'];
}
$site_salt="subinsblogsalt";
$salted_hash = hash('sha256',$password.$site_salt.$p_salt);
if($p==$salted_hash){
$_SESSION['user']=$id;
$_SESSION['username']=$email;
$_SESSION['firstname']=$firstname;
header("Location:home.php");
}else{
echo "<h2>Username/Password is Incorrect.</h2>";
}
}
?>
** 更新 2**
这是需要查看类别的 home.php 文件:
<?php include 'header.php'; ?>
<?php
if(isset($_SESSION['user'])){ $_SESSION['user']=$id;
$results = $dbh->query("SELECT * FROM cat_list JOIN user_cats ON cat_id = cat_id WHERE user_id = ? ORDER BY cat_title ASC");
?>
根据您的需求描述,用户和类别具有一对多关系(一个用户可以访问多个类别)- 但是用户实际上 "own" 类别(多个用户可能有访问同一个类别),所以你必须有一个中间table来定义两者之间的关系。
这就是你所缺少的!
table应该是这样的(我的mySQL有点生疏,如果有语法错误请见谅):
CREATE TABLE `user_cats` (
`user_id` int(11) NOT NULL,
`cat_id` int(11) NOT NULL,
);
如何填充这取决于您!请注意,给定用户的 cat_ids 不应重复,否则您将在列表中获得重复的类别。
您的结果查询应该如下所示:
$sql=$dbh->prepare(("SELECT A.* FROM cat_list A JOIN user_cats B ON A.cat_id = B.cat_id WHERE B.user_id = ? ORDER BY A.cat_title ASC");
$sql->execute(array($id));
其中 $id 是您从成功登录中获得的 user_id。
对更新 2 的响应
抱歉,我的 mySQL 和 PHP 有点生疏了,我复制并粘贴了您上面的代码中的一些内容,您说它可以正常工作。
首先,我查询中的 "A" 和 "B" 是 table 别名 - 它们只是使查询更易于阅读,因此您可以写 "A.column_name" 而不是 "my_long_table_name.column_name"。有一个可选的“[AS]”,为了清楚起见,我可能应该包括它,但我习惯于省略它。 有关 mySQL 中别名的一些信息,请参见此处:http://www.techonthenet.com/mysql/alias.php
"$id" 是您的登录代码中的变量,但当然它只存在于该页面。您已经将其存储在会话变量中,因此您只需要从 home.php 中的会话中检索它。您似乎有点倒退,并且正在将一个不存在的变量分配回会话。
我会让 home.php 看起来更像这样:
<?php
include('header.php');
if(isset($_SESSION['user'])){
try {
/* Note: I would put stuff like this in a common include for all your pages that need DB access */
$dbh=new PDO('mysql:dbname=dashboardr;host=******', '******', '******');
$sql=$dbh->prepare(("SELECT A.* FROM cat_list AS A JOIN user_cats AS B ON A.cat_id = B.cat_id WHERE B.user_id = ? ORDER BY A.cat_title ASC");
$sql->execute(array($_SESSION['user']));
} catch(Exception $e) {
echo $e->getMessage();
die();
}
$docs = $sql->fetchAll(PDO::FETCH_ASSOC);
foreach($docs as $doc_item) {
echo '
<a href="catView.php?cat_id='.$doc_item["cat_id"].'">
<div class="indexBox">
<div class="indexBoxHeader"><i class="fa fa-phone" style="font-size: 2em;"></i></div>
<div class="indexBoxFooter">
<p>
'.$doc_item["cat_title"].'
</p>
</div>
</div>
</a>';
}
}
?>
请注意,我已将 foreach 循环中的迭代器变量更改为“$doc_item”,因为使用与数组相同的变量对我来说是个错误!