Judul dan kategori WordPress, fungsi wp_list_categories. Kelas PHP untuk pekerjaan yang nyaman dan aman dengan MySQL kategori php tidak berguna

Pada artikel ini (tingkat webmaster - lanjutan) kita akan berbicara tentang apa yang disebut berpotongan dengan cara yang berbeda. navigasi "segi". Untuk menyederhanakan asimilasi materi, saya sarankan membaca artikel Wikipedia "Klasifikasi segi" dan publikasi di Bahasa inggris(tetapi dengan gambar!) "Rancang navigasi yang lebih baik untuk situs web Anda."

Navigasi segi dengan pemfilteran berdasarkan warna atau kisaran harga mungkin berguna bagi pengunjung Anda, namun sering kali berbahaya dalam penelusuran karena menghasilkan banyak kombinasi alamat dengan konten duplikat. Karena duplikat mesin pencari tidak akan dapat dengan cepat memindai situs untuk mencari pembaruan konten, yang akibatnya memengaruhi pengindeksan. Untuk meminimalkan masalah ini dan membantu webmaster menjadikan penelusuran navigasi tersaring ramah, kami ingin:

Ideal untuk pengguna dan pencarian Google

Hapus jalur ke halaman produk/artikel:

Representasi URL untuk halaman kategori:
http://www.example.com/category.php?category=gummy-candies

Representasi URL khusus produk:
http://www.example.com/product.php?item=swedish-fish

Duplikat yang tidak diinginkan disebabkan oleh navigasi segi

Halaman yang sama dapat diakses dari alamat web yang berbeda:

Halaman kanonik



URL: example.com/product.php? item=ikan swedia

Halaman duplikat



URL:example.com/product.php? item=ikan-swedia&kategori=permen bergetah&harga=5-10


kategori=permen bergetah&rasa=asam&harga=5-10

Kesalahan:

  • Tidak ada gunanya bagi Google karena pengguna jarang menelusuri [selai jeruk dengan harga $9:55].
  • Tidak berarti bagi perayap, yang akan menemukan item yang sama ("salad buah") dari halaman kategori induk (baik "Jummy" atau "Sour Gummy").
  • Poin negatif bagi pemilik situs, karena permintaan pengindeksan diencerkan dengan banyak versi dari kategori yang sama.
  • Suatu hal yang negatif bagi pemilik situs, karena tidak ada gunanya dan menjadi beban tambahan lebar pita lokasi
Halaman kosong:


URL: example.com/category.php? kategori=permen bergetah&rasa=asam&harga=di atas 10

Kesalahan:

  • Kode untuk mesin pencari dikembalikan dengan tidak benar (dalam hal ini, halaman harus mengembalikan kode 404)
  • Halaman kosong untuk pengguna


Solusi terburuk (tidak ramah pencarian) untuk navigasi segi

Contoh No.1: Parameter non-standar digunakan sebagai bagian dari URL: koma dan tanda kurung kunci=nilai&:

  • contoh.com/category? [ kategori:permen bergetah ][ sort:harga-rendah-ke-tinggi ][ sid:789 ]
  • example.com/category?category , permen bergetah , sortir , rendah ke tinggi , sid , 789
Cara:
contoh.com/category? kategori=permen bergetah&sort=rendah ke tinggi&sid=789

Contoh No.2: Menggunakan direktori atau jalur file daripada parameter dalam daftar nilai yang tidak mengubah konten halaman:
example.com/c123 /s789/product?swedish-fish
(di mana /c123/ kategori, /s789/ ID sesi, yang tidak mengubah konten halaman)

Solusi yang bagus:

  • contoh.com /gummy-candy/ produk?item=ikan swedia&sid=789(direktori, /gummy-candy/, mengubah konten halaman dengan cara yang berarti)
Solusi terbaik:
  • example.com/product?item=swedish-fish& kategori=permen bergetah&sid=789 (Parameter URL memberikan fleksibilitas lebih besar bagi mesin telusur untuk menentukan cara merayapi secara efektif)
Sulit bagi crawler untuk membedakan nilai-nilai yang berguna (seperti "permen bergetah") dari nilai-nilai yang tidak berguna (seperti "SESSIONID") ketika nilai-nilai ini ditempatkan langsung di jalur tautan. Di sisi lain, parameter URL memberikan fleksibilitas bagi mesin telusur untuk menguji dan menentukan dengan cepat kapan nilai tertentu tidak memerlukan akses crawler ke semua opsi.

Nilai umum yang tidak mengubah konten halaman dan harus dicantumkan sebagai parameter URL meliputi:

  • ID Sesi
  • Pelacakan ID
  • ID perujuk
  • Stempel waktu
Contoh No.3: Mengonversi nilai yang dibuat pengguna (mungkin tak terbatas) menjadi parameter URL yang dapat dirayapi dan diindeks, namun tidak berguna untuk penelusuran.
Menggunakan data kecil yang dihasilkan oleh pengguna situs (seperti bujur/lintang atau "hari yang lalu") pada URL yang dirayapi dan diindeks:
  • example.com/find-a-doctor? radius=15&lintang=40,7565068&bujur=-73,9668408
  • example.com/article?category=health& hari yang lalu=7
Cara:
  • example.com/find-a-doctor? kota=san-francisco&lingkungan=soma
  • example.com/articles?category=health& tanggal=10-Januari-2014
Daripada mengizinkan pengguna menghasilkan nilai untuk membuat URL yang dapat dirayapi (yang menghasilkan kemungkinan tak terbatas dengan nilai yang sangat kecil bagi pengunjung), lebih baik mempublikasikan kategori halaman untuk nilai paling populer, selain itu Anda dapat menyertakan informasi tambahan sehingga halaman tersebut memberikan nilai lebih dibandingkan halaman hasil pencarian biasa. Alternatifnya, Anda dapat mempertimbangkan untuk menempatkan nilai yang dibuat pengguna di direktori terpisah, lalu menggunakan robots.txt untuk mencegah perayapan dari direktori tersebut.
  • contoh.com /penyaringan/ cari-dokter?radius=15&lintang=40.7565068&bujur=-73.9668408
  • contoh.com /penyaringan/ artikel?kategori=kesehatan&hari-hari yang lalu=7
