Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 用WHERE选择所有内容_Php_Mysql_Pdo - Fatal编程技术网

Php 用WHERE选择所有内容

Php 用WHERE选择所有内容,php,mysql,pdo,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['acce

我目前正在从事一个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子句来说明应该如何使用它。而且,使用*是不可能的

最好的选择是什么


谢谢大家!

我明白了吗:你想要一个
WHERE
-语句,这总是正确的

WHERE 1 = 1

我认为在变量中保留
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);
创建一个函数,如getProjects(),它将根据用户级别返回项目


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

这样的SQL如何:

$sql = 'SELECT project_name FROM projects WHERE user_id = ? OR 3 = ?';
$res = $db->prepare($sql);
$res->execute(array($id, $access_level);
当我在脚本的多个部分中这样做时,它变得一团糟

。如果您发现自己在重复代码块,这表明您应该将该公共代码重构为函数或方法

您还可以通过向查询中添加额外的信息而不是重写查询,并使用类似于
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']));
就我个人而言,我认为这比原来的要整洁一些,因为只适用于较低访问级别的部分都有明确的标记,并且是自包含的,而不是已经呈现的重复代码

另外,在访问级别中使用一个具有描述性名称的新变量可以防止重复神奇的数字,并为您提供一个单一的更改点


希望这能有所帮助。

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

每次遇到脚本的多个部分出现问题,结果变得一团糟时,您必须创建一个函数

事实上,您仍然在为页面上的每个查询编写所有这些丑陋的重复代码,包括prepare、execute、fetch、prepare、execute、fetch、prepare、execute、fetch。对你来说不是一团糟吗

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

一般用途一,只是为了从查询中提取一些值,而不重复无用的代码,使用方法如下:

$proj_names_arr = $db->getColumn("SELECT project_name FROM projects");
莱森提到的一个,基于第一个,是这样使用的

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

是的,差不多。但我仍然需要能够传递有用的数据,这样在这里就不起作用了。这看起来是迄今为止最简单的解决方案,谢谢。但我认为这不是一种好的编程技术。一种好的编程技术是创建一个工厂,根据您的访问级别返回不同的对象,然后使用不同的SQL语句生成结果。第二个最好的选择,如果你不介意在数据库上多加一点污点的话,那就是替换WHERE子句be user\u id LIKE?使用user_id或%作为参数。关于该函数:我没有正确解释它-它的代码不完全相同,因此函数getProjects()不起作用。关于getColumn():我已经在考虑编写一个简单的PDO包装器,但是我已经很久没有使用PDO了,我担心要正确地使用它是相当困难的。但我会尝试一些常见的功能,比如插入、检索一些记录等@Bv202那么,请正确解释一下。我看不出为什么getProjects()不能工作