MySQL不喜欢使用php和pdo绑定处理多个字段

MySQL不喜欢使用php和pdo绑定处理多个字段,php,mysql,class,pdo,sql-like,Php,Mysql,Class,Pdo,Sql Like,我的WHERE-LIKE声明有点问题。理想情况下,我希望能够搜索多个术语(或仅搜索1个或另一个)。现在,出于测试目的,我在我的测试表单中分离了它,在这里我选择我正在运行的函数的类型 目的: 请暂时忽略更新功能(我确信它和其他功能一样混乱,但我还没有完成)。仍在尝试完成dFind()函数。这个测试的目的是,我可以构建一个数据类,它将创建一个类,将数据插入数据库,搜索数据库中的数据,并提取数据,更新数据。到目前为止,每一步对我来说都是一条学习的曲线,所以请耐心等待 关于dFind(): 下面,如果我

我的WHERE-LIKE声明有点问题。理想情况下,我希望能够搜索多个术语(或仅搜索1个或另一个)。现在,出于测试目的,我在我的测试表单中分离了它,在这里我选择我正在运行的函数的类型

目的: 请暂时忽略更新功能(我确信它和其他功能一样混乱,但我还没有完成)。仍在尝试完成dFind()函数。这个测试的目的是,我可以构建一个数据类,它将创建一个类,将数据插入数据库,搜索数据库中的数据,并提取数据,更新数据。到目前为止,每一步对我来说都是一条学习的曲线,所以请耐心等待

关于dFind(): 下面,如果我在dFind()函数中将查询限制为1个类似的实例,它就可以工作了(名称是2个实例中更重要的一个,但我需要在工作后搜索其他字段)。如果我在查询中添加'orphone-LIKE:phone',那么它就不会提取正确的数据(我得到了所有信息)。我在phpmyadmin中测试了我的查询,但它工作得很好,所以我不确定这是我处理查询本身的方式,还是我没有用php捕捉到一些东西(我还尝试添加“并转义它,但这也没有帮助)

你们知道我在这件事上错在哪里吗?提前谢谢。此外,任何实现我正在研究的功能的建议或方向都是非常受欢迎的。这些方法将并入一个小型数据库,用于建立、搜索和更新消费者

INDEX.PHP

<\?php

    require 'incl/con.php';
    require 'incl/class.php';

?>

<!DOCTYPE html>
<html>
<head><title>Test 1 Million</title>



</head>
<body>
<h3>Pull data using classes</h3>

<form method="POST" action="index.php">

    <table border="0">
        <tr>
            <td>ID (Required for update):</td><td><input type="text" name="id" maxlength="4"></td>
        </tr>
        <tr>
            <td>Name:</td><td><input type="text" name="name"></td>
        </tr>
        <tr>
            <td>phone:</td><td><input type="text" name="phone"></td>
        </tr>
        <tr>
            <td>Insert<input type="radio" name="type" value="insert" checked="checked">Find<input type="radio" name="type" value="find">Update<input type="radio" name="type" value="update"></td><td><input type="submit" value="Submit"></td>
        </tr>
    </table>

</form>

<?

if ($_SERVER['REQUEST_METHOD'] == "POST") {

    $type = $_POST['type'];
    $name = $_POST['name'];
    $phone = $_POST['phone'];
    $id = $_POST['id'];

    $newData = new Data($name, $phone);

    if ($type == 'insert') {

        $newData->dInsert();

    } elseif ($type == 'find') {

        $newData->dFind();

    } elseif ($type == 'update') {
        if ($id != null && $name != null) {
            $newData->dUpdate($id,$name,$phone);
        } else {
            echo 'Please enter, at minimum, the id and name fields.';
            return false;
        }        
    }

} else {
    echo 'Please enter data in both fields and choose the correct option.';
}

?>


</body>
</html>
<\?php

# VARs
# set the current timezone (host is MST)
date_default_timezone_set("America/New_York");

#$host = "MY_HOST";
#$db = "MY_DB";
#$user = "MY_UN";
#$pw = "MY_PW";
<\?php

class Data {

    private $dsn = "DSN STRING";
    private $user = "MY_UN"; // I know this was already declared - was trying it within the class to see how it works, which does ok.
    private $pw = "MY_PW"; // I know this was already declared - was trying it within the class to see how it works, which does ok.
    private $opts = array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION );

    public $name;
    public $phone;

    public function __construct($n,$p) {
        $this->name = $n;
        $this->phone = $p;
    }

    public function dInsert() {                
        try {            
            $DBH = new PDO($this->dsn, $this->user, $this->pw, $this->opts);

            $STH = $DBH->prepare("INSERT INTO directory (name, phone) VALUES (:name, :phone)");

            $STH->bindParam(':name', $this->name);
            $STH->bindParam(':phone', $this->phone);

            $STH->execute();            
        } catch(PDOException $e) {            
            echo "I'm sorry, Dave. I'm afraid I can't do that.<br />";
            echo date("d/m/y : H:i:s", time()) . " - " . $e->getMessage();
            file_put_contents('PDOErrors.txt', date("d/m/y : H:i:s", time()) . " - " . $e->getMessage() . "\n", FILE_APPEND);
            $DBH = null;            
        }        
        $DBH = null;        
    }

    public function dFind() {                
        try {        
            $DBH = new PDO($this->dsn, $this->user, $this->pw, $this->opts);

            # $STH = $DBH->prepare('SELECT id, name, phone FROM directory WHERE name LIKE :name OR phone LIKE :phone');
            # $STH = $DBH->prepare("SELECT * from directory WHERE name LIKE CONCAT('%', :name ,'%') OR phone LIKE CONCAT('%', :phone ,'%')");
            $STH = $DBH->prepare("SELECT * from directory WHERE name LIKE :name OR phone LIKE :phone");

            $STH->bindValue(':name', '%' . $this->name . '%');
            $STH->bindValue(':phone', '%' . $this->phone . '%');

            $STH->execute();

            $STH->setFetchMode(PDO::FETCH_ASSOC);

            while($row = $STH->fetch()) {
                echo $row['id'] . " " . $row['name'] . ": " . $row['phone'] . "<br />";
            }            
        } catch(PDOException $e) {            
            echo "I'm sorry, Dave. I'm afraid I can't do that.<br />";
            echo date("d/m/y : H:i:s", time()) . " - " . $e->getMessage();
            file_put_contents('PDOErrors.txt', date("d/m/y : H:i:s", time()) . " - " . $e->getMessage() . "\n", FILE_APPEND);
            $DBH = null;            
        }        
        $DBH = null;        
    }

    public function dUpdate($id,$name,$phone) {

        $this->name = $name;
        $this->phone = $phone;

        try {        
            $DBH = new PDO($this->dsn, $this->user, $this->pw, $this->opts);

            $STH = $DBH->prepare('UPDATE directory SET name = :name, phone = :phone WHERE id = :id');

            $STH->bindValue(':id', $id);
            $STH->bindValue(':name', '%' . $name . '%');
            $STH->bindValue(':phone', '%' . $phone . '%');

            $STH->execute();

            $STH->setFetchMode(PDO::FETCH_ASSOC);

            while($row = $STH->fetch()) {
                echo $row['id'] . " " . $row['name'] . ": " . $row['phone'] . "<br />";
            }            
        } catch(PDOException $e) {            
            echo "I'm sorry, Dave. I'm afraid I can't do that.<br />";
            echo date("d/m/y : H:i:s", time()) . " - " . $e->getMessage();
            file_put_contents('PDOErrors.txt', date("d/m/y : H:i:s", time()) . " - " . $e->getMessage() . "\n", FILE_APPEND);
            $DBH = null;            
        }        
        $DBH = null;

    }

}
将dFind()中的绑定数据替换为以下内容,它似乎正在工作:

    $STH->bindValue(':name', '%' . $this->name . '%');
    $STH->bindValue(':phone', '%' . $this->phone . '%');

    $STH->bindValue(':name_provided', empty($this->name) ? 0 : 1);
    $STH->bindValue(':phone_provided', empty($this->phone) ? 0 : 1);

问题可能是运行查询时,
$this->phone
为空

在这种情况下,查询将是
SELECT*FROM[…]或WHERE phone,如“%”
,它将始终返回所有内容

解决方案:如果未提供电话标准,则省略电话标准,或者(黑客警报!)使用该列中永远不会出现的值

另一种方法是将查询更改为

SELECT *
  FROM directory
 WHERE name LIKE :name 
   AND :name_provided = 1
    OR phone LIKE :phone
   AND :phone_provided = 1

然后,如果定义了
$this->phone
,则将提供的电话绑定到1,否则为0。同样,对于
:name\u提供的

问题可能是运行查询时,
$this->phone
为空

在这种情况下,查询将是
SELECT*FROM[…]或WHERE phone,如“%”
,它将始终返回所有内容

解决方案:如果未提供电话标准,则省略电话标准,或者(黑客警报!)使用该列中永远不会出现的值

另一种方法是将查询更改为

SELECT *
  FROM directory
 WHERE name LIKE :name 
   AND :name_provided = 1
    OR phone LIKE :phone
   AND :phone_provided = 1

然后,如果定义了
$this->phone
,则将提供的电话绑定到1,否则为0。同样地,
:name_提供

谢谢。当查询不为空时,只将所需的搜索字段追加到查询中是否更有意义?可能是这样的:如果($\u POST['name']&&&&&&$\u POST['phone']){做这个查询}其他。。。这样做会不会更安全,或者更容易受到注射攻击?我会选择上面的第三种方法。以编程方式构建SQL语句既繁琐又容易出错,所以我更喜欢使用静态语句。再次感谢。。。我会试一试,然后再打给你。谢谢你的帮助。我在@mzedeler上面的帖子中添加了另一个部分。我使用了您建议的查询并添加了自定义if语句。看起来很有效。您同意使用if修改后的解决方案吗?看起来不错,但我仍然会尝试使用
$STH->bindValue(':phone\u提供的',empty($this->phone)?0:1来缩短代码。谢谢。当查询不为空时,只将所需的搜索字段追加到查询中是否更有意义?可能是这样的:如果($\u POST['name']&&&&&&$\u POST['phone']){做这个查询}其他。。。这样做会不会更安全,或者更容易受到注射攻击?我会选择上面的第三种方法。以编程方式构建SQL语句既繁琐又容易出错,所以我更喜欢使用静态语句。再次感谢。。。我会试一试,然后再打给你。谢谢你的帮助。我在@mzedeler上面的帖子中添加了另一个部分。我使用了您建议的查询并添加了自定义if语句。看起来很有效。您同意使用if修改后的解决方案吗?看起来不错,但我仍然会尝试使用
$STH->bindValue(':phone\u提供的',empty($this->phone)?0:1来缩短代码