使用 WHERE 选择所有内容

发布于 2024-10-30 22:33:27 字数 1229 浏览 0 评论 0原文

我目前正在开发一个存在多个访问权限的 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 子句应该如何使用它。另外,使用 * 是不可能的。

对此最好的选择是什么?

谢谢你!

I'm currently working on a PHP project where multiple access rights exists. The logic is simple:
- When your access level is 2, you can see a list of your own projects only
- When your access level is 3, you can see ALL projects

So in SQL:
First one:

SELECT project_name FROM projects

Second one:

SELECT project_name FROM projects WHERE user_id = user_id

The problem is that I'm using PDO with prepared statements and such queries are executed multiple times across the script. This is how it looks like:

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']));

As I'm doing this in multiple parts of the script, it becomes a mess. Is there a better way to do this? Personally I was thinking of a WHERE-clause where every record is selected. That way this would be possible at the start of the script:

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

Now querying is much easier:

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

(Now it will get all records when your access level is 3, but only your own when you're only level 2)

This looks like a pretty dump solution imo as I'm not really usng the WHERE clause how it should be used. Also, using * is just not possible.

What's the best option for this?

Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

携余温的黄昏 2024-11-06 22:33:27

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

每当您遇到在脚本的多个部分执行某些操作并且变得一团糟的情况时,您都必须创建一个函数

事实上,您仍然在为页面上的每个查询编写所有这些丑陋的重复代码,包括准备、执行、获取、准备、执行、获取、准备、执行、获取。你不觉得这看起来很混乱吗?

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

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

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

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

$proj_names_arr = getProjects();

它将是唯一的真实< /strong> 改进你的代码

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

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']);

You are looking for the solution in completely wrong way.

Every time you face a situation where you doing somethin in multiple parts of the script, and it become a mess, You have to create a function.

In fact, you are still writing all this ugly repeated code with prepare, execute, fetch, prepare, execute, fetch, prepare, execute, fetch - for the every query on the page. Doesn't it looks like a mess for you?

So, you have to create two functions.

general purpose one, just to fetch some value out of query without repeating useless code, to use it like this:

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

and one mentioned by Raisen, based on the first one, to be used like this

$proj_names_arr = getProjects();

It will be the only real improvement of your code

As for the function, it's not that hard
a rough example:

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;
}

so, it can be called

$proj_names = $db->getColumn("SELECT project_name FROM projects WHERE user_id = ?",
                             $_SESSION['user_id']);
太阳男子 2024-11-06 22:33:27

我认为将 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);

I think it's easier to keep the where clauses in a variable, as well as the bind parameters, and then compose the query when running it:

<?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);
〗斷ホ乔殘χμё〖 2024-11-06 22:33:27

那么像这样的 SQL 呢:

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

What about an SQL like that:

$sql = 'SELECT project_name FROM projects WHERE user_id = ? OR 3 = ?';
$res = $db->prepare($sql);
$res->execute(array($id, $access_level);
枕花眠 2024-11-06 22:33:27

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

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

Create a function such as getProjects() where it will return the projects according to the user level.

Use Alvaro's code for example inside the function and return the resultset.

無心 2024-11-06 22:33:27

我是否明白:您想要一个 WHERE 语句,这总是正确的?

WHERE 1 = 1

Did I understand: You want a WHERE-Statement, thats always true?

WHERE 1 = 1
幼儿园老大 2024-11-06 22:33:27

由于我在脚本的多个部分中执行此操作,因此变得一团糟。

不要重复。如果您发现自己重复代码块,则表明您应该将该通用代码重构为函数或方法。

您还可以通过向查询附加额外信息而不是重写查询来消除一些较小的重复,并使用诸如 bindParam() 之类的内容来添加附加参数,而不是修改您的 execute() 语句:就

$userOnly = ($_SESSION['access_level'] == 2);

$sql = "SELECT project_name FROM projects";

if ($userOnly) {
    $sql .= " WHERE user_id = ?";
}

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

if ($userOnly) {
 $res=>bindParam(bindParam(1, $_SESSION['user_id'], PDO::PARAM_INT);
}

$res->execute(array($_SESSION['user_id']));

我个人而言,我认为这比原来的更简洁,因为仅适用于较低访问级别的部分被明确标记并且是独立的,而不是重复已经呈现的代码。

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

希望有帮助。

As I'm doing this in multiple parts of the script, it becomes a mess.

Don't Repeat Yourself. If you find yourself repeating blocks of code, that's a sign that you should be refactoring that common code into a function or method.

You can also get rid of some of the more minor repetitions by appending extra information to your query rather than rewriting it, and using something like bindParam() to add the additional parameter, rather than modifying your execute() statement:

$userOnly = ($_SESSION['access_level'] == 2);

$sql = "SELECT project_name FROM projects";

if ($userOnly) {
    $sql .= " WHERE user_id = ?";
}

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

if ($userOnly) {
 $res=>bindParam(bindParam(1, $_SESSION['user_id'], PDO::PARAM_INT);
}

$res->execute(array($_SESSION['user_id']));

Personally, I think that's a bit neater than the original, since the parts that only apply to the lower access level are clearly marked and self-contained, not repeating code already presented.

Also, using a new variable with a descriptive name for the access level stops you from repeating magic numbers, and gives you a single point of change.

Hope that helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文