0

私は mysql db にページを保存しており、フィールドの 1 つは各ページのタグの配列であり、サイト検索に役立つことを期待していました。

呼び出しが原因でエラーが発生しています...

$results = $db->select('pages','','','name',array('name', 'DESC'),'10',array('tags', '%' .$word. '%'));

(select は次のように機能します -- 'table','where','bind for where query match','fields','orderby array','limit',where/like array')

問題は、配列である「タグ」フィールドにあると思います。これについて最善の方法は何ですか?必要に応じて、クエリの後に各結果を取得しています。

//if we got something through $_POST
if (isset($_GET['search'])) {
// here you would normally include some database connection
require_once('../config/dbconfig.php');

// never trust what user wrote! We must ALWAYS sanitize user input
//$word = mysql_real_escape_string($_POST['search']);
$word = htmlentities($_GET['search']);
// build your search query to the database
//$sql = "SELECT title, url FROM pages WHERE content LIKE '%" . $word . "%' ORDER BY title LIMIT 10";

$results = $db->select('pages','','','*',array('name', 'DESC'),'10',array('tags', '%' .$word. '%'));

// get results
if (count($results) > 0) {
    $end_result = '';
    echo '<ul>';
    foreach($results as $row) {
        $bold = '<span class="found">' .$word. '</span>';
        $end_result .= '<li>' .str_ireplace($word, $bold, $row['title']).   '</li>';
    }
    //echo $end_result. '</ul>';
}else {
    //echo '<ul><li>No results found</li></ul>';
}
var_dump($results);
exit;
}

エラーは私のforeachにあると言われています:

警告: foreach() に無効な引数が指定されました

これは、これまでの私のクエリが原因でした。毎回。

調べてみたのですが、特にそのようなものは見当たりませんでした。また、私は疲れているので、詳細を見逃している場合はお知らせください。投稿します。ありがとう!

これは、選択が実行される前に処理される方法です。

public function select($table, $where="", $bind="", $fields="*", $order="", $limit="", $like="") {
    $sql = "SELECT " . $fields . " FROM " . $table;
    if(!empty($where)) {
        $sql .= " WHERE " . $where;
    }
    if (!empty($order)) {
        $sql .= " ORDER BY " . $order[0] . " " . $order[1];
    }
    if (!empty($limit) && is_array($limit)) {
        $sql .= " LIMIT " . $limit[0] . " " . $limit[1];
    }
    if (!empty($limit)) {
        $sql .= " LIMIT " . $limit;
    }
    if (!empty($like)) {
        $sql .= " WHERE " .$like[0]. " LIKE " . $like[1];
    }
    $sql .= ";";
    //var_dump($sql);
    //var_dump($bind);
    //exit;
    return $this->run($sql, $bind);
}

public function run($sql, $bind="") {
    $this->sql = trim($sql);
    $this->bind = $this->cleanup($bind);
    $this->error = "";

    try {
        $pdostmt = $this->prepare($this->sql);
        if($pdostmt->execute($this->bind) !== false) {
            if(preg_match("/^(" . implode("|", array("select", "describe", "pragma")) . ") /i", $this->sql))
                return $pdostmt->fetchAll(PDO::FETCH_ASSOC);
            elseif(preg_match("/^(" . implode("|", array("delete", "insert", "update")) . ") /i", $this->sql))
                return $pdostmt->rowCount();
        }   
    } catch (PDOException $e) {
        $this->error = $e->getMessage();    
        $this->debug();
        return false;
    }
}

($_GET b/c に切り替えた場合、検索は AJAX を使用しており、それを呼び出すためだけに多くのものを変更する気がしなかったので、代わりに URL を使用してページで直接行いました。)

そのクエリの編集で、私はちょうど削除しました、それは初めてでした...疲れて申し訳ありません...

4

1 に答える 1

0

1 つの問題は、count()配列以外の値を使用していることです。

非配列が配列に変換されると、元の値を含む単一要素の配列になります。

(array) 1234; // results in array(0 => 1234)
(array) "ABC" // results in array(0 => "ABC")
(array) false // results in array(0 => false)

count($results)そのため、 when $resultsisを実行するとfalse、値は内部で配列に変換され1、単一要素の配列であるため取得されます。また、結果を処理するためのコードがelse句の代わりに実行されます。

これが、Invalid argument supplied for foreach()表示されているエラー メッセージの原因です。


そもそもなぜ false を返すのかについては、生成されているクエリを見てみましょう。

SELECT name FROM pages ORDER BY name DESC WHERE tags LIKE %someword%

ここには実際にはいくつかの問題があります。

  1. あなたの言葉の価値は引用されていません。したがって、クエリは次のように終了します。

    WHERE tags LIKE %someword%
    

    そのため、1 つのエラーは の周りに引用符がないために発生します%someword%

    これは関数の責任であると思いselect()ます-SQLインジェクションを防ぐために値をエスケープするとともに、これも欠落しています。

    最適な解決策は、おそらく$likeパラメーターで自動的に を使用?し、$bind値に追加することです。は単なる配列であると想定$bindしているため、次のようなことができます。

    if (!empty($like)) {
        if (empty($bind)) $bind = array();
        $bind[] = $like[1];
        $sql .= " WHERE " .$like[0]. " LIKE ?"
    }
    
  2. LIKE条件は、クエリの最後に追加されます-任意のandORDER BYLIMITの後。これにより、無効な SQL も発生します。に追加のパラメータが必要な場合は、オーダーバイの後ではなく$like、既存の条件と同時に処理する必要があります。$where

全体として、既存のパラメーター$likeに渡すだけでなく、 に7 番目のパラメーターを使用している理由がわかりません。"tags LIKE ?"$where


false を返す原因となっているエラーを推測する代わりに、実際のエラー メッセージを見てみましょう。

falseを返す前にエラーメッセージを保存しています...したがって、これをif条件の先頭に追加すると:

if ($results === false) {
    echo($db->error);
} elseif (count($results) > 0) {

... PDO が不平を言っていることを正確に確認できるはずです。

于 2013-07-14T05:46:58.393 に答える