2017-01-17 12 views
2

コードをrejuvinateしようとすると、私は主に14年以上前に書いています。私が書いた素敵なセットアップは、特定の場所に欠けていた、つまりユーザーの入力を処理することがなかったことがわかりました。PHP/MySQLのより良いユーザー検索

レッスン:ごみ箱、タイプミス、およびダンプをバリデーターよりも先に注入する能力を過小評価しないでください。

今やSELECTドロップダウンには470個のアイテムが存在するため、古い方法が限界に達しています。私はプロセスのこの部分を再考したいので、それが突破口を打つことについて心配する必要はありません。

したがって、タイピストが検索文字列を入力した後、同じ行にある5つのデータをチェックするように、ファジー検索メソッドを作成することを考えます。

ステージ名、2つの既知の名前、正当な名前、およびステージ名に基づいたsoundex()インデックスに対する最終チェックとして送信された名前を確認する必要があります。

do/whileループの一部として、これらのことをチェックするために複雑なコードブロックを試しました(そして、これは動作しません。 。

以下では、var $Rinにはユーザー指定の名前が含まれています。

$setr = mysql_query("SELECT ID,StageName,AKA1,AKA2,LegalName,SoundEx FROM performers"); 
IF ($R = mysql_fetch_array($setr)) { 
    do { 
     $RT = substr(trim($Rin), 5); 
     $RT1 = substr($R[1], 5); 
     $RT2 = substr($R[2], 5); 
     $RT3 = substr($R[3], 5); 
     $RT4 = substr($R[4], 5); 
     $RTx = soundex($RT); 
     IF ($RT == $RT1) { 
      $RHits[] = $R[0]; 
     } 
     IF ($RT == $RT2) { 
      $RHits[] = $R[0]; 
     } 
     IF ($RT == $RT3) { 
      $RHits[] = $R[0]; 
     } 
     IF ($RT == $RT4) { 
      $RHits[] = $R[0]; 
     } 
     IF ($RTx == $R[5]) { 
      $RHits[] = $R[0]; 
     } 
    } while ($R = mysql_fetch_array($setr)); 
} 

私は、全体のテーブルだけがうまくいけば、より少ないヒットを持って選択し、ドロップダウンに移入ます近くヒットのID番号の年代の配列を、構築しますということでアイデア。つまり、その配列の内容から結果セットを照会することで、実行者の名前をSELECTドロップダウンに表示し、その選択肢の値としてID#を渡します。

「WHERE句で配列を使用する必要があります」というヒットをしたときに、その答えを見つけた後、私は下の規定#2のために私が運が悪いと思われ始めました。だから私は別の検索方法を見て始めました。どこにいてもわかりませんが、もっと混乱しました。

したがって、6つのフィールドについて1つのテーブルをスキャンし、ユーザー入力に対して5をチェックし、元のテーブルのサブセットに表示する6番目のテーブルを調べる方が良いでしょうか?

思考プロセス:テーブル全体に対する

、レコードごとに、この順序でこれらのテストに対するテスト$りん:

$凛 - >芸名
$凛 - > AKA1
$凛 - > AKA2
$凛 - >氏名権
のsoundex($りん) - > SOUNDEX

ここで、5つの操作のいずれかでヒットすると、結果セットを470人のパフォーマーから適切なリストに絞り込むために使用される結果配列にID#が追加されます。

に関する規定

1)書かれたとして、私はこれは、SQLインジェクション攻撃に対して脆弱であることを知っています。

2)サーバーがPHP 4.4.9とMySQL 4.0.27-Standardを実行しているため、アップグレードできません。私はお金が費やされる前にそれが動作することを証明しなければなりません。

3)これは趣味レベルのもので、私の仕事ではありません。

4)出演者は、名前に英語以外の名前や要素を使用することが多く、データ入力タイピストによるタイプミスや重複が発生しています。

私はこの種のものについて多くのmysqliとPDOの回答を見つけました。そして、半分しか意味をなさないことがたくさんあります(下記のリンク#4のように)。私は何を壊すようにしようとすると、これらのもののスピードアップに取り組んでいます。私はJavascriptの先行入力ライブラリは良いかもしれないとのコメントで述べた

  1. PHP mysql using an array in WHERE clause
  2. PHP/MySQL small-scale fuzzy search
  3. MySQL SubString Fuzzy Search
  4. Sophisticated Name Lookup
+0

最初に最初に "mysql_ *"がデリケートされました。代わりに "mysqli_ *"関数を使用してください。 :) – Ronald

+0

mysqliはPHP4.4.9で利用できますか? –

+1

