Черствый category php. Критические части кода в приложении php? #2 Список категорий и их описание

Государственный Эрмитаж в данный момент занимает семь строений: Зимний дворец, Большой Эрмитаж (или Старый Эрмитаж), Малый Эрмитаж, Новый Эрмитаж, Эрмитажный театр, Меншиковский дворец и бывшее здание Главного штаба. Два последних архитектурных ансамбля вошли в состав Государственного Эрмитажа сравнительно недавно.

Эрмитаж - один из самых больших и известных художественных музеев в мире. Каждый посетивший Санкт-Петербург турист начинает свое знакомство с городом прогулки по набережной вдоль пять зданий Эрмитажа. Каждый житель Петербурга просто уверен, что если ты не посетил Эрмитаж, значит не проникся духом Петербурга. В настоящее время Эрмитаж является еще и культурно-образовательным учреждением. Тут читают лекции на самые разнообразные темы преподаватели различных ВУЗов. В школьную программу учащихся Санкт-Петербурга входит посещение Эрмитажа. Эрмитаж тесно сотрудничает со школьным и молодежным центром.

Главным зданием Эрмитажа считают Зимний дворец. Дворец был построен в середине 18 века по приказу Елизаветы Петровны. На его месте стоял другой Зимний дворец, показавшийся императрице недостаточно пышным и просторным для царских апартаментов. Новое здание, достойное называться императорским дворцом, строилось под руководством архитектора Бартоломео Франческо Растрелли, но ни Елизавете, ни вступившему после нее на престол Петру III, пожить в нем не удалось. В законченный Зимний дворец, который позже стал символом Эрмитажа, торжественно въехала после коронации в Москве Екатерина II. Впрочем, ей новое место жительства не понравилось: сначала она распорядилась здесь кое-что перестроить, а потом и вовсе решила возвести рядом с Зимним дворцом другое здание, которое было названо впоследствии - Малый Эрмитаж. Над его проектом работали архитекторы Юрий Матвеевич Фельтен и Валлен-Деламот Жан Батист Мишель. Когда здание Малого Эрмитажа было завершено, Екатерина стала проводить в нем значительную часть своего времени.

Малый Эрмитаж стал для Екатерины II местом где она смогла разместить свою коллекцию живописи, которая легла в основу будущего музея. Коллекция постоянно пополнялась новыми картинами, скульптурами, изделиями из поделочных камней и другими предметами искусства. И в конце концов в Малом Эрмитаже не осталось свободного места для их размещения. В 1771-1787 годах к нему было пристроено еще одно здание - Большой Эрмитаж, которое специально предназначалось для хранения живописных и скульптурных произведений. Большой Эрмитаж, построенный под руководством архитектора Ю. М. Фельтена, отличался от Зимнего дворца и Малого Эрмитажа очень строгим, без каких-либо украшений, внешним обликом.

В моду вошло участие в театрализованных представлениях. Примерно в те же годы, что и Большой Эрмитаж, на Дворцовой площади был возведен Эрмитажный театр, созданный по проекту Джакомо Кваренги. Императрица Екатерина II приглашала на спектакли так много гостей, что Малый Эрмитаж не вмещал всех приглашенных. Новый Эрмитаж стал необходим когда в Малом и Большом Эрмитаже закончилось свободное место. Разработка проекта Нового Эрмитажа была поручена немецкому архитектору Лео фон Кленце, а осуществляли его российские зодчие Василий Петрович Стасов и Николай Ефимович Ефимов. Удивительно красивый Эрмитажный театр, в настоящее время является местом проведения массовых мероприятий городского уровня.
(Просмотров папки: 78464)

Найдено: 188 фотографий 16 страницах. Показано: с 13 по 24.



Эрмитаж
Смотрели:2939. Комменты:0


Эрмитаж
Смотрели:2659. Комменты:0


Эрмитаж
Смотрели:2027. Комменты:0


Эрмитаж
Смотрели:2227. Комменты:0


Эрмитаж
Смотрели:2542. Комменты:0


Эрмитаж
Смотрели:2531. Комменты:0


Эрмитаж
Смотрели:3068. Комменты:0


Эрмитаж
Смотрели:2737. Комменты:0


Эрмитаж
Смотрели:2945. Комменты:0

Сегодня наша цель, создать иерархическую структуру категорий. Нам важно чтобы было удобно хранить категории и чтобы было легко выводить их там где нам надо.

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

Итак, структура должна состоять из id категории (id), из названия категории (name) и конечно id родительской категории (parent_id). В MySQL это выглядит так:

CREATE TABLE IF NOT EXISTS `category` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `parent_id` int(11) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=0 ;

Минимальная и понятная структура таблицы для хранения категорий.

INSERT INTO `category` (`id`, `name`, `parent_id`) VALUES (1, "Телефоны и планшеты", "0"), (2, "Автомобили", "0"), (3, "Samsung", "1"), (4, "Apple", "1"), (5, "LG", "1"), (6, "Ford", "2"), (7, "Lexus", "2"), (8, "BMW", "2"), (9, "Galaxy Tab 4", "3"), (10, "Galaxy S6", "3");

Там где значение parent_id=0, у данной категории нет родительской категории.

Тут все понятно и просто. Теперь присутпим к выводу списка категорий. Но для правильного вывода списка, нам нужно сначала получить весь список php категорий, а уже потом с помощью рекурсии сформировать наше дерево. Следующая функция предназначена для получения этого списка:

