Безнадежный category php. PHP Категории (Дерево категорий). #2 Список категорий и их описание

  • 03.11.2019

Проверяет принадлежит ли текущий (или указанный) пост к указанной категории (можно указать несколько категорий). Условный тег.

Проверяется прямая принадлежность поста к категории, т.е. содержит ли указанная категория текущий/указанный пост. Если, например, пост принадлежит родительской категории или дочерней к указанной, то функция вернет false.

Чтобы проверить отношение поста к дереву категорий используйте самописную функцию post_is_in_descendant_category() (см. пример ниже).

in_category() можно использовать внутри Цикла WordPress или за пределами Цикла WordPress, но на отдельной странице поста (single.php). Или можно использовать где угодно, если указать какой именно пост нужно проверить.

✈ 1 раз = 0.003672с = очень медленно | 50000 раз = 1.00с = очень быстро | PHP 7.1.5, WP 4.8.1

Хуков нет.

Возвращает

true, если условие выполняется и false, если нет.

Использование if(in_category($category, $post)){ // ... } $category(строка/массив/число) (обязательный)

ID, название или ярлык (slug) категории, которую нужно проверить принадлежит ли ей пост.

Можно указать несколько параметров в массиве вперемешку.
По умолчанию: нет

$post(число/объект) ID или объект поста. По умолчанию текущий пост определяется автоматически внутри Цикла WordPress или на странице поста.
По умолчанию: нет

Примеры #1 Проверка текущего поста внутри Цикла WordPress.

in_category часто используется внутри Цикла, чтобы проверить относится ли пост к указанной категории, если "да", то сделать какие-либо действия:

If (in_category("pachyderms")) { // действия, если пост относится к категории "pachyderms" } elseif (in_category(array("Tropical Birds", "small-mammals"))) { // действия, если пост относится к одной из категорий "Tropical Birds", "small-mammals" } else { // если никакие из предыдущих условий не выполнены. }

П.С. Лучше указывать не названия, а ID категории для проверок

#2 Проверка текущего поста за пределами Цикла.

На странице поста (обычно это файл шаблона single.php) проверку можно выполнять за пределами Цикла:

If (in_category("fruit")) { include "single-fruit.php"; } elseif (in_category("vegetables")) { include "single-vegetables.php"; } else { // Ниже начинается Цикл WordPress if (have_posts()) : while (have_posts()) : the_post(); // ... }

#3 Проверка принадлежности поста к текущей или вложенной в текущую категории

Бывают случаи, когда нужно проверить относиться ли пост к дереву категорий. Например, мы указываем в проверке ID категории 60, а пост принадлежит категории 70, которая является дочерней к категории 60. Но in_category() вернет в данном случае false, а иногда нужно чтобы вернула true.

Для того, чтобы проверить принадлежность к дереву категорий, можно последовательно указать в массиве все названия категорий:

If(in_category(array("Малина", "Яблоки", "Бананы", "Груши", "Сливы"))) { // Действие если выполнено условие }

Такой подход проверки, совершенно не гибкий, потому что если мы добавим новую подкатегорию к категории "Фрукты", нам так же нужно будет добавить её и в массив, для проверки.

Чтобы избежать таких сложностей можно воспользоваться такой проверкой:

// Проверка принадлежности поста к категории "Фрукты" или любой вложенной в эту категорию категории. if (in_category(11) || post_is_in_descendant_category(11)) { // Здесь все "фрукты" }

Также, менее желательный, но вариант - указать названия:

Post_is_in_descendant_category(get_term_by("name", "fruit", "category"))

А вот сама функция post_is_in_descendant_category() :

Function post_is_in_descendant_category($cats, $_post = null){ foreach ((array) $cats as $cat) { // get_term_children() accepts integer ID only $descendants = get_term_children((int) $cat, "category"); if($descendants && in_category($descendants, $_post)) return true; } return false; }

#4 Древовидная проверка принадлежности к термину

Проверим входит ли пост в термин произвольной таксономии (будем проверять и дочерние термины к указанному):

If(has_term(11, "taxonomy", $post->ID) || post_is_in_descendant_term(11, "taxonomy", $post->ID)){ // Текущая запись в термине 11 или в его дочернем термине }

Функция post_is_in_descendant_term() :

Function post_is_in_descendant_term($term_ids, $taxonomy = "category", $post = null){ foreach((array) $term_ids as $term_id){ $descendants = get_term_children((int) $term_id, $taxonomy); if ($descendants && has_term($descendants, $taxonomy , $post)) return true; } return false; }

Решил написать эту заметку, потому как надоело отвечать 100500 раз одно и то же на ВиО.

Многие начинающие веб-программисты рано или поздно сталкиваются с задачей внедрения в свой сайт человеко-понятных линков (ЧПУ). До внедрения ЧПУ все ссылки имеют вид /myscript.php или даже /myfolder/myfolder2/myscript3.php, что тяжело для запоминания и ещё хуже для SEO. После внедрения ЧПУ линки принимают вид /statiya-o-php или даже на кириллице /статья-о-пхп.

Кстати о SEO. Человекопонятные линки на САМОМ деле придумали не для удобного запоминания, а в основном для повышения индексируемости сайта, потому что совпадение поискового запроса и части URL даёт хорошее преимущество в рейтинге поиска.

Эволюция начинающего PHP-программиста может быть выражена следующей последовательностью шагов:

  • Размещение plain-PHP кода в отдельных файлах и доступ к этим файлам через линки вида /myfolder/myscript.php
  • Понимание, что все скрипты имеют значительную часть общего (например, создание подключения к БД, чтение конфигурации, запуск сессии и проч.) и как следствие создание общей начальной точки «входа», некоторого скрипта, который принимает ВСЕ запросы, а потом выбирает — какой внутренний скрипт подключить. Обычно этот скрипт имеет имя index.php и лежит в корне, вследствие чего все запросы (они же URLы) выглядят так: /index.php?com=myaction&com2=mysubaction
  • Необходимость внедрения роутера и переход к человекопонятным линкам.
  • Замечу, что между пунктами 2 и 3 большинство программистов делают очевидную ошибку. Я не ошибусь, если назову это значением около 95% программистов. Даже большинство известных фреймворков содержат эту ошибку. И заключается она в следующем.

    Вместо того, чтобы реализовывать принципиально новый способ обработки линков, ошибочно делается концепция «заплаток и редиректов» на базе.htaccess, которая заключается в том, чтобы с помощью mod_rewrite создавать множество правил редиректа. Эти строки сравнивают URL с каким-либо регулярным выражением и при совпадении расталкивают выуженные из URL значения по GET-переменным, в дальнейшем вызывая всё тот же index.php.

    #Неправильный метод ЧПУ RewriteEngine On RewriteRule ^\/users\/(.+)$ index.php?module=users&id=$1 #....Ещё куча подобных правил...

    У данной концепции множество недостатков. Один из них — трудность создания правил, большой процент человеческих ошибок при добавлении правил, которые сложно выявить, но они приводят к ошибке сервера 500.

    Другой недостаток в том, что часто правится по сути конфига сервера, что само по себе нонсенс. И если в Apache конфиг можно «пропатчить» с помощью.htaccess, то в популярном nginx такой возможности нет, там всё находится в общем файле конфигурации в системной зоне.

    И ещё один недостаток, вероятно, наиболее важный, что при таком подходе невозможно динамически конфигурировать роутер, то есть «на лету», алгоритмически менять и расширять правила выбора нужного скрипта.

    Предлагаемый ниже способ избавлен от всех этих недостатков. Он уже используется в большом количестве современных фреймворков.

    Суть заключается в том, что начальный запрос всегда хранится в переменной $_SERVER[‘REQUEST_URI’], то есть его можно считать внутри index.php и разобрать как строку средствами PHP со всеми обработками ошибок, динамическими редиректами и проч и проч.

    При этом в файле конфигурации можно создать только одно статичное правило, которое будет все запросы к несуществующим файлам или папкам редиректить на index.php.

    RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f #Если файл не существует RewriteCond %{REQUEST_FILENAME} !-d #И если папка не существует RewriteRule ^.*$ index.php

    Причём это правило можно разместить как в.htaccess, так и в основном файле конфигурации Apache.

    Для nginx соответствующее правило будет выглядеть вот так:

    Location / { if (!-e $request_filename) { rewrite ^/(.*)$ /index.php last; } }

    Всё просто.

    Теперь рассмотрим кусок кода PHP в index.php, который анализирует ссылки и принимает решение — какой скрипт запускать.

    /часть1/часть2/часть3

    Первое, что приходит в голову — разбить её с помощью explode(‘/’, $uri) и сделать сложный роутер на основе switch/case, анализирующий каждый кусок запроса. Не делайте этого! Это сложно и в итоге приводит код в ужасный непонимабельный и неконфигурабельный вид!

    Я предлагаю более лаконичный способ. Лучше не описывать словами, а сразу показать код.