使用WHERE选择所有内容

时间:2011-04-07 08:33:41

标签: php mysql pdo

我目前正在开发一个存在多种访问权限的PHP项目。逻辑很简单:
- 当您的访问级别为2时,您只能看到自己项目的列表 - 当您的访问级别为3时,您可以看到所有项目

所以在SQL中:
第一个:

SELECT project_name FROM projects

第二个:

SELECT project_name FROM projects WHERE user_id = user_id

问题是我正在使用带有预处理语句的PDO,并且在脚本中多次执行此类查询。这就是它的样子:

if ($_SESSION['access_level'] == 3) {
    $sql = "SELECT project_name FROM projects";
  } else {
    $sql = "SELECT project_name FROM projects WHERE user_id = ?";
}

$res = $db->prepare($sql);

// Some more PHP 

if ($_SESSION['access_level'] == 3)
      $res->execute();
    else
      $res->execute(array($_SESSION['user_id']));

当我在脚本的多个部分中执行此操作时,它变得一团糟。有一个更好的方法吗?就个人而言,我在想一个WHERE子句,其中每个记录都被选中。这样就可以在脚本开始时实现:

if ($_SESSION['access_level'] == 3)
      $id = *;
    else
      $id = $_SESSION['user_id'];

现在查询更容易:

$res = $db->prepare("SELECT project_name FROM projects WHERE user_id = ?");
$res->execute(array($id));

(现在,当您的访问级别为3时,它将获取所有记录,但只有当您的级别为2时才会获得自己的记录)

这看起来像一个漂亮的转储解决方案,因为我并没有真正使用WHERE子句如何使用它。此外,使用*是不可能的。

最好的选择是什么?

谢谢!

7 个答案:

答案 0 :(得分:3)

您正在以完全错误的方式寻找解决方案。

每次你遇到你在脚本的多个部分做某事的情况,它变得一团糟,你必须创建一个功能

事实上,对于页面上的每个查询,您仍在编写所有这些丑陋的重复代码,包括准备,执行,获取,准备,执行,获取,准备,执行,获取。对你来说这不是一团糟吗?

因此,您必须创建两个函数。

通用目的,只是为了从查询中获取一些值而不重复无用的代码,就像这样使用它:

$proj_names_arr = $db->getColumn("SELECT project_name FROM projects");

和Raisen提到的一个,基于第一个,就像这样使用

$proj_names_arr = getProjects();

这将是您代码的唯一真正改进

至于功能,它并不难 一个粗略的例子:

function getColumn() {
  $args  = func_get_args();
  $query = array_shift($args);
  $res = $db->prepare($query);
  $res->execute($args);
  $data = array();
  while ($row = $res->fetch(PDO::FETCH_NUM)) {
    $data[] = $row[0];
  }
  return $data;
}

所以,它可以被称为

$proj_names = $db->getColumn("SELECT project_name FROM projects WHERE user_id = ?",
                             $_SESSION['user_id']);

答案 1 :(得分:2)

我认为将where子句保存在变量中以及绑定参数更容易,然后在运行时编写查询:

<?php

$sql = 'SELECT project_name FROM projects';
$where = array();
$parameters = array();


if ($_SESSION['access_level'] !== 3) {
    $where[] = 'user_id = ?';
    $parameters = array($_SESSION['user_id']);
}



if( !empty($where) ){
    $sql .= ' WHERE ' . implode(', ', $where);
}
$res = $db->prepare($sql);

$res->execute($parameters);

答案 2 :(得分:2)

那样的SQL怎么样:

$sql = 'SELECT project_name FROM projects WHERE user_id = ? OR 3 = ?';
$res = $db->prepare($sql);
$res->execute(array($id, $access_level);

答案 3 :(得分:1)

创建一个函数,例如 getProjects(),它将根据用户级别返回项目。

在函数内部使用Alvaro的代码并返回结果集。

答案 4 :(得分:0)

我明白了:您想要WHERE - 声明,这总是正确的吗?

WHERE 1 = 1

答案 5 :(得分:0)

  

正如我在脚本的多个部分中这样做,它变得一团糟。

Don't Repeat Yourself。如果您发现自己重复代码块,那就表明您应该将该公共代码重构为函数或方法。

您还可以通过在查询中附加额外信息而不是重写信息来删除一些较小的重复,并使用bindParam()之类的内容添加其他参数,而不是修改{{1}声明:

execute()

就我个人而言,我认为它比原版更加整洁,因为仅适用于较低访问级别的部分已经清楚地标记和自包含,而不是重复已经呈现的代码。

此外,使用具有访问级别描述性名称的新变量可以阻止您重复幻数,并为您提供单点更改。

希望有所帮助。

答案 6 :(得分:-1)

这是我的理解:你想先创建一个子句,然后,你可以在其他内容中使用这个子句,你可以这样做:

开始时:

if ($_SESSION['access_level'] == 3)
      $idClause = '1 = 1';
else
      $idClause = 'user_id = '.$_SESSION['user_id'];

现在,你可以在你想要的地方使用$ idClause,比如

$res = $db->prepare("SELECT project_name FROM projects WHERE ?");
$res->execute(array($idClause));

这与其他WHERE子句相似,比如

$res = $db->prepare("SELECT project_name FROM projects WHERE ? and project_group = 'group'");
$res->execute(array($idClause));

希望这对你有所帮助。

相关问题