Lelaki itu mempunyai paparan php carian. Carian yang selamat dan mudah dalam mySQL. Seorang lelaki dari jauh

Maklumat ringkas tentang pelaksanaan carian: Pemprosesan rentetan, memotong aksara perkhidmatan, menyusun pertanyaan pangkalan data, logik, output halaman, perkaitan.

Bahagian 1: Kenyataan am

Pemprosesan Rentetan

Perkara pertama yang perlu anda lakukan ialah memotong tali dengan tangan anda.

$search = substr($search, 0, 64);

64 aksara akan mencukupi untuk pengguna mencari. Sekarang mari kita bakar semua simbol "tidak normal" dengan seterika panas.

$search = preg_replace("/[^\w\x7F-\xFF\s]/", " ", $search);

Secara teori, anda tidak seharusnya memberi pengguna peluang untuk mencari menggunakan perkataan yang terlalu pendek - antara lain, ini sangat memuatkan pelayan. Jadi, mari benarkan anda mencari hanya dengan perkataan yang lebih panjang daripada dua huruf (jika had lebih besar, anda perlu menggantikan "(1,2)" dengan "(1, bilangan aksara)").

$baik = trim(preg_replace("/\s(\S(1,2))\s/", " ", ereg_replace(" +", " "," $search ")));

Dan selepas menggantikan perkataan buruk, anda perlu memampatkan ruang berganda (ia dibuat khusus untuk carian perkataan pendek yang betul).

$baik = ereg_eplace(" +", " ", $good);

Katakan kami ingin memberi pengguna peluang untuk memilih logik carian - cari semua perkataan atau hanya satu daripada beberapa perkataan. Jika anda mahu melakukannya seperti dalam Yandex - dua ampersand bermaksud "I" (word1&&word2&&word3) atau sesuatu yang lain, maka saya bukan penasihat. Kebodohan dengan rentetan di tapak kecil imho tidak berbaloi dengan masa yang dihabiskan. Oleh itu, kami melukis borang carian seperti ini:

cari mana-mana perkataan cari semua perkataan

Dan dalam skrip carian kami sekali lagi menyemak perkara yang dimasukkan pengguna:

Jika (($logic!="DAN") && ($logic!="OR"))
$logik = "ATAU";

Bagaimana logik akan digunakan adalah di bawah.

Statistik carian

Adalah idea yang baik untuk memaklumkan pengguna dengan segera berapa banyak baris jadual yang ditemuinya. Untuk melakukan ini, permintaan tambahan dibuat kepada pangkalan data:

$query = "PILIH id DARI jadual DI MANA medan SEPERTI "%". str_replace(" ", "%" ATAU medan SEPERTI "%", $good). "%"";

Untuk statistik pada perkataan individu, anda boleh melakukan perkara berikut:

$word = explode(" ", $search); while (list($k, $v) = each($word)) ( if (strlen($v)>2) $stat="$v:". mysql_num_rows(mysql_query("SELECT id FROM table WHERE field LIKE " %$v%"")); else $stat="$v: short"; ); $word_stats = "Statistik perkataan: ". meletup("", $stat). "
"; unset ($stat);

Keluaran hasil halaman demi halaman

Nah, sebaik sahaja kami mempunyai reka letak carian dan beberapa baris hasil carian, melakukan carian halaman demi halaman adalah satu kek. Kami menyemak pembolehubah $page (tidak kurang daripada 0, tidak lebih daripada $results_amount/$rows_in_page). Dalam pertanyaan yang mengira bilangan baris (lihat di atas), kami menulis medan yang kami perlukan dan medan untuk mengisih. Dan kemudian kami menambah

Jika ($halaman==0) $request .= "LIMIT $rows_in_page"; else $request .= "HAD ". $halaman*$baris_dalam_halaman. ","". $baris_dalam_halaman;

(sintaks: LIMIT atau LIMIT , )

Hasil daripada melaksanakan permintaan sedemikian, kami akan menerima baris yang sama yang perlu dipaparkan pada halaman. Untuk navigasi, anda boleh sama ada melukis pautan ke halaman seterusnya dan sebelumnya, atau, yang lebih sukar, buat navigasi bar pada beberapa muka surat.