Dan di robots.txt:
Agen pengguna: *
Melarang: /penyaringan/

Contoh No.4. Menambahkan parameter URL tanpa logika.

  • contoh.com /permen-gummy/lolipop/permen-gummy/ permen bergetah/produk?ikan swedia
  • contoh.com/product? kucing=permen bergetah&cat=lolipop&cat=permen bergetah&cat=permen bergetah&item=ikan swedia
Solusi yang bagus:
  • example.com /gummy-candy/ product?item=swedish-fish
Solusi terbaik:
  • contoh.com/product? item=ikan-swedia&kategori=permen bergetah
Parameter URL asing hanya meningkatkan duplikasi, menyebabkan situs dirayapi dan diindeks dengan kurang efisien. Oleh karena itu, penting untuk membuang parameter URL yang tidak perlu dan membersihkan tautan sampah secara berkala sebelum membuat URL baru. Jika banyak parameter diperlukan untuk sesi pengguna, Anda dapat menyembunyikan informasi di cookie daripada terus-menerus menambahkan nilai seperti kucing=permen bergetah&kucing=lolipop&cat=permen bergetah& ...

Contoh No.5: Menyarankan perbaikan lebih lanjut (pemfilteran) bila ada hasil nol.

Dengan buruk:
Izinkan pengguna memilih filter ketika ada item nol yang perlu disaring.


Klarifikasi ke halaman dengan hasil nol (misalnya, harga=lebih dari 10), yang membuat pengguna frustrasi dan menyebabkan permintaan yang tidak perlu ke mesin pencari.

Cara:
Buat tautan hanya jika ada elemen yang dapat dipilih pengguna. Jika hasilnya nol, tautan tersebut ditandai “abu-abu” (yaitu, tidak dapat diklik). Untuk lebih meningkatkan kegunaan, pertimbangkan untuk menyertakan indikator jumlah item yang tersedia di samping setiap filter.


Menampilkan halaman dengan hasil nol (misalnya, harga=di atas 10) tidak diperbolehkan, ditambah lagi pengguna dilarang melakukan klik yang tidak perlu, dan mesin pencari dilarang meng-crawl halaman yang tidak berguna ini.

Penting untuk mencegah munculnya alamat yang tidak perlu dan meminimalkan ruang bagi pengunjung dengan membuat URL hanya jika produk tersedia. Hal ini akan membantu menjaga pengguna tetap terlibat di situs Anda (lebih sedikit klik pada tombol kembali ketika tidak ada produk yang ditemukan) dan akan mengurangi jumlah kemungkinan URL yang diketahui mesin pencari. Selain itu, jika halaman tidak hanya "stok habis untuk sementara" namun kemungkinan besar tidak berisi informasi yang relevan, Anda mungkin ingin mempertimbangkan untuk memberikan kode respons 404. Pada halaman 404 Anda dapat membuat pesan yang bermanfaat untuk pengguna dengan sejumlah besar pilihan di navigasi atau kotak pencarian sehingga pengguna dapat menemukan produk terkait.

Untuk situs baru yang webmasternya mempertimbangkan penerapan navigasi segi, terdapat beberapa opsi untuk mengoptimalkan perayapan (kumpulan alamat di situs Anda yang diketahui Google) laman konten unik dan mengurangi laman duplikat agar tidak disertakan dalam indeks mesin telusur (konsolidasi sinyal pengindeksan).

Tentukan parameter URL apa yang diperlukan agar mesin telusur dapat merayapi setiap halaman konten (yaitu, menentukan parameter apa yang diperlukan untuk membuat setidaknya satu jalur klik ke setiap item). Parameter yang diperlukan dapat mencakup item-id , Category-id , page dll.

Tentukan parameter mana yang berguna bagi pengunjung dengan kueri mereka, dan mana yang cenderung menyebabkan duplikasi dalam perayapan dan pengindeksan. Dalam contoh kue-kue (marmalade), parameter URL "rasa" dapat bermanfaat bagi pengguna dengan kueri dalam contoh rasa = asam . Namun, masuk akal untuk menganggap parameter "harga" menyebabkan duplikasi yang tidak perlu kategori=permen bergetah&rasa=asam& harga=di atas-10 . Contoh umum lainnya:

  • Parameter berharga untuk mesin pencari: item-id , Category-id , name , brand ...
  • Parameter yang tidak diperlukan: session-id , price-range ...
Mari kita lihat penerapan salah satu dari beberapa opsi konfigurasi untuk URL yang berisi parameter yang tidak diperlukan. Pastikan saja bahwa parameter URL yang "tidak perlu" sebenarnya tidak diperlukan untuk dirayapi oleh perayap mesin telusur atau bagi pengguna untuk menemukan setiap produk!

Opsi 1: dan tautan internal

Tandai semua URL yang tidak perlu dengan . Hal ini akan mengurangi biaya tenaga kerja robot pencari dan mencegah penurunan frekuensi perayapan. Anda perlu mengelola pemindaian secara global melalui robots.txt (Catatan Penerjemah: lihat artikel " ").
Gunakan atribut rel="canonical" untuk memisahkan halaman indeks pencarian dari halaman yang tidak diperlukan di sana (misalnya pada halaman harga=5-10 Anda dapat menambahkan atribut rel="canonical" yang menunjukkan kategori semua selai asam example.com/category.php?category=gummy-candies&taste=sour& halaman=semua ).

Opsi 2: Robots.txt dan Larang

