使用pdo在搜索变量中使用冒号(:)进行查询

时间:2012-11-10 18:05:44

标签: php mysql pdo

我有一个恼人的问题。我正在尝试做一些简单的事情,比如从db获取一个单元格值。 这是你可以用db做的最基本的事情......给我一个值,其中有一个具有这个值的单元格....

问题是搜索查询包含冒号(:)。 我在一个准备好的语句的类中使用pdo函数,但没有运气。 我已经尝试了一切,甚至将查询分开,因此它不会包含冒号,但仍然没有运气。我试图恢复到mysqli,但结果仍然相同......

数据表包含title - >等值Morlanda C:2和sourceID - > S11。 顺便说一句,如果我试着在phpmyadmin中搜索一个标题,当我寻找Morlanda C:2时,我会得到我想要的东西。

但是,当我调用我的功能时,这就是:

$sourceID = $sources->sourceAvalibe('Morlanda C:2');

我正在访问我的功能:

public function sourceAvalibe($sourceTitle){
    try {
        $sql = "SELECT sourceID FROM sources WHERE title=:sourceTitle";
        $core = Core::getInstance();
        $stmt = $core->dbh->prepare($sql);
        $stmt->bindParam(':sourceTitle', $sourceTitle, PDO::PARAM_STR, 32);
        $stmt->execute();
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        return $row;    
}

然后结果将为空..

但如果我这样调用函数:

 $sourceID = $sources->sourceAvalibe('1910 Massachusetts Census');

结果将返回我正在寻找的内容。

如果查询包含冒号(:),结果将为空,但如果它包含没有冒号(:)的内容,则返回正确的sourceID。

我试图以不同的方式逃避结肠,但它也不会找到结果。

在我去香蕉之前,你可以帮助我吗?

更新1

您好

感谢您的回答。我正在搜索的数据与数据库中的数据完全相同,使用复制/粘贴。我找到了邪恶的白色空间,但没有找到额外的空间。 我现在改为使用bindValue。

关于禁用模拟准备语句的评论我的答案是.. Que? :) 我现在在本文中找到了关于模拟的内容:Best way to prevent SQL injection?,并更新了我的构造函数类。我仍然得到相同的结果......没什么..

我正在使用此构造函数类进行数据库连接:

class Core {

    public $dbh;
    private static $instance;

   function __construct(){
        $this->dbh = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass, 
        array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8", 
              PDO::ATTR_EMULATE_PREPARES => false));
    }

    public static function getInstance(){
        if (!isset(self::$instance)){
            $object = __CLASS__;
            self::$instance = new $object;
        }
        return self::$instance;
    }

}

更新2

您好

当我将搜索值 Morlanda C:2 硬编码到我的sql行中时,一切都按预期工作。所以我对我生成的php标题进行了比较:

  $sourceTitle = $sourcePreTitle." ".$preTitleNumber[0].":". $preTitleNumber[1];

使用:

   $orginalString = "Morlanda C:2";

他们不匹配。 做了类型检查,但两者都是叮咬。 我开始认为这是旧的UTF8编码问题,在这里弄乱了我。 我的数据库,表和单元格设置为utf8_unicode_ci。 pdo连接是UTF8,并使用Notepad ++将php文件编码为'ANSI with UTF-8'(无BOM)。

这里的整个项目是将一个族谱注释转换为源,所以我从一个表中,在同一个数据库中收集一个长字符串,并将其爆炸,然后将一些部分组合成上面的sourceTitle。然后我搜索数据库以查看源是否已经存在,如果没有,那么我只是创建一个新的。数据的收集和搜索sourceTilte是由相同的pdo类完成的。

更新3

您好

这是一个愚蠢的白色空间或类似的东西...... 我确实在$ sourceTitle变量上使用了trim,但是没有在explode函数中使用数组中的每个部分。当我这样做时,它起作用了。我猜这是最后一个与我混淆的数字之后的终点线。

感谢您的帮助,我现在终于可以将我的3000笔记转换为资源:) 下一个项目是如何防止我的脚本自定义来阻止我的VPS ......

1 个答案:

答案 0 :(得分:3)

您绑定的数据不需要以任何方式进行转义。这几乎是绑定参数的重点。你的问题不是数据中有冒号。最有可能的是,您已经在代码或实际数据库记录中输入了标题。

在不相关的说明中,最好使用bindValue()代替bindParam()用于您的用例:

$stmt->bindValue(':sourceTitle', $sourceTitle);

养成使用bindValue()的习惯,除非你知道你需要通过引用绑定(在这个和类似的情况下,你只使用一次值,所以你不需要通过引用绑定)