Function get_cat() { //запрос к базе данных $sql = "SELECT * FROM category"; $result = mysql_query($sql); if(!$result) { return NULL; } $arr_cat = array(); if(mysql_num_rows($result) != 0) { //В цикле формируем массив for($i = 0; $i < mysql_num_rows($result);$i++) { $row = mysql_fetch_array($result,MYSQL_ASSOC); //Формируем массив, где ключами являются адишники на родительские категории if(empty($arr_cat[$row["parent_id"]])) { $arr_cat[$row["parent_id"]] = array(); } $arr_cat[$row["parent_id"]] = $row; } //возвращаем массив return $arr_cat; } }

//получаем массив каталога $result = get_cat();

Теперь нужна функция с рекурсией

Function view_cat($arr,$parent_id = 0) { //Условия выхода из рекурсии if(empty($arr[$parent_id])) { return; } echo "

    "; //перебираем в цикле массив и выводим на экран for($i = 0; $i < count($arr[$parent_id]);$i++) { echo "
  • " .$arr[$parent_id][$i]["name"].""; //рекурсия - проверяем нет ли дочерних категорий view_cat($arr,$arr[$parent_id][$i]["id"]); echo "
  • "; } echo "
"; }

Теперь осталось только вывести каталог на экран с помощью рекурсивной функции

View_cat($result);

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

Уважаемые товарищи программисты, мой проект уже давно вышел за рамки желаний просто разобраться с технологиями web-программирования, и попрактиковаться в реализации. В связи с этим я все чаще стал задумываться о развитии проекта более глобально.

Задумывался я уже как с месяц и наконец, пришел к выводу: надо выносить проект дальше, нежели записи в блоге, и дать ему какое-то имя.

С подбором имени были некоторые проблемы, ибо все красивые домены давно заняты, либо скуплены перекупщиками. По итогам нескольких дней подбора имен, я нашел достойное название моему проекту!

Встречайте: MOGUTA.CMS

Я уже зарегистрировал домен moguta.ru , и в скором времени все новости по проекту начнут публиковаться именно там.

Кроме этого с сегодняшнего дня стала доступна группа вконтакте: MOGUTA.CMS

Но это еще не все!

Приглашаю к сотрудничеству

Всем, кто заинтересован в развитии проекта MOGUTA.CMS я предлагаю вступить в ряды разработчиков.

Какие плюсы вы получите, вступив в команду:

  1. Реальный обмен опытом;
  2. Возможность творить;
  3. В итоге: готовую, быструю, современную CMS для разработки интернет магазина;
  4. Общественное уважение.

Кроме этого в перспективе я хочу зарегистрировать юридическое лицо, и обеспечить рабочие места всей команде, соответственно, с положенным окладом. Конечно, это будет не скоро, и нет гарантий, что вообще будет, все зависит от активности откликов на мое приглашение.

Поэтому если ты школьник, студент, или просто умный парень – не упускай возможности, вступай в ряды разработчиков, и со временем наша команда будет занимать свое почетное место на рынке CMS. (Достаточно оптимистично! 🙂)

Вернемся к уроку…

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

Проверяется прямая принадлежность поста к категории, т.е. содержит ли указанная категория текущий/указанный пост. Если, например, пост принадлежит родительской категории или дочерней к указанной, то функция вернет 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-программиста может быть выражена следующей последовательностью шагов:

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

Замечу, что между пунктами 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, анализирующий каждый кусок запроса. Не делайте этого! Это сложно и в итоге приводит код в ужасный непонимабельный и неконфигурабельный вид!

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

"page404.php", // Страница 404 "/" => "mainpage.php", // Главная страница "/news" => "newspage.php", // Новости - страница без параметров "/stories(/+)?" => "storypage.php", // С числовым параметром // Больше правил); // Код роутера class uSitemap { public $title = ""; public $params = null; public $classname = ""; public $data = null; public $request_uri = ""; public $url_info = array(); public $found = false; function __construct() { $this->mapClassName(); } function mapClassName() { $this->classname = ""; $this->title = ""; $this->params = null; $map = &$GLOBALS["sitemap"]; $this->request_uri = parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH); $this->url_info = parse_url($this->request_uri); $uri = urldecode($this->url_info["path"]); $data = false; foreach ($map as $term => $dd) { $match = array(); $i = preg_match("@^".$term."$@Uu", $uri, $match); if ($i > 0) { // Get class name and main title part $m = explode(",", $dd); $data = array("classname" => isset($m)?strtolower(trim($m)):"", "title" => isset($m)?trim($m):"", "params" => $match,); break; } } if ($data === false) { // 404 if (isset($map["_404"])) { // Default 404 page $dd = $map["_404"]; $m = explode(",", $dd); $this->classname = strtolower(trim($m)); $this->title = trim($m); $this->params = array(); } $this->found = false; } else { // Found! $this->classname = $data["classname"]; $this->title = $data["title"]; $this->params = $data["params"]; $this->found = true; } return $this->classname; } } $sm = new uSitemap(); $routed_file = $sm->classname; // Получаем имя файла для подключения через require() require("app/".$routed_file); // Подключаем файл // P.S. Внутри подключённого файла Вы можете использовать параметры запроса, // которые хранятся в свойстве $sm->params

Несмотря на то, что код довольно длинный, он прост логически. Мне не хочется его объяснять, я считаю любой код на PHP самообъясняющим, если он правильно написан. Учитесь читать код.

Похожие статьи

  • Firearms – шутер ностальгии

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

  • Огромная база данных торрентов, доступных для скачивания

    Цифровая копия официального ключа активации (CD KEY) Crysis 2. Мгновенная доставка! Код Ключа Активации на игру Crysis 2 отображается в браузере сразу после оплаты! _________________________________________________________________ Мир...

  • Как добыча ресурсов работает в мультиплеере

    Этот режим полезен для тех, кто заинтересован в получении очков влияния, лута, новых достижений и многого другого. Однако вы не получите к нему доступ сразу же. Поэтому давайте разберемся, как играть в кооперативный режим State of Decay 2,...

  • Шкурки пробития для World of Tanks

    В этом разделе нашего сайта вы можете скачать Шкурки для World of Tanks бесплатно и без регистрации. Все файлы размещенные на нашем сайте доступны для скачивания по прямой ссылке и на высокой скорости.Шкурки или зоны пробития для World of...

  • Ассоциация же позволяет получить доступ к эмоциям внутри ситуации

    Одно из довольно интересных субмодальных различий – это ассоциированное или дисооциированное восприятие ситуации. Если воспринимать ситуацию являясь участником, «своими глазами», то говорят об ассоциации , если же воспринимать себя «со...

  • Выделяем текст под видео на YouTube

    Сочинение по тексту на ЕГЭ строится по специальному алгоритму: формулировка одной проблемы, её разъяснение (т.е. комментирование с введением двух текстовых примеров), обозначение позиции автора текста, выделение своего мнения (согласия или...