简体   繁体   English

MySQL在哪里无法使用php和pdo绑定处理多个字段

[英]MySQL WHERE LIKE not working with multiple fields using php and pdo bind

I'm having an issue here with my WHERE LIKE statement. 我的WHERE LIKE陈述出现问题。 Ideally, I want to be able to search for multiple terms (or just 1 or the other). 理想情况下,我希望能够搜索多个术语(或仅搜索1个或另一个)。 Right now, for testing purposes, I have this separated in my test form where I choose what type of function I'm running. 现在,出于测试目的,我将其隔离在测试表单中,从中选择运行的函数类型。

Purpose : Please ignore the update function for the moment (I'm sure it's a mess like the rest but I haven't finished up there yet). 目的 :请暂时忽略更新功能(我敢肯定其余部分一样,但我还没有完成)。 Still trying to finish the dFind() function. 仍在尝试完成dFind()函数。 The purpose of this testing is so that I can build a data class that will create a class, insert data into the database, search the database for data and pull it, update that data. 该测试的目的是让我可以构建一个数据类,该数据类将创建一个类,将数据插入数据库,在数据库中搜索数据并提取它,然后更新该数据。 So far, every step is a learning curve for me, so please bear with me. 到目前为止,每一步对我来说都是一个学习曲线,所以请耐心等待。

In regards to dFind() : Below, if I just keep the query down to 1 like instance within the dFind() function, it works (the name is the more important of the 2, but I need to search other fields once I get this working). 关于dFind() :在下面,如果我只是像dFind()函数中的实例一样将查询缩减到1,它就可以工作(名称是2中最重要的一个,但是一旦获得,我就需要搜索其他字段这个工作)。 If I add 'OR phone LIKE :phone' to the query, then it doesn't pull the right data (I get everything back). 如果我在查询中添加“ OR phone LIKE:phone”,那么它不会提取正确的数据(我将所有信息都收回了)。 I tested my query in phpmyadmin and it worked fine though, so I'm not sure if it's how I'm treating the query itself or I'm not catching something with php (and I also tried adding ' and escaping it, but that didn't help either). 我在phpmyadmin中测试了我的查询,尽管它工作正常,所以我不确定这是我自己对待查询的方式还是我没有用php捕获某些东西(我也尝试添加'并转义它,但这也没有帮助)。

Do any of you see where I'm going wrong on this? 你们中有人看到我在哪里做错了吗? Thanks in advance. 提前致谢。 Also, any recommendations or direction to achieve the functionality I'm working on is more then welcome. 另外,欢迎提供任何建议或实现我正在使用的功能的方向。 These methods will be incorporated into a small database for setting up, searching for and updating consumers. 这些方法将被合并到一个小型数据库中,用于建立,搜索和更新消费者。

INDEX.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>

CON.PHP : CON.PHP

<\?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";

CLASS.PHP : CLASS.PHP

<\?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;

    }

}

- - - - - - - - - - - - - - - - - - - - - - - - RESOLVED - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 解决 - - - - - - - - - - - - - - - - - - - - - - - -

Using @mzedeler's suggestion (THANKS!) from the below post, which is to change the dFind() query to: 使用以下帖子中的@mzedeler的建议(谢谢!),这是将dFind()查询更改为:

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

Replaced bound data in dFind() with the following and it seems to be working: 将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);

The problem is probably that $this->phone is empty when you run the query. 问题可能是运行查询时$this->phone为空。

In that case, the query will be SELECT * FROM [...] OR WHERE phone LIKE '%%' which will always return everything. 在这种情况下,查询将为SELECT * FROM [...] OR WHERE phone LIKE '%%' ,它将始终返回所有内容。

Solution: leave out the phone criteria if not provided or ( hack alert! ) use a value that will never occur in that column. 解决方案:如果没有提供电话标准,请忽略电话标准,或者( hack alert! )使用该列中永远不会出现的值。

Another way to do this is changing the query to something like 另一种方法是将查询更改为

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

And then bind :phone_provided to 1 if $this->phone is defined, 0 otherwise. 然后如果定义了$this->phone ,则将:phone_provided绑定为1,否则为0。 Likewise with :name_provided . :name_provided同样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM