Немного о компьютере

Критические части кода в приложении php? Самый простой и логичный ЧПУ для PHP Бдительный categories php

И так для начала опишу с чем мы будем работать и что нам понадобится.
Система : PHP 5 и выше, mySQL 4 и выше
Вспомогательные классы : dbsql.class.php (класс для работы с базой данных)
Класс вложенных категорий : classTreeCategory.php (непосредственно основной класс, ниже приведен его листинг и пояснения.

Создаем таблицу в БД, следующей структуры:

Просмотр кода MYSQL

В данной таблице присутствует поле ID — порядковый номер категории, podcat — имеет значение ноль у категорий первого порядка или ID родительской категории, name — название категории.

Пример работы класса, вывод категорий списком с подкатегориями:

Просмотр кода PHP

include ("dbsql.class.php" ) ; include ("classTreeCategory.php" ) ; $DB = new DB_Engine("mysql" , $settings [ "dbHost" ] , $settings [ "dbUser" ] , $settings [ "dbPass" ] , $settings [ "dbName" ] ) ; // подключаемся к БД, с указанием данных доступа $category = new TreeCategory ($DB ) ; // передаем в класс категорий, объект работы с БД $category -> table = "category" ; // название таблицы в БД с категорийми $array = $category -> getCategory () ; // получаем все категории из БД в виде многоуровневого массива, отсортированные и вложенные уже в нужном нам порядке $category -> outCategory ($array , "option" ) ; // подготовка вывода категорий (формируем HTML), передаем массив с категориями echo $category -> html ; // вывод категорий в виде HTML name

Как видно из примера выше, все предельно просто, создаем новый объект $category, устанавливаем с какой таблицей БД работаем: ‘category’, далее получаем из таблицы список всех категорий уже оформленный в виде массива и разложенных в иерархичном порядке, с учетом всех подкатегорий. затем передаем массив в метод outCategory() который формирует для нас готовый HTML код, который остается только вывести в браузер.

Метод outCategory(), как мы видим принимает два параметра @array и @string в первом параметре массив со всеми категориями, а во втором строка содержащая значение option или table , это значени указывает какой тип HTML кода требуется сформировать.
Значение option

Просмотр кода HTML

-категория1 --подкатегория 1 ---подподкатегория 1 -категория 2

Для вставки данного HTML кода в поле select какой либо формы.

Значение table — формирует следующий HTML код:

Просмотр кода HTML

Этот HTML код удобен для вставки в таблицу которая отображает все наши категории подкатегории.

Класс имеет также следующие методы:
deleteItem($id); — удаляет одну категорию, не смотря на вложенные
delCategory($array, $id); — удаляет категорию со всеми вложенными подкатегориями, $array — массив со всеми категориями подготовленный методом $category->getCategory(), $id- номер удаляемой категории
addItem(); — данный метод следует вызывать если вы хотите добавить категорию, при этом этот метод считывает значения из данных переданных методом POST, т.е. из массива $_POST.
$name=$this->PHP_slashes(strip_tags($_POST[‘name’])); // имя категории
$podcat=intval($_POST[‘podcat’]); // ID родительской категории, если указан 0 категория будет в корне.
updateItem() ; — аналогично предыдущему методу, кроме того что данный метод обновляет категорию, её название и уровень вложенности.

table="category"; // запрос на выборку списка категорий, название таблицы * $category->outCategory($category->getCategory()); // подготовка вывода категорий(запрос массива категорий) * echo $category->html; // вывод категорий в HTML name * */ /** * Дамп таблицы с которой ведется работа * * DROP TABLE IF EXISTS `category`; * CREATE TABLE `category` (* `id` int(11) NOT NULL auto_increment, * `podcat` int(11) NOT NULL, * `name` varchar(255) NOT NULL, * PRIMARY KEY (`id`), * KEY `id` (`id`) *) ENGINE=MyISAM DEFAULT CHARSET=utf8; * */ class TreeCategory { /** * Строка запроса в БД */ var $table; /** * Интерфейс работы с БД */ var $DB; /** * Массив категорий с вложенными подкатегориями */ var $arrayCat; /** * Авто-подстчет кол-ва прочерков перед названием категории при выводе */ var $countPodcat; /** * HTML код для вывода категорий с подкатегориями */ var $html; /** * Получаем интерфейс для работы с БД и кладем его в локальные переменную */ function __construct($DB) { $this->DB=$DB; $this->component=$_GET["component"]; } /** * Получает список категорий, сортирует и помещает в массив с вложенными массивами и т.д. * @return array category */ function getCategory () { $all = $this->DB->getAll("SELECT * FROM `{$this->table}` ORDER BY `id` ASC"); $path = array(); if(count($all)>0) { foreach($all as $item): if($item["podcat"]==0)$sort[$item["id"]]=$item; if($item["podcat"]>0) { if(isset($path[$item["podcat"]])) { $str="$sort"; foreach($path[$item["podcat"]] as $pitem): $rep=$item["podcat"]; $str.="[$pitem]"; endforeach; $str.="[{$item["podcat"]}]"; $str.="[{$item["id"]}]"; $str.="=$item;"; eval($str); foreach($path[$item["podcat"]] as $pitem): $path[$item["id"]]=$pitem; endforeach; $path[$item["id"]]=$item["podcat"]; } else { $sort[$item["podcat"]]["sub"][$item["id"]]=$item; $path[$item["id"]]=$item["podcat"]; } } endforeach; } $this->arrayCat=$sort; return $this->arrayCat; } /** * Печатает категории, помещает готовый HTML в $this->html * @param array Массив с категориями и вложенными подкатегориями * @param string Тип генерируемого HTML кода для вывода, option или table */ function outCategory(&$arrayCat, $type="option", $idSel=0) { foreach($arrayCat as $sub) { $this->countPodcat++; $this->outItem($sub, $type); if(!empty($sub["sub"]))$this->outCategory($sub["sub"], $type, $idSel); $this->countPodcat--; } } /** * Вспомогательный метод подготовки HTML кода * @param array Массив с категорией * @param string Тип генерируемого HTML кода для вывода, option или table */ function outItem($sub, $type="option", $idSel=0) { for($i=0;$icountPodcat;$i++) { $out.="-"; } if($idSel==$sub["id"])$se="selected"; else $se=""; if($type=="option")$this->html.=" {$out} {$sub["name"]} "; if($type=="table")$this->html.= {$out} {$sub["name"]} HTML; } function delCategory(&$a_tree,&$id=0) { foreach($a_tree as $sub) { if($sub["id"]$id and isset($sub["sub"]))$this->delCategory($sub["sub"],$id); if($sub["id"]==$id) { $sql="DELETE FROM {$this->table} WHERE id = "$id" LIMIT 1"; $this->DB->execute($sql); if (isset($sub["sub"])) $this->delCategory_process($sub["sub"]); } } } function delCategory_process(&$a_tree) { foreach($a_tree as $sub) { $sql="DELETE FROM {$this->table} WHERE id = "{$sub["id"]}" LIMIT 1"; $this->DB->execute($sql); if(isset($sub["sub"]))$this->delCategory_process($sub["sub"]); } } function updateItem() { $name=$this->PHP_slashes(strip_tags($_POST["name"])); $podcat=intval($_POST["podcat"]); $id=intval($_POST["id"]); $sql="UPDATE `{$this->table}` SET `name` = "{$name}",`podcat` = "{$podcat}" WHERE `id`="{$id}" LIMIT 1; "; $this->DB->execute($sql); } function addItem() { $name=$this->PHP_slashes(strip_tags($_POST["name"])); $podcat=intval($_POST["podcat"]); $id=intval($_POST["id"]); $sql="INSERT INTO `{$this->table}` (`id`,`podcat`,`name`) VALUES ("", "$podcat", "$name");"; $this->DB->execute($sql); } function deleteItem($id) { $id=intval($id); $sql="DELETE FROM `{$this->table}` WHERE `id` = "{$id}" LIMIT 1"; $DB->execute($sql); header("Location: ?component={$this->component}"); } function PHP_slashes($string,$type="add") { if ($type == "add") { if (get_magic_quotes_gpc()) { return $string; } else { if (function_exists("addslashes")) { return addslashes($string); } else { return mysql_real_escape_string($string); } } } else if ($type == "strip") { return stripslashes($string); } else { die("error in PHP_slashes (mixed,add | strip)"); } } }

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

Буду признателен если в комментариях вы предложите собственные варианты решения данной задачи — организации категорий бесконечного уровня вложенности.

Хорошо, в моей голове это несколько сложно, и я надеюсь, что смогу это объяснить. Если что-то неясно, прокомментируйте, поэтому я могу уточнить вопрос.

Я хочу обрабатывать загрузки файлов пользователей на 3-й сервер.

Итак, мы имеем

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

Поток должен быть следующим:

    Сайт запрашивает URL загрузки из шлюза облака хранения, который указывает непосредственно к конечному серверу хранения (что-то вроде http://serverXY.mystorage.com/upload.phpа >). Наряду с запросом отправляется "целевой путь" (уникальный веб-сайт и глобально уникальный) и URL-адрес перенаправления.

    Веб-сайт создает форму загрузки с сервером загрузки серверов хранения в качестве целевого объекта, пользователь выбирает файл и нажимает кнопку отправки. Сервер хранилища обрабатывает почтовый запрос, сохраняет файл во временное местоположение (т.е. "/tmp-directory/".sha1(target-path-fromabove)) и перенаправляет обратно на URL-адрес перенаправления, указанный веб-сайтом. Также передается "целевой путь".

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

    это критические шаги

    • Теперь веб-сайт записывает запись в свою собственную базу данных и выдает спокойный запрос на хранение api (подпись, веб-сайт должен аутентифицироваться с помощью секретного токена), который
    • копирует файл из своего временного местоположения на сервере хранения в его конечное местоположение (это должно быть быстрым, потому что его только переименование)
    • тот же запрос на отдых также вставляет строку базы данных в базу данных сетей хранения вместе с идентификатором веб-сайта как владельца
  • Все файлы в каталоге tmp на сервере хранения, которые старше 24 часов, автоматически удаляются.

Если пользователь закрывает окно браузера или соединение прерывается, поток программы на сервере также прерывается, верно? Выполняются только деструкторы и зарегистрированные функции выключения, правильно?

Могу ли я каким-либо образом сделать эту часть кода "критичной", чтобы сервер, если он когда-то попадал в эту часть кода, выполняет его до конца, независимо от того, отменяет ли пользователь загрузку страницы или нет?

(Конечно, я знаю, что авария сервера или ошибка могут прерываться в любой момент, но мои проблемы касаются регулярного потока)

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

Я хочу, чтобы хранилище api было очень общим и использовало его во многих других будущих проектах.

Я посмотрел на хранилище Google для разработчиков и Amazon s3.

У них такая же проблема и еще хуже. В amazon S3 вы можете "подписать" свой почтовый запрос. Таким образом, файл загружается пользователем под вашими полномочиями и непосредственно сохраняется и сохраняется, и вы должны его оплатить. Если соединение прерывается, и пользователь никогда не возвращается на ваш сайт, вы даже не знаете. Таким образом, вы должны хранить все загружаемые URL-адреса, которые вы подписываете, и проверять их в cronjob и удалять все, что "не достигло цели".

В статье описан функционал, который доступен в PHP (актуально для 5.3.х) для обработки ошибок всех типов, включая ошибки интерпретации кода (E_ERROR, E_PARSE, E_WARNING, etc). Эта обработка поможет вам для управляемого отображения страницы в случае возникновения таких проблем. В статье присутствует множество описаний и рабочих примеров(архитектуры) для того, что бы сразу воспользоваться в своем программном продукте. В конце концов, ну немного сломали сайт, ну надо же, об этом сообщить поисковику с заголовком 4хх или 5хх и повеселить пользователя, вместо возврата белого экрана (или что хуже экрана со священной информацией, для хакеров) с ответом 200 Ok.

Идея написать этот топик возникла, когда я на храбре задал 2 вопроса:

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

Если заинтересовались, то подробности под катом…

Причины использования Пользователю/поисковику, требуется внятно ответить, что на сервере проблемы. Без использования определенного фен-шуя, этого добиться достаточно трудно, а порой невозможно. Тут я проливаю свет на все это, ну и себе заметочку оставляю, так как еще неделю назад я не знал за что взяться, и, наверное, многие новички тоже будут обескуражены.Описания функций Данный функционал доступен в PHP для того, что бы обрабатывать ошибки и контролировать вывод. Вот описание их вкусностей и недостатков. Документацию я приводить не буду, я только сошлюсь её страницы и опишу свое мнение. Все что будет приведено это только малая доля, ссылки на соответствующие разделы документации я приведу в конце статьи. Итак встречаем:

- Контроль некритических ошибок: замечания, предупреждения, пользовательские ошибки. В общем все то, что не завершает интерпретацию аварийно.
set_error_handler - Задает определенный пользователем обработчик ошибок.
Нужен для того, что бы писать в лог все такие ошибки. Если её не задать, то в лог это не пишется, а мне вот всегда хочется узнать при каких боевых ситуациях могут вызываться замечания и предупреждения. То есть позволяет автоматически тестировать продукт пользователем и он даже не будет замечать этого.
Если функция не задана, то PHP лишь пытается вывести данные на экран, а если ему и это не дают, то вообще никаких признаков жизни от этих типов ошибок не возникает.

- Контроль, исключений: является ошибкой типа E_ERROR.
set_exception_handler - Задает пользовательский обработчик исключений
Ну не знаю, зачем это вообще было придумано, когда есть то, что описано ниже и просто обработка ошибки типа Exception. Так что сообщаю что оно просто существует. Она перехватывает критическую ошибку «исключение» и позволяет что-то с ней делать. В любом случае скрипт завершается. Её работы по умолчанию лично для меня достаточно (пишет в логи, пытается вывести на экран). Я бы её вообще не переопределял, а то придется в логи о случившимся исключении самому писать.

- Функции контроля вывода: Тут я опишу 3 функции, которые следует знать по разным причинам. Например, для проблем производительности или для проблем вывода заголовков. В нашем случае требуется выводить заголовки ошибок.

Условия Есть файл с кодом, который запускается первым или перед кодом в котоом может появиться ошибка и этот файл и все файлы до него 100% отлаженные с невозможностью появления ошибки. Вот такое вот условие, что бы было проще - без ошибок до того пока не пройдут все регистрации вышеизложенных функций. В данном файле описаны данные методики контроля ошибок в комплексе. Контролируется буфер, если ошибка, то сбросить буфер и вывести ошибку.Код с комментариямиОт себя добавлю, что код не тестировал, так как это упрощенная схема того, что у меня в коде, замечания принимаются
Государственный Эрмитаж в данный момент занимает семь строений: Зимний дворец, Большой Эрмитаж (или Старый Эрмитаж), Малый Эрмитаж, Новый Эрмитаж, Эрмитажный театр, Меншиковский дворец и бывшее здание Главного штаба. Два последних архитектурных ансамбля вошли в состав Государственного Эрмитажа сравнительно недавно.

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

Главным зданием Эрмитажа считают Зимний дворец. Дворец был построен в середине 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);

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

Похожие публикации