Jika ($halaman>0) cetak (" Halaman sebelumnya"); if ($page0 ORDER BY relev DESC

walaupun anda boleh:

PILIH *, PADANKAN medan TERHADAP ("$searchwords") sebagai relev DARI jadual DI MANA PADAN medan LAWAN ("$searchwords")>0 ORDER OLEH relev DESC

  • Kelajuan agak tinggi - walaupun dalam beberapa kes lebih pantas daripada carian
  • Semua kerja di atas bermula dari MySQL versi 3.23.23
  • Apabila membuat indeks FULLTEXT pada beberapa medan, terdapat 2 pilihan:

    CIPTA jadual JADUAL (medan1 VARCHAR (255), field2 TEXT, FULLTEXT (field1, field2)) CREATE TABLE table (field1 VARCHAR (255), field2 TEXT, FULLTEXT (field1), FULLTEXT (field2))

    Dalam kes pertama, pertanyaan berikut mungkin:

    PILIH *, MATCH field1, field2 AGAINST ("$searchwords") sebagai relev DARI jadual ORDER BY relev DESC

    perkaitan dikira untuk semua medan sekaligus. Dalam kes kedua, permintaan sedemikian akan menghasilkan ralat. Di sini kami mengira perkaitan seperti berikut:

    PILIH *, PADANKAN medan1 LAWAN ("$kata carian")+PADANKAN medan2 LAWAN ("$kata carian") sebagai relev DARI jadual ORDER OLEH relev DESC

    Pilihan kedua agak rumit dalam pertanyaan, bagaimanapun, pada pendapat saya lebih baik, kerana Fleksibiliti carian meningkat - untuk setiap medan anda boleh tetapkan, sebagai contoh, pekali keertian dan, apabila merumuskan perkaitan medan, darabkannya dengan pekali ini. Frasa carian akan "lebih" dicari dalam medan dengan pekali yang lebih tinggi. Sebagai contoh, jika kami melakukan carian pada halaman diindeks katalog sumber, maka medan nama halaman biasanya ditetapkan dengan pekali yang lebih tinggi daripada medan tag atau kata kunci perihalan meta.

    Bahagian 3: Latihan Perkaitan

    Pertama, bagaimana untuk menambah indeks FULLTEXT:

    Mysql> alter table articlea add fulltext(ztext); RALAT 1073: BLOB lajur "ztext" tidak boleh digunakan dalam spesifikasi utama dengan jenis jadual yang digunakan mysql> alter table articlea type=myisam; Pertanyaan OK, 36 baris terjejas (0.60 saat) Rekod: 36 Pendua: 0 Amaran: 0 mysql > ubah jadual artikela tambah teks penuh(zteks); Pertanyaan OK, 36 baris terjejas (10.00 saat) Rekod: 36 Pendua: 0 Amaran: 0

    Indeks teks hanya boleh dilakukan pada jadual jenis MyISAM. Teks diambil dari jadual dan dibuang ke dalam fail indeks, dan jumlah pangkalan data bertambah. Berkenaan permintaan. Anda tidak boleh menggunakan medan relev dalam klausa WHERE:

    PILIH *, PADANKAN medan TERHADAP ("$searchwords") sebagai relev DARI jadual WHERE relev>0 ORDER BY relev DESC

    Walaupun anda boleh:

    PILIH *, PADANKAN medan TERHADAP ("$searchwords") sebagai relev DARI jadual DI MANA PADAN medan LAWAN ("$searchwords")>0 ORDER OLEH relev DESC

    Medan yang dikira, sudah tentu, tidak boleh digunakan di WHERE mengikut semua peraturan sintaks, tetapi boleh digunakan dalam HAVING:

    PILIH *, PADANKAN medan TERHADAP ("$searchwords") sebagai relev DARI jadual MEMPUNYAI relev>0 ORDER OLEH relev DESC

    Carian melalui PERLAWANAN, seperti yang ditulis Oleg, dilakukan hanya dengan keseluruhan perkataan. ...Namun, anda hanya boleh mengisih mengikut kaitan dan memilih dengan SUKA (ini, sudah tentu, akan menjejaskan prestasi, saya tidak tahu berapa banyak).

    Kami mengalih keluar keadaan "relev>0" dan meninggalkan pengisihan. Selebihnya adalah sama seperti sebelumnya - kami memotong rentetan yang terhasil dan mengubahnya menjadi pertanyaan dengan beberapa operator LIKE:

    PILIH *, medan PADANAN TERHADAP ("$words") SEBAGAI relev DARI jadual DI MANA medan SEPERTI "%$word1%" ATAU medan SEPERTI "%$word2%" ORDER OLEH relev DESC, datefield DESC

    Bahagian 4: Meneruskan apa yang kita mulakan

    Saya meneruskan topik pencarian, disusun mengikut kaitan, dalam pangkalan data MySQL, yang saya mulakan pada bulan September.

    MySQL menawarkan dalam versi terkini pangkalan data untuk menggunakan pengindeksan FULLTEXT dan medan MATCH AGAINST construction untuk carian teks penuh. Walau bagaimanapun, tidak semua pelayan mempunyai versi terkini MySQL, dan tidak semua penyedia pengehosan mahu mengemas kini perisian atas sebab kebolehpercayaan sistem.

    Pada satu masa, saya menganggap bahawa carian yang disusun mengikut kaitan perlu dilakukan dalam beberapa pertanyaan, dan, oleh itu, adalah lebih baik untuk tidak melakukan ini sama sekali. Fikiran bahawa perkaitan boleh dikira dalam pertanyaan itu sendiri datang kepada saya dari jauh, tetapi saya takut untuk membayangkan pembinaan sedemikian.

    Walau bagaimanapun, seorang pekerja salah satu syarikat pembina laman web N-ska bermegah kepada saya tentang sistem carian yang mereka gunakan di tapak web mereka. Saya pasti tidak ingat permintaan itu, saya akan cuba menghasilkan semula seperti ini:

    PILIH tajuk, format_tarikh(tarikh_bahan,"%e.%c.%y") AS date1, IF(teks seperti "%word1 word2 word3%", 3*10, 0) + IF(teks SEPERTI "%word1%", 9, 0) + IF(teks SEPERTI "%word2%", 9, 0) + IF(teks SEPERTI "%word3%", 9, 0) SEBAGAI perkaitan DARI jadual DI MANA teks SEPERTI "%word1%" ATAU teks SEPERTI " %word2%" ATAU teks SEPERTI "%word3%" ORDER MENGIKUT perkaitan DESC, material_date DESC

    Ia kelihatan mengerikan, tetapi ia berfungsi walaupun pada versi MySQL yang lebih lama. Saya cuba membandingkan kelajuan dengan pertanyaan ini:

    PILIH tajuk, format_tarikh(tarikh_bahan,"%e.%c.%y") SEBAGAI tarikh1, PADANKAN teks LAWAN("word1 word2 word3") SEBAGAI perkaitan DARI jadual DI MANA teks SEPERTI "%word1%" ATAU teks SEPERTI "%word2% " ATAU teks SEPERTI "%word3%" ORDER MENGIKUT perkaitan DESC, material_date DESC

    Secara purata, kelajuan pertanyaan universal adalah separuh daripada kelajuan pertanyaan menggunakan binaan baharu. Yang agak logik - lebih besar serba boleh, lebih besar intensiti sumber.

    Mari cuba membina pertanyaan sedemikian secara automatik. Kami memotong baris panjang, serta semua aksara yang salah dan perkataan pendek. Mari kita lukis permintaan.

    $query = "PILIH tajuk, format_tarikh(tarikh_bahan,"%e.%c.%y") AS date1, IF(teks seperti "%". $good_words. "%", ". (substr_count($good_words, " " ) + 1). "*10, 0) + IF(teks SUKA "%". str_replace(" ", "%", 9, 0) + IF(teks SUKA "%", $good_words). "%", 9, 0) SEBAGAI perkaitan DARI jadual DI MANA teks SEPERTI "%". str_replace(" ", "%" ATAU teks SEPERTI "%", $good_words). "%" ORDER MENGIKUT perkaitan DESC, material_date DESC";

    Tak susah sangat. Untuk kebolehpercayaan dan perlindungan banjir, anda boleh mengehadkan bilangan perkataan dalam permintaan.

    Beberapa penambahan kepada penerbitan terdahulu

    Jumlah bilangan baris yang terdapat dalam jadual. Untuk memaparkan hasil carian, sudah tentu, anda perlu menggunakan operator LIMIT (agar tidak menulis pembentukan parameter ini setiap kali, gunakan fungsi siap sedia). Jika tiada operasi pengelompokan dilakukan dalam pertanyaan, lebih baik mengira bilangan baris dengan segera dalam pertanyaan - COUNT(*), dan bukan melalui fungsi php mysql_num_rows(). Anda boleh menyemaknya di atas meja besar. Jika operasi kumpulan dilakukan, kami membuat pertanyaan dengan COUNT(DISTINCT()), tetapi tanpa GROUP BY.

    Lampu latar. Jika tiada tag html dalam teks, kehidupan lebih mudah

    $text = preg_replace("/word1|word2|word3/i", "\\0", $text);

    Jika teg digunakan dalam teks, maka terdapat tiga pilihan: a) jangan serlahkan b) kerana pengguna tidak melihat tag (melainkan pengguna yang sangat ingin tahu), maka anda boleh membuat medan indeks di mana tidak akan ada tag tetapi simbol [^\w\x7F- \xFF\s] akan digantikan dengan ruang (aksara ini dipotong daripada rentetan carian pada awal-awal lagi, jadi ia tidak dicari). Dalam kes ini, carian dan penyerlahan harus dilakukan menggunakan indeks. c) serlahkan teks daripada medan biasa, setelah memotong teg menggunakan fungsi srip_tags() sebelum ini.

    Versi penuh kod carian, seperti biasa, terdapat dalam senarai fail.




    Jika anda mempunyai sebarang soalan lain atau sesuatu yang tidak jelas - selamat datang ke kami

    Cara terbaik untuk mengekalkan pengguna di tapak adalah dengan membenarkan dia mencari perkara yang dia cari. Jika anda mencipta sistem yang mudah untuk ini, maka tahap keutamaan untuk tapak anda akan berkembang dan pengguna pasti akan kembali untuk mencari apa yang menarik minatnya.

    Saya akan menunjukkan kepada anda cara membuat borang carian yang ringkas tetapi berkesan dari segi fungsi yang akan digunakan untuk mencari artikel di tapak. Hasilnya akan muncul pada halaman tanpa sebarang muat semula, yang sudah pasti merupakan cara terbaik untuk menyampaikan maklumat.

    Saya akan mencipta 2 fail: search.php, yang akan mengandungi HTML dan JavaScript. Fail kedua, do_search.php akan mengandungi kod PHP. Mari mulakan membuat fail pertama:

    PHP, demo carian jQuery $(function() ($(".button_search").klik(function() ( // dapatkan apa yang pengguna tulis var searchString = $("#search_box").val(); // borang rentetan pertanyaan var data = "search="+ searchString; // jika searchString tidak kosong if(searchString) ( // buat permintaan ajax $.ajax(( type: "POST", url: "do_search.php", data: data, beforeSend: function(html) ( // akan dijalankan sebelum permintaan dipanggil $("#results").html(""); $("#searchresults").show(); $(". word").html (searchString); ), success: function(html)( // akan dijalankan selepas menerima keputusan $("#results").show(); $("#results").append(html) ; ) )); ) return false; )); )); Cuba masukkan perkataan ajax
    Keputusan untuk

    Dalam fail ini kami telah mencipta borang HTML biasa yang menghantar permintaan POST ke bahagian belakang - fail do_search.php.

    Kod PHP mengandungi ulasan supaya anda boleh memahami cara skrip berfungsi dengan mudah. Jika terdapat padanan dalam pangkalan data, anda menunjukkannya kepada pengguna anda, menyerlahkan dalam huruf tebal perkataan yang dicari oleh pengguna.

    Mari berikan semuanya sedikit CSS:

    Body( font-family:Arial, Helvetica, sans-serif; ) *( margin:0; padding:0; ) #container ( margin: 0 auto; width: 600px; ) a ( color:#DF3D82; text-decoration: tiada ) a:hover ( color:#DF3D82; text-decoration:underline; ) ul.update (list-style:none;font-size:1.1em; margin-top:10px ) ul.update li( height:30px; border-bottom:#dedede solid 1px; text-align:left;) ul.update li:first-child( border-top:#dedede solid 1px; height:30px; text-align:left; ) #flash ( margin- atas:20px; text-align:left; ) #searchresults ( text-align:left; margin-top:20px; display:none; font-family:Arial, Helvetica, sans-serif; font-size:16px; color: #000; ) .word ( font-weight:bold; color:#000000; ) #search_box ( padding:4px; border:solid 1px #666666; width:300px; height:30px; font-size:18px;-moz- jejari sempadan: 6px;-jejari-sempadan-webkit: 6px; ) .butang_carian ( sempadan:#000000 pepejal 1px; padding: 6px; warna:#000; berat fon: tebal; saiz fon:16px;-moz- jejari sempadan: 6px;-jejari-sempadan-webkit: 6px; ) .ditemui ( berat fon: tebal; gaya fon: condong; warna: #ff0000; ) h2 ( margin-kanan: 70px; )

    Jadi anda telah belajar cara membuat borang carian mudah yang berfungsi tanpa memuatkan semula halaman. Saya harap anda menikmati pelajaran.

    Daripada pengarang: Skrip carian PHP adalah sebahagian daripada sumber moden. Tetapi bagi pemaju pemula, pelaksanaannya boleh menjadi "batu asas". Hari ini saya akan cuba menerangkan pembinaan modul sedemikian semudah mungkin, supaya kodnya tidak menakutkan anda dengan kerumitannya yang berlebihan.

    Mencari PHP

    Menyusun sistem carian dalaman di laman web adalah tugas penting. Kehadiran fungsi sedemikian dengan ketara meningkatkan sumber di mata mana-mana pengguna. Ini adalah benar terutamanya untuk tapak bertema sempit, yang kandungannya dikhaskan untuk menyelesaikan "masalah" tertentu. Contohnya, dalam pengaturcaraan web.

    Selalunya, untuk menulis skrip carian tapak dalam PHP, gabungan bahasa program ini dengan . Teknologi AJAX digunakan untuk melaksanakan sistem carian interaktif. Tetapi hari ini kami tidak akan "berangin" dalam keadaan liar seperti itu, dan akan memberi tumpuan kepada versi klasik.

    Saya akan memberikan contoh carian yang paling mudah. Ia tidak akan menyemak kehadiran sambungan ke DBMS, menyemak keputusan sampel yang dikembalikan, dsb. Anda boleh menambah semua kehalusan ini sendiri. Tujuan bahan ini adalah untuk memberikan idea umum membina sistem carian dalaman pada sumber Internet moden. Pergi!

    Sebagai permulaan, saya akan menyediakan kod untuk borang untuk memasukkan pertanyaan carian. Ini adalah penanda yang mudah, tanpa sedikit pun "tambahan" gaya.




    < form name = "f1" method = "post" action = "search.php" >

    < input type = "search" name = "search_q" / > < / br >

    < / br >

    < input type = "submit" value = "Cari" / > < / br >

    < / form >

    Ini adalah rupa bentuk dalam penyemak imbas:

    Mari pergi ke skrip

    Sekarang mari kita beralih terus ke kod program. Sebagai permulaan, saya akan memberikan struktur jadual yang perlu dibuat dalam . Kami akan mencari bahan yang diterbitkan mengikut tajuk. Menggunakan prinsip yang sama, anda boleh membuat skrip PHP untuk mencari perkataan di tapak. Semuanya di tangan anda yang mampu.

    Mula-mula kita memintas nilai yang dimasukkan oleh pengguna ke dalam borang. Kemudian kami mengosongkannya daripada "sampah": ruang tambahan, tag dan sambungkan ke pangkalan data. Selepas ini, kami menjalankan pertanyaan SQL di mana kami membandingkan nilai pertanyaan carian dengan nama bahan yang disimpan dalam jadual. Sekiranya terdapat padanan, kami memaparkan kandungan yang sepadan. Pada akhirnya, kami menutup sambungan ke MySQL dan "menetapkan semula" permintaan. Berikut ialah keseluruhan contoh kod: