6

迷惑な問題があります。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?:)私は今、この記事で、エミュレートに関してあなたが話していることを見つけました:SQLインジェクションを防ぐための最良の方法は?、およびコンストラクタークラスを更新しました。私はまだ同じ結果を得ています..何も..

私はdb接続にこのコンストラクタークラスを使用しています:

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

やあ

検索値MorlandaC:2を自分のSQL行にハードコーディングすると、すべてが意図したとおりに機能します。そこで、phpで生成されたタイトルを比較しました。

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

と:

   $orginalString = "Morlanda C:2";

そして、それらは一致しませんでした。タイプチェックをしましたが、両方とも刺し傷として出てきました。ここで私を混乱させているのは、古いUTF8エンコーディングの問題だと思い始めています。私のデータベース、テーブル、セルはutf8_unicode_ciに設定されています。pdo接続はUTF8であり、Notepad ++を使用して「ANSIwithUTF-8」(BOMなし)でphpファイルをエンコードしています。

ここでのプロジェクト全体は、系図のメモをソースに変換することです。そのため、同じデータベース内のテーブルから長い文字列を収集し、それを分解して、上記のようにいくつかのピースをsourceTitleにアセンブルします。次に、データベースを検索してソースがすでに存在するかどうかを確認し、存在しない場合は、新しいソースを作成します。データの収集とsourceTilteの検索は、同じpdoクラスによって実行されます。

アップデート3

やあ

それはばかげた空白かそれに類似したものでした....私は$sourceTitle変数でトリムを使用しましたが、explode関数からの配列の各部分では使用しませんでした。私がそれをしたとき、それはうまくいきました。私を台無しにしたのは、最後の番号の後のエンドラインか何かだったと思います。

あなたの助けに感謝します。私はついに私の3000のメモをソースに変換することができます:)次のプロジェクトは私のスクリプトが私のVPSを窒息させるのを防ぐ方法です...

4

1 に答える 1

3

バインドするデータは、決してエスケープする必要はありません。これが、バインドパラメータのほぼすべてのポイントです。問題は、データにコロンがあることではありません。ほとんどの場合、コードまたは実際のデータベースレコードのいずれかでタイトルを入力していません。

無関係なことに、ユースケースbindValue()の代わりに使用することをお勧めします。bindParam()

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

参照によってバインドする必要があることがわかっている場合を除いて、使用する習慣を身にbindValue()付けてください(この場合や同様の場合、値を1回だけ使用するため、参照によってバインドする必要はありません)。

于 2012-11-10T18:12:30.037 に答える