数百のオプションとタイプアヘッドで、ページロード後にバックグラウンドでサービスコール(AJAX)を使用してデータをロードし、Javascriptツールで先行処理を行うことをお勧めします。 [TwitterのTypeaheadライブラリ](https://twitter.github.io/typeahead.js/examples/)、複数の列を検索している場合は特に*です。 – alttag

答えて

1

場所はすでにを見てあなたのための選択。私はTwitterのTypeaheadライブラリとBloodhoundエンジンがかなり堅牢であることを発見しました。残念ながら、ドキュメントは混在しています。必要なものがサンプルに非常によく似ている限り、あなたは金色ですが、特定の詳細(トークナイザの説明など)がありません。ここでスタックオーバーフロー上のseveral questions re Typeaheadの一つで

、@JensAKochは言う:

正直に言うと、私はツイッターをtypeahead.jsをあきらめたと思います。私たちは13000個の星を見ています。完全なバグトラッカーは、メンテナやソフトウェアが壊れていて、2015年の最後のリリースです。 ...フォークの1つを試してみてください。

簡単に言えば、ほんの少しの点検では、フォークの文書がもう少しよく見えます。あなたはそれをチェックしたいかもしれません。

サーバーサイドコード:PHPの古いバージョンを使用しての注意事項の

すべてが適用されます。 PDOをPHP 5で使用するためには、再構築を強くお勧めしますが、この例ではPHP 4を要求どおりに使用しています。

完全にテストされていないPHPコード。 json_encode()が良いだろう、しかし、のようなPHP 5.あなたのエンドポイントがものになるだろうまでは表示されません:クライアント側のコード

headers("Content-Type: application/json"); 
$results = mysql_query(
    "SELECT ID,StageName,AKA1,AKA2,LegalName,SoundEx FROM performers" 
); 

$fields = array("ID","StageName","AKA1","AKA2","LegalName","SoundEx"); 

echo "["; 

$first = true; 
while ($row = mysql_fetch_array($results)) { 
    ($first) ? $first = false : echo ','; 

    echo "\n\t,{"; 
    foreach($fields as $f) { 
     echo "\n\t\t\"{$f}\": \"".$row[$f]."\""; 
    } 
    echo "\n\t}"; 
} 
echo "]"; 

この例では、すべてのためのスタブとしてstatic JSON fileを使用しています結果。結果セットが1,000件以上になることが予想される場合は、remote option of Bloodhoundを調べる必要があります。これには、クエリを処理するカスタムPHPコードを書く必要がありますが、すべての(または少なくとも最も一般的な)データをダンプするエンドポイントとほとんど同じように見えます。

var actors = new Bloodhound({ 
 
    // Each row is an object, not a single string, so we have to modify the 
 
    // default datum tokenizer. Pass in the list of object fields to be 
 
    // searchable. 
 
    datumTokenizer: Bloodhound.tokenizers.obj.nonword(
 
    'StageName','AKA1','AKA2','LegalName','SoundEx' 
 
), 
 
    queryTokenizer: Bloodhound.tokenizers.whitespace, 
 
    // URL points to a json file that contains an array of actor JSON objects 
 
    // Visit the link to see details 
 
    prefetch: 'https://gist.githubusercontent.com/tag/81e4450de8eca805f436b72e6d7d1274/raw/792b3376f63f89d86e10e78d387109f0ad7903fd/dummy_actors.json' 
 
}); 
 

 
// passing in `null` for the `options` arguments will result in the default 
 
// options being used 
 
$('#prefetch .typeahead').typeahead(
 
    { 
 
     highlight: true 
 
    }, 
 
    { 
 
     name: 'actors', 
 
     source: actors, 
 
     templates: { 
 
     empty: "<div class=\"empty-message\">No matches found.</div>", 
 
     
 
     // This is simply a function that accepts an object. 
 
     // You may wish to consider Handlebars instead. 
 
     suggestion: function(obj) { 
 
      return '<div class="actorItem">' 
 
       + '<span class="itemStageName">'+obj.StageName+"</span>" 
 
       + ', <em>legally</em> <span class="itemLegalName">'+obj.LegalName+"</span>" 
 
     } 
 
     //suggestion: Handlebars.compile('<div><strong>{{value}}</strong> – {{year}}</div>') 
 
     }, 
 
     display: "LegalName" // name of object key to display when selected 
 
     // Instead of display, you can use the 'displayKey' option too: 
 
     // displayKey: function(actor) { 
 
     //  return actor.LegalName; 
 
     // } 
 
});
/* These class names can me specified in the Typeahead options hash. I use the defaults here. */ 
 
    .tt-suggestion { 
 
     border: 1px dotted gray; 
 
     padding: 4px; 
 
     min-width: 100px; 
 
    } 
 
    .tt-cursor { 
 
     background-color: rgb(255,253,189); 
 
    } 
 
    
 
    /* These classes are used in the suggestion template */ 
 
    .itemStageName { 
 
     font-size: 110%; 
 
    } 
 
    .itemLegalName { 
 
     font-size: 110%; 
 
     color: rgb(51,42,206); 
 
    }
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script> 
 
<script src="https://twitter.github.io/typeahead.js/releases/latest/typeahead.bundle.js"></script> 
 

 

 
<p>Type something here. A good search term might be 'C'.</p> 
 
<div id="prefetch"> 
 
    <input class="typeahead" type="text" placeholder="Name"> 
 
</div>

は簡単にするために、ここにGist of the client-side codeです。

+0

これは実行可能なソリューションのようです。私はPHPのようにjavascriptに精通していません。私は確かにこれを徹底的に見ていきます。ありがとうございました。 –

関連する問題