URL dengan parameter yang tidak perlu disertakan dalam direktori /filtering/, yang akan ditutup di robots.txt (dilarang). Ini akan memungkinkan semua mesin pencari untuk merayapi hanya tautan dalam (konten) situs yang “benar”, namun akan memblokir perayapan URL yang tidak diinginkan sekaligus. Misalnya ( example.com/category.php?category=gummy-candies), jika parameter berharganya adalah item, kategori, dan selera, serta pengidentifikasi sesi dan harga berlebihan, maka URL untuk selera akan menjadi seperti ini:
example.com/category.php?category=gummy-candies& rasa = asam, tetapi semua parameter yang tidak perlu, seperti harga, akan disertakan dalam URL di direktori yang telah ditentukan sebelumnya - /filtering/:
contoh.com /penyaringan/ kategori.php?category=permen-gummy&harga=5-10,
yang kemudian akan dilarang melalui robots.txt:
Agen pengguna: *
Larang: /filtering/

Opsi 3: Host Terpisah

Memastikan solusi terbaik, yang tercantum di atas (misalnya untuk alamat yang tidak diperlukan) masih berlaku. Jika tidak, mesin pencari telah membentuk banyak tautan dalam indeks. Oleh karena itu, pekerjaan Anda akan ditujukan untuk mengurangi pertumbuhan lebih lanjut pada laman yang tidak diperlukan yang dirayapi oleh Googlebot dan mengonsolidasikan sinyal pengindeksan.

Gunakan parameter dengan pengkodean standar dan format kunci=nilai.

Pastikan nilai yang tidak mengubah konten halaman, seperti ID sesi, diterapkan sebagai key=value, bukan direktori.

Jangan izinkan klik atau buat URL jika tidak ada elemen yang perlu difilter.

Tambahkan logika ke tampilan parameter URL: hapus parameter yang tidak perlu daripada terus-menerus menambahkan nilai (misalnya, hindari pembuatan tautan seperti ini: example.com/product?cat=gummy-candy&cat=lolipop &cat=gummy-candy&item=swedish-fish).

Pertahankan parameter berharga dalam URL dengan mencantumkannya terlebih dahulu (karena URL terlihat di hasil penelusuran) dan parameter yang kurang relevan terakhir (misalnya, ID sesi).
Hindari struktur tautan ini: contoh.com/category.php? id-sesi=123&id-pelacakan=456&category=permen bergetah&rasa=asam
Konfigurasikan parameter URL di Alat Webmaster jika Anda memiliki pemahaman yang jelas tentang cara kerja tautan di situs Anda.

Pastikan saat menggunakan JavaScript untuk memanipulasi konten secara dinamis (mengurutkan/memfilter/menyembunyikan) tanpa memperbarui URL, terdapat alamat web sebenarnya di situs Anda yang memiliki nilai penelusuran, seperti kategori utama dan laman produk, yang dapat dirayapi dan diindeks . Usahakan jangan hanya menggunakan saja halaman rumah(yaitu satu URL) untuk keseluruhan situs Anda, dan menggunakan JavaScript untuk mengubah konten secara dinamis dengan navigasi - sayangnya, hal ini hanya akan memberi pengguna satu URL dalam penelusuran. Selain itu, periksa apakah tidak ada dampak kinerja pada pemfilteran dinamis sisi terburuknya, karena akan mencegah pengguna bekerja dengan situs tersebut.

Tingkatkan pengindeksan halaman berbeda dari konten yang sama dengan menentukan atribut rel="canonical" pada versi halaman yang diistimewakan. Atribut rel="canonical" dapat digunakan dalam satu atau beberapa domain.

Optimalkan pengindeksan konten yang diberi nomor halaman (misalnya, halaman=1 dan halaman=2 dari kategori "permen bergetah") dengan:

  • Tambahkan atribut rel="canonical" ke serangkaian halaman yang menunjukkan kategori kanonik dengan parameter “lihat semua” (misalnya, halaman=1, halaman=2, dan halaman=3 dari kategori “permen bergetah” dengan dengan rel=”kanonik” aktif kategori=permen bergetah&halaman=semua), memastikan halaman relevan bagi pengguna dan dimuat dengan cepat.
  • Gunakan markup penomoran halaman rel="next" dan rel="prev" untuk menunjukkan hubungan antar halaman individual (lihat "Paginaton dengan rel="next" dan rel="prev" ").
Hanya sertakan tautan kanonik di peta situs Anda.

Untuk setiap posting dan posting wordpress pengguna dapat menentukan satu atau lebih judul (kategori). Fitur ini memungkinkan Anda mengelompokkan postingan yang memiliki kesamaan makna dan memberikan kesempatan kepada pengunjung untuk membaca dan melihat hanya bagian yang mereka sukai. Misalnya, ketika saya membuat blog utama saya, Tod's Blog, saya akan menulis tentang semua nuansa Internet - mulai dari desain hingga pemrograman. Katakanlah seseorang membuka artikel tentang Wordpress dari mesin pencari dan ingin membaca lebih banyak tentang sistem - dia harus mengobrak-abrik arsip, menggunakan kembali pencarian, atau melihat semua posting secara berurutan. Tentu saja, semua ini bisa dihindari dengan masuk ke kategori khusus yang disebut wordpress. Atau misalnya bagi yang hanya tertarik pada desain, bagian blog mungkin bisa menarik.

Jika diperhatikan lebih dekat pada header blog, Anda akan melihat semacam menu dimana kategori wordpress bertindak sebagai bagian dari proyek. Bagi saya, ini adalah cara yang cukup nyaman dan visual untuk memisahkan topik entri.

Di tengah halaman Anda akan melihat formulir untuk menambahkan kategori baru. Di sini Anda perlu menunjukkan namanya (nama), label (bagian tautan url untuk CNC), kategori induk (jika ada), dan Anda juga dapat mengaturnya deskripsi singkat. Kategori induk memungkinkan Anda membuat bagian di WordPress dengan beberapa tingkat sarang - misalnya, untuk kategori “WordPress” di beberapa blog TI, Anda dapat menambahkan templat, plugin, dll.

Di sisi kanan halaman Kategori, semua kategori WordPress ditampilkan, dengan kemampuan untuk mengedit atau menghapus. Untuk melakukan tindakan, cukup gerakkan kursor mouse ke atas nama kategori tertentu, setelah itu Anda akan melihat menu pop-up kecil.

Saat mengedit, Anda akan melihat salah satu blok informasi tempat Anda dapat memilih satu atau lebih kategori untuk artikel tersebut. Cukup centang kotak di sebelah nama yang Anda inginkan.

Di sini Anda dapat menambahkan kategori baru dengan mengklik link yang sesuai. Satu-satunya kelemahan dari mekanisme ini adalah ketika membuat, Anda hanya dapat menentukan nama dan kategori induk, sedangkan untuk mengatur bidang label Anda harus pergi ke bagian “Kategori” dan mengedit informasi di sana.

Selain itu, Anda dapat mengedit kategori postingan blog melalui daftarnya di menu Postingan – Edit. Di sana, saat Anda mengarahkan kursor ke publikasi tertentu, Anda akan melihat tautan “ Sunting Cepat" Klik di atasnya dan lihat formulir untuk diedit:

Di sini Anda dapat mengubah kategori, tag, dan semua informasi tambahan pada artikel. Masalahnya sangat nyaman + berfungsi tanpa memuat ulang halaman.

fungsi wp_list_categories untuk kategori wordpress

Secara tradisional, saya tidak hanya mempertimbangkan masalah bekerja dengan elemen tertentu dari sistem, tetapi juga menyediakan fungsi khusus untuk templat. Seperti yang saya bicarakan. Jadi, untuk menampilkan daftar kategori dengan tautan ke kategori tersebut, gunakan wp_list_categories. Ini memiliki sejumlah argumen:

  • show_option_all – menampilkan link ke semua kategori jika Anda telah memilih daftar sebagai gaya tampilan.
  • orderby – mengurutkan kategori berdasarkan ID, nama (name), label (slug), jumlah postingan (count).
  • urutan – urutan pengurutan (ASC – meningkat, DESC – menurun).
  • show_last_updated – menampilkan tanggal pembaruan terakhir.
  • gaya – gaya desain: daftar, pembagian melalui
    (tidak ada).
  • show_count – menampilkan jumlah postingan dalam kategori.
  • hide_empty – menyembunyikan kategori kosong tanpa postingan.
  • use_desc_for_title – gunakan deskripsi untuk atribut title di link.
  • child_of – hanya menampilkan kategori untuk kategori induk tertentu.
  • feed – menampilkan link ke feed untuk kategori.
  • feed_type – jenis umpan.
  • feed_image – gambar untuk ikon rss.
  • kecualikan – mengecualikan kategori dari daftar, dan parameter child_of secara otomatis dinonaktifkan.
  • kecualikan_pohon – mengecualikan seluruh cabang kategori.
  • include adalah parameter kebalikan yang hanya menyertakan kategori WordPress tertentu dalam daftar.
  • hierarki – parameter untuk menampilkan subkategori.
  • title_li – judul daftar kategori.
  • number – jumlah kategori yang akan ditampilkan (jika terlalu banyak).
  • echo – menampilkan kategori, defaultnya adalah True.
  • depth – menentukan jumlah level subkategori yang akan ditampilkan.

Terakhir, saya akan memberikan beberapa contoh penggunaan wp_list_categories. Pertama, pilihan dari header blog ini.

"hide_empty=1&exclude=1&title_li=&orderby=count&order=desc&use_desc_for_title=0") ; ?>

Di sini diatur untuk menampilkan kategori tersembunyi, mengecualikan kategori dari daftar, baris kosong untuk judul blok, mengurutkan berdasarkan jumlah artikel dan mengurangi urutan (yaitu, saya memiliki artikel terbanyak di bagian tersebut). Argumen terakhir tidak menggantikan deskripsi kategori ke dalam judul link.

Nah, dan beberapa situasi sederhana lainnya. Menggunakan pengecualian dan penyertaan kategori.

Jika Anda memiliki sesuatu untuk ditambahkan tentang judul dan kategori WordPress, tulis di komentar.

Memperbarui: Anda mungkin juga memerlukan sedikit peretasan untuk melakukannya. Di WordPress, secara default, teks judul ditentukan, seperti "lihat semua entri dalam kategori ....", Anda dapat meninggalkan judul kategori - baca artikel di tautan di atas.

Mengembalikan array objek yang berisi informasi tentang kategori.

Parameter yang diteruskan ke fungsi ini sangat mirip dengan parameter yang diteruskan ke fungsi tersebut wp_list_categories() dan dapat diteruskan baik sebagai array atau sebagai string kueri: type=post&order=DESC .

✈ 1 kali = 0,005625 detik = sangat lambat| 50.000 kali = 11,98 detik = perlahan-lahan| PHP 7.1.11, WP 4.9.5

Penggunaan

$kategori = get_categories($args);

Pola penggunaan

$categories = get_categories(array("taxonomy" => "category", "type" => "post", "child_of" => 0, "parent" => "", "orderby" => "name", " order" => "ASC", "hide_empty" => 1, "hierarchical" => 1, "exclude" => "", "include" => "", "number" => 0, "pad_counts" => PALSU, // daftar lengkap Untuk parameter, lihat deskripsi fungsi http://wp-kama.ru/function/get_terms)); if($categories)( foreach($categories as $cat)( // Data pada objek $cat // $cat->term_id // $cat->name (Rubrik 1) // $cat->slug (rubrika - 1) // $cat->term_group (0) // $cat->term_taxonomy_id (4) // $cat->taxonomy (kategori) // $cat->description (Teks deskripsi) // $cat-> induk (0) // $cat->count (14) // $cat->object_id (2743) // $cat->cat_ID (4) // $cat->category_count (14) // $cat-> kategori_deskripsi (Teks deskripsi) // $cat->cat_name (Rubrik 1) // $cat->category_nicename (rubrika-1) // $cat->category_parent (0) ) ) taksonomi (garis) Nama taksonomi yang akan diproses. Ditambahkan sejak versi 3.0.
Bawaan: "kategori" jenis (garis)
  • posting - kategori untuk posting (default);
  • tautan - bagian tautan.
    Bawaan: "postingan"
anak_dari (garis) Dapatkan kategori anak (termasuk semua level bersarang) dari kategori yang ditentukan. Parameter menentukan ID kategori induk (kategori yang kategori bertingkatnya ingin Anda tampilkan). induk(nomor)
Mendapatkan kategori yang kategori induknya sama dengan ID yang ditentukan dalam parameter. Perbedaan dari child_of adalah satu level nesting akan ditampilkan. Bawaan: "" (garis)

dipesan oleh

  • Menyortir data yang diterima menurut kriteria tertentu. Misalnya berdasarkan jumlah postingan di setiap kategori atau berdasarkan nama kategori. Kriteria berikut tersedia:
  • ID - urutkan berdasarkan ID;
  • nama - urutkan berdasarkan nama (default);
  • siput - urutkan berdasarkan alt. nama (siput);
  • hitung - berdasarkan jumlah entri dalam kategori;

term_group - berdasarkan grup.

Bawaan: "nama" (garis)

Memesan

  • Arah penyortiran yang ditentukan dalam parameter "orderby":
  • ASC - berurutan, dari terkecil hingga terbesar (1, 2, 3; a, b, c); DESC - masuk urutan terbalik

, dari yang terbesar ke yang terkecil (3, 2, 1; c, b, a).

Bawaan: "ASC" Sembunyikan_kosong

(logis)

  • Apakah akan menerima kategori kosong atau tidak (tidak memiliki entri):
  • 1 (benar) - jangan terima yang kosong,

0 (salah) - terima yang kosong.

Bawaan: benar Sembunyikan_kosong Hierarki Jika parameter disetel ke BENAR
0 (salah) - terima yang kosong., maka hasilnya akan menyertakan kategori anak kosong yang kategori anaknya memiliki entri (tidak kosong). mengecualikan(string/array)
Mendapatkan kategori yang kategori induknya sama dengan ID yang ditentukan dalam parameter. Perbedaan dari child_of adalah satu level nesting akan ditampilkan. Kecualikan kategori apa pun dari daftar. Anda harus menentukan ID kategori yang dipisahkan dengan koma atau dalam array. Jika parameter ini ditentukan, parameter child_of akan diganti. mengecualikan termasuk
Mendapatkan kategori yang kategori induknya sama dengan ID yang ditentukan dalam parameter. Perbedaan dari child_of adalah satu level nesting akan ditampilkan. Cantumkan hanya kategori yang ditentukan. Anda perlu menentukan ID kategori yang dipisahkan dengan koma atau dalam array. induk Membatasi. Jumlah kategori yang akan diambil. Secara default, tidak ada batasan - semua kategori akan diambil. Sembunyikan_kosong pad_counts
Jika Anda lulus benar, maka angka yang menunjukkan jumlah postingan di kategori induk akan menjadi jumlah postingannya dan postingan dari kategori anak.

Bawaan: salah

Contoh

Daftar tarik-turun #1

Untuk membuat daftar drop-down kategori, kita dapat menggunakan fungsi lain yang khusus untuk tujuan ini, wp_dropdown_categories() :

Wp_dropdown_categories(array("hide_empty" => 0, "name" => "category_parent", "orderby" => "name", "selected" => $category->parent, "hierarchical" => true, "show_option_none" => __("Tidak ada")));

namun, dengan pendekatan ini kita akan kehilangan fleksibilitas dalam menyiapkan daftar, karena kita akan menerima daftar yang sudah lengkap. Oleh karena itu, dalam beberapa kasus akan lebih logis untuk membuat daftar drop-down menggunakan fungsi tersebut dapatkan_kategori()

"; gema $pilihan; ) ?>

#2 Daftar kategori dan deskripsinya

Contoh ini akan menunjukkan kepada kita bagaimana kita dapat menampilkan daftar link ke kategori, dimana segera setelah setiap link akan ada deskripsi kategori (ditentukan saat membuat/mengedit kategori):

"nama", "pesanan" => "ASC")); foreach($kategori sebagai $kategori)( echo " Kategori:

term_id) . "" judul="" . sprintf(__("Lihat semua posting di %s"), $category->name) . "" " . ">" .$kategori->nama."

"; gema"

Deskripsi:". $kategori->deskripsi . "

"; gema"

"; } ?>

Jumlah Postingan: ". $category->count ."

  • Catatan

Lihat: get_terms() Jenis argumen yang dapat diubah.

Daftar perubahan Dari versi 2.1.0

Diperkenalkan. Kode dapatkan kategori: wp-include/category.php

WP 5.3.2 "kategori"); $args = wp_parse_args($args, $default);", "/** * Memfilter taksonomi yang digunakan untuk mengambil istilah saat memanggil get_categories().")); $args["taxonomy"] = "link_category"; ) $categories = get_terms($args); if (is_wp_error($categories)) ( $categories = array(); ) else ( $categories = (array ) $kategori; foreach (array_keys($kategori) sebagai $k) ( _make_cat_compat($kategori[ $k ]); ) ) mengembalikan $kategori;

Saya mulai menulis kelas yang akan mengimplementasikan ide-ide yang diuraikan di dalamnya.
Lebih tepatnya, karena fungsionalitas utama sudah digunakan dalam kerangka kerja, saya mulai memisahkannya ke dalam kelas terpisah. Saya ingin menggunakan kesempatan ini untuk mengucapkan terima kasih kepada anggota PHPClub atas bantuan mereka dalam memperbaiki beberapa kesalahan kritis dan komentar yang berguna. Di bawah ini saya akan mencoba menjelaskan fitur-fitur utamanya, tetapi pertama-tama sedikit

penafian

Ada beberapa cara untuk bekerja dengan SQL - Anda bisa menggunakan pembuat kueri, Anda bisa menggunakan ORM, Anda bisa bekerja dengan SQL murni. Saya memilih opsi terakhir karena lebih dekat dengan saya. Menurut saya dua yang pertama tidak buruk sama sekali. Hanya saja saya pribadi selalu merasa terkekang dalam kerangka mereka. Tapi saya sama sekali tidak mengklaim bahwa versi saya lebih baik. Itu hanyalah pilihan lain. Yang dapat digunakan antara lain saat menulis ORM. Bagaimanapun, saya percaya bahwa memiliki cara yang aman untuk bekerja dengan SQL murni tidak akan merugikan. Namun pada saat yang sama, ini mungkin membantu para penganut penggunaan mysql_* dalam kode aplikasi untuk akhirnya meninggalkan praktik buruk ini.


Singkatnya, kelas ini dibangun berdasarkan sekumpulan fungsi pembantu yang memungkinkan Anda melakukan sebagian besar operasi database dalam satu baris, sambil menyediakan (tidak seperti API standar) penuh perlindungan terhadap injeksi SQL, diimplementasikan menggunakan serangkaian placeholder yang diperluas yang melindungi semua jenis data yang mungkin diminta.
Kelas ini didasarkan pada tiga prinsip dasar:
  1. Perlindungan 100% terhadap injeksi SQL
  2. Pada saat yang sama, perlindungannya sangat nyaman digunakan, membuat kode menjadi lebih pendek daripada panjang
  3. Fleksibilitas, portabilitas dan kemudahan belajar
Saya akan membahas lebih detail masing-masing poin.

Keamanan

dijamin oleh dua aturan yang saya rumuskan dalam artikel:
  1. Setiap- tidak ada pengecualian! - elemen dinamis disertakan dalam permintaan hanya melalui placeholder.
  2. Segala sesuatu yang tidak dapat digantikan melalui placeholder dijalankan terlebih dahulu melalui daftar putih.
Sayangnya, perpustakaan standar tidak memberikan perlindungan penuh terhadap injeksi, hanya melindungi string dan angka menggunakan pernyataan yang telah disiapkan.
Oleh karena itu, untuk melengkapi perlindungan, kami harus meninggalkan konsep pernyataan siap pakai yang jelas-jelas terbatas dan memilih konsep yang lebih luas - placeholder. Selain itu, placeholder yang diketik (kita semua mengetahui hal ini dari rangkaian fungsi printf(): %d adalah placeholder yang memberi tahu parser cara memproses nilai yang diganti, dalam hal ini - sebagai bilangan bulat). Inovasi tersebut ternyata sangat sukses sehingga segera memecahkan banyak masalah dan menyederhanakan kode secara signifikan. Saya akan menulis lebih banyak tentang placeholder yang diketik di bawah.
Dukungan untuk pemfilteran berdasarkan daftar putih disediakan oleh dua fungsi, agak dibuat-buat, namun tetap diperlukan.

Kenyamanan dan singkatnya kode aplikasi

Di sini, placeholder yang diketik juga banyak membantu saya, yang memungkinkan saya melakukan panggilan fungsi satu baris, meneruskan permintaan dan datanya sekaligus. Ditambah satu set pembantu yang mengingatkan pada PEAR::DB - fungsi yang segera mengembalikan hasil dari tipe yang diinginkan. Semua pembantu diatur menurut skema yang sama: satu parameter wajib diteruskan ke fungsi - permintaan dengan placeholder, dan parameter opsional sebanyak yang diinginkan, jumlah dan urutannya harus sesuai dengan jumlah dan urutan placeholder dalam permintaan . Fungsi keluarga Ind menggunakan satu lagi parameter wajib - nama bidang yang digunakan untuk mengindeks array yang dikembalikan.
Berdasarkan pengalaman saya, saya sampai pada kumpulan nilai pengembalian berikut (dan, sebagai hasilnya, pembantu):
  • query() - mengembalikan sumber daya mysqli. Dapat digunakan secara tradisional, dengan mengambil(), dll.
  • getOne() - mengembalikan skalar, elemen pertama dari baris pertama hasil
  • getRow() - array satu dimensi, baris pertama dari hasilnya
  • getCol() - array skalar satu dimensi - kolom tabel
  • getAll() - array dua dimensi yang diindeks berdasarkan angka secara berurutan
  • getInd() - array dua dimensi yang diindeks oleh nilai bidang yang ditentukan oleh parameter pertama
  • getIndCol() adalah larik skalar yang diindeks berdasarkan bidang dari parameter pertama. Sangat diperlukan untuk menyusun kamus seperti key => value
Akibatnya, sebagian besar panggilan ke database dikurangi menjadi satu atau dua konstruksi baris (bukan 5-10 dengan pendekatan tradisional):
$data = $db->getAll("PILIH * DARI ?n DI MANA mod=?s LIMIT ?i",$tabel,$mod,$batas);
Kode ini hanya berisi elemen yang diperlukan dan bermakna, tetapi tidak ada yang berlebihan dan berulang. Semua jeroan ayam itik tersembunyi dengan rapi di dalam kelas: helper getAll() memungkinkan Anda untuk segera mendapatkan hasil yang diinginkan tanpa menulis loop dalam kode aplikasi, dan placeholder yang diketik memungkinkan dengan aman tambahkan elemen dinamis ke permintaan setiap mengetik tanpa menentukan binding secara manual (bind_param). Kode KERING ekstra! Dalam kasus penggunaan placeholder ?a dan ?u, perbedaan jumlah kode menjadi lebih besar:
$data = $db->getAll("PILIH * DARI tabel WHERE kategori IN (?a)",$ids);

Fleksibilitas dan kemudahan belajar

berdiri di atas tiga pilar:
  1. Sangat API kecil - setengah lusin placeholder dan jumlah pembantu yang sama.
  2. Kami bekerja dengan SQL lama yang bagus, yang tidak perlu dipelajari kembali.
  3. Fungsi parse() yang tampaknya tidak terlalu mencolok namun sangat berguna pada awalnya ditujukan hanya untuk debugging, namun akhirnya berkembang menjadi elemen kunci saat menulis kueri yang kompleks.
Hasilnya, semua kueri kompleks dirangkai dengan cara lama - misalnya, dalam satu lingkaran - tetapi pada saat yang sama mematuhi semua aturan keselamatan!
Izinkan saya memberi Anda sebuah contoh kecil (contoh yang lebih kompleks dapat ditemukan dalam dokumentasi pada tautan di bagian bawah artikel):
Kasus yang cukup umum ketika kita perlu menambahkan kondisi ke kueri jika ada variabel

$sqlbagian = ""; if (!empty($var)) ( $sqlpart = $db->parse(" AND field = ?s", $var); ) $data = $db->getAll("SELECT * FROM table WHERE a=? saya ?p", $id, $sqlpart);
Penting untuk mencatat beberapa hal di sini.
Pertama, karena kami tidak terikat oleh API asli, tidak ada yang melarang kami untuk mengurai tidak seluruh permintaan, tetapi hanya sebagian saja. Hal ini ternyata sangat nyaman untuk kueri yang disusun berdasarkan logika tertentu: kami hanya mengurai sebagian permintaan, lalu menggantinya ke permintaan utama melalui placeholder "idle" khusus untuk menghindari penguraian berulang (dan untuk mematuhi dengan aturan “setiap elemen diganti hanya melalui placeholder”).
Namun sayangnya, inilah titik lemah seluruh kelas. Tidak seperti semua placeholder lainnya (yang, meskipun digunakan secara tidak benar, tidak akan pernah menghasilkan suntikan), penggunaan placeholder?p yang salah dapat menyebabkannya.
Namun, pengamanan yang sangat mudah akan sangat mempersulit kelas, namun tetap tidak melindungi terhadap penyisipan variabel yang bodoh ke dalam string kueri. Jadi saya memutuskan untuk membiarkannya apa adanya. Namun jika Anda mengetahui cara untuk memecahkan masalah ini tanpa terlalu banyak rekayasa berlebihan, saya akan berterima kasih atas idenya.

Namun, pada akhirnya kami mendapatkan generator kueri yang kuat dan ringan yang lebih dari sekadar membenarkan kelemahan kecil ini.
Kuat karena kita tidak terbatas pada sintaks pembuat kueri, “SQL ditulis dalam PHP” - kita menulis SQL murni.
Mudah karena seluruh API pembuatan kueri terdiri dari setengah lusin placeholder dan fungsi parse()
Ini adalah contoh favorit saya - masukkan menggunakan fungsi Mysql
$data = array("bidang"=>$nilai,"bidang2"=>$nilai); $sql = "MASUKKAN KE dalam tabel SET ts=unix_timestamp(), ip=inet_aton(?s),?u"; $db->kueri($sql, $ip, $data);
Di satu sisi, kami mempertahankan sintaks SQL, di sisi lain, kami membuatnya aman, dan di sisi ketiga, kami mengurangi jumlah kode secara drastis.

Lebih lanjut tentang placeholder yang diketik

Pertama, mari kita jawab pertanyaannya, mengapa ada placeholder?
Ini, secara umum, sudah menjadi hal yang lumrah, namun demikian, saya ulangi - data dinamis apa pun harus disertakan dalam permintaan hanya melalui placeholder karena alasan berikut:
  • yang terpenting adalah keselamatan. Dengan menambahkan variabel melalui placeholder, kita dapat yakin bahwa variabel tersebut akan diformat dengan benar.
  • pemformatan lokal. Ini adalah poin yang sama pentingnya. Pertama, data diformat segera sebelum memasukkan permintaan, dan tidak mempengaruhi variabel asli, yang kemudian dapat digunakan di tempat lain. Kedua, data diformat tepat di tempat yang diperlukan, dan bukan sebelum skrip mulai berjalan, seperti kutipan ajaib, dan bukan di sepuluh tempat yang memungkinkan dalam kode oleh beberapa pengembang, yang masing-masing dapat mengandalkan satu sama lain.
Dengan mengembangkan konsep ini lebih lanjut, kami sampai pada gagasan bahwa paceholder haruslah ada diketik. Tapi kenapa?
Disini saya ingin berhenti sejenak dan menelusuri sejarah perkembangan pemikiran programmer di bidang proteksi injeksi.
Awalnya terjadi kekacauan - tidak ada perlindungan sama sekali, kami mendorong semuanya apa adanya.
Kemudian tidak menjadi lebih baik, dengan paradigma “mari kita pulihkan semua yang masuk ke dalam skrip dari pengguna” dan puncaknya dalam bentuk kutipan ajaib.
Kemudian para pemikir terbaik sampai pada kesimpulan bahwa berbicara bukan tentang penyaringan, tetapi tentang pemformatan adalah hal yang benar. Karena pemformatan tidak selalu bermuara pada satu tata letak saja. Ini adalah bagaimana metode quote() muncul di PDO, yang melakukan pemformatan lengkap sebuah string - tidak hanya meloloskan karakter khusus di dalamnya, tetapi juga mengapitnya dalam tanda kutip, tanpa bergantung pada pemrogram. Akibatnya, bahkan jika pemrogram menggunakan fungsi ini di tempat yang salah (misalnya, untuk nomor), injeksi tetap tidak berfungsi (dan dalam kasus pelolosan telanjang melalui mysql_real_escape_string, fungsi tersebut akan lolos dengan mudah jika kita memasukkan nomor ke dalam kueri tanpa menyertakannya dalam tanda kutip). Saat digunakan untuk memformat pengenal, fungsi ini menyebabkan kesalahan pada tahap pengembangan, yang memberi kesan kepada pembuat kode bahwa dia sedikit salah.
Sayangnya, penulis PDO berhenti di situ, karena gagasan bahwa hanya string yang perlu diformat dalam kueri masih melekat kuat di benak para pengembang. Namun nyatanya, permintaan tersebut mengandung lebih banyak elemen dari berbagai jenis. Dan masing-masing memerlukan jenis pemformatannya sendiri! Artinya, satu-satunya metode quote() tidak cocok untuk kita - kita memerlukan banyak kutipan berbeda. Dan bukan sebagai pengecualian, “inilah quoteName()”, tetapi sebagai salah satu konsep utama: setiap jenis memiliki formatnya sendiri. Karena ada banyak jenis pemformatan, jenisnya harus ditunjukkan. Dan placeholder yang diketik paling cocok untuk ini.

Selain itu, placeholder yang diketik SANGAT nyaman!
Pertama, karena operator khusus untuk mengikat nilai ke placeholder menjadi tidak diperlukan (tetapi masih memungkinkan untuk menentukan jenis nilai yang diteruskan!)
Kedua, karena kita telah menemukan placeholder yang diketik, kita dapat menempelkan sejumlah besar placeholder ini untuk menyelesaikan banyak tugas rutin penulisan kueri SQL.
Pertama-tama, kami akan membuat placeholder untuk pengidentifikasi - kami sangat merindukannya dalam kehidupan nyata, bukan imajinasi penulis API standar. Segera setelah pengembang dihadapkan pada kebutuhan untuk secara dinamis menambahkan nama bidang ke permintaan, semua orang mulai memutarbalikkan dengan caranya sendiri, ada yang ke hutan, ada yang ke kayu bakar. Di sini semuanya disatukan dengan elemen permintaan lainnya, dan menambahkan pengidentifikasi tidak lebih sulit daripada menambahkan string. Tetapi pada saat yang sama, pengidentifikasi diformat bukan sebagai string, tetapi sesuai dengan aturannya sendiri - ia diapit oleh tanda kutip belakang, dan di dalam tanda kutip ini di-escape dengan menggandakan.
Lebih-lebih lagi. Sakit kepala berikutnya bagi pengembang mana pun yang pernah mencoba menggunakan pernyataan standar yang disiapkan dalam kehidupan nyata adalah operator IN(). Voila, kami juga memiliki pengganti untuk operasi ini! Substitusi array menjadi tidak lebih sulit daripada elemen lainnya, ditambah lagi bersatu dengan mereka tidak ada fungsi terpisah, hanya huruf di placeholder yang berubah.
Kami membuat placeholder untuk SET dengan cara yang persis sama. Saya tidak dapat menahan diri untuk tidak menunjukkan betapa sederhananya kode tersebut untuk kueri yang membingungkan seperti INSERT... ON DUPLICATE:
$data = array("penawaran_masuk" => $masuk, "penawaran_keluar" => $keluar); $sql = "MASUKKAN KE DALAM statistik SET pid=?i,dt=CURDATE(),?u PADA UPDATE KUNCI DUPLIKAT ?u"; $db->query($sql,$pid,$data,$data);
Saat ini kelas mendukung 6 jenis placeholder

  • ?s (“string”) - string (serta DATE, FLOAT, dan DECIMAL).
  • ?i (“bilangan bulat”) - bilangan bulat.
  • ?n (“nama”) - nama bidang dan tabel
  • ?p (“diurai”) - untuk memasukkan bagian permintaan yang sudah diproses
  • ?a (“array”) - sekumpulan nilai untuk IN (string seperti “a”,”b”,”c”)
  • ?u (“perbarui”) - sekumpulan nilai untuk SET (string seperti `field`="value", `field`="value")
Ini cukup untuk tugas saya, tetapi himpunan ini selalu dapat diperluas dengan placeholder lainnya, misalnya, untuk bilangan pecahan. Saya tidak melihat gunanya membuat placeholder terpisah untuk NULL - itu selalu dapat disertakan langsung dalam permintaan.
Saya memutuskan untuk tidak menerjemahkan PHP NULL secara otomatis ke SQL NULL. Mungkin ini akan sedikit memperumit kode (dalam kasus yang jarang terjadi ketika hal ini diperlukan), tetapi ini akan mengurangi ambiguitasnya.

Omong-omong, seperti yang mungkin telah diketahui banyak orang, kelas ini dalam banyak hal mengingatkan pada perpustakaan DbSimple milik Dmitry Koterov. Namun saya mempunyai perbedaan mendasar dengan beberapa gagasan yang terkandung di dalamnya.
Pertama, saya menentang keajaiban apa pun ketika fungsi yang sama dapat memberikan hasil yang berbeda tergantung pada jenis data yang diteruskan. Hal ini mungkin membuat penulisan sedikit lebih mudah, namun juga membuat pemeliharaan dan debugging kode menjadi sangat sulit. Oleh karena itu, di kelas saya, semua keajaiban dijaga seminimal mungkin, dan semua operasi dan tipe data selalu ditulis secara eksplisit.
Kedua, menurut saya, DbSimple memiliki sintaks yang sedikit rumit. Di satu sisi, kurung kurawal adalah ide cemerlang. Di sisi lain, mengapa kita harus melakukannya, jika kita memiliki semua kekuatan PHP yang kita miliki? Oleh karena itu, saya memutuskan untuk mengambil jalan lain dan memperkenalkan logika "eksternal", yang hanya dibatasi oleh sintaks PHP, bukan logika "internal" - yang jelas-jelas terbatas. Hal utama adalah bahwa setiap elemen dinamis masuk ke permintaan hanya melalui placeholder, dan sisanya hanya bergantung pada imajinasi pengembang (dan fungsi parse()).

Kode kelas tersedia di Github, github.com/colshrapnel/safemysql/blob/master/safemysql.class.php
Lembar contekan dengan perintah dasar dan contoh: phpfaq.ru/misc/safemysql_cheatsheet_ru.pdf
Ide bagus tentang kemungkinan dapat diperoleh di halaman contoh dokumentasi (sayangnya, belum selesai), phpfaq.ru/safemysql
Ada juga jawaban atas pertanyaan umum, seperti “mengapa Anda tidak menggunakan pernyataan asli?” dll.
Namun, saya akan dengan senang hati menjawab pertanyaan apa pun di komentar, serta meningkatkan kelas itu sendiri dan artikel ini berdasarkan komentar Anda.