[Закрыть]
 
popoff.donetsk.ua
Пока Вы врёте сами себе, веря в то, что Вам кажется приятным, Вы никогда не отличите правду от лжи, так как Вы не понимаете разницы между ними даже в самих себе. /Путь дурака/
Начало | Новости | Статьи | Форум | Опросы | Карта сайта | Обо мне
popoff.donetsk.ua - Статьи - Программирование - Движок для портала - Часто задаваемые вопросы
Я это делаю
Персональное меню
Голосование
Деньги, либо любимое занятие? Постоянный адрес этого вопроса
Деньги, но неинтересная работа и невозможность уделить время семье
Интересная работа, возможность саморазвиваться, но нищенский заработок
Ваш возраст (не обязательно)
Почему? (не обязательно)

Голосование закрыто.

Поиск по сайту
Реклама
Обмен электронных валют
money.dn.ua
Статистика

Часто задаваемые вопросы

Постоянный адрес статьи

Содержание

Где взять базу к системе popoff.donetsk.ua/light?

База данных создается на страницах программиста. Страницы программиста находятся в папке public_html/prg/. Пароль для входа задается в библиотеке prg.options в файле libs/prg/prg.options.php. Скрипты для создания базы данных находятся в файлах libs/*/*.db.php.

В системе для хранения деревьев используются Nested Sets. Почему Вы выбрали именно этот способ?

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

Вот здесь можно найти информацию о способах хранения деревьев:
http://phpclub.ru/faq/Tree

В своей системе я выбрал Nested Sets для хранения деревьев. Но я не буду отстаивать этот выбор, потому что я не считаю это наилучшим выбором. Я так же не буду спешить изменить этот способ хранения деревьев на какой-либо другой, потому что недостатки других способов хранения деревьев я тоже знаю. Почему я выбрал именно Nested Sets? Так сложилось исторически. В будущем, возможно, способ хранения деревьев будет задаваться в настройках.

Почему при генерации страниц выполняется так много SQL-запросов?

Действительно, в моей системе при генерации страниц может генерироваться довольно большое количество (порядка 500) sql-запросов.

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

Время от времени возникает вопрос о том, возможно ли избавиться от большого количества запросов. Многие говорят, что «большое количество запросов - это потому что кривые руки программиста». На самом деле люди, которые так говорят, не понимают, что они говорят: они привыкли писать простенькие сайтики, без поддержки мультиязычности и без особо гибкого интерфейса - в таком случае большое количество sql-запросов действительно говорит о кривых руках программиста.

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

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

Порядка 90% запросов возникает из-за использованной системы поддержки мультиязычности: все отображаемые на сайте сообщения и надписи хранятся в базе данных. В случае, если Вы только что установили систему и у Вас полностью пустая база данных переводов, то для каждой надписи выполняется 2 запроса, а при первом обращении - 3 запроса (1 - найти перевод на текущий язык, 2 - найти перевод на наиболее похожий язык, 3 - добавить сообщение в базу данных).

Попытаемся уменьшить это количество. Курсивом я буду выделять то, как мне предлагали это количество уменьшить. Начнем с малого.

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

Запрос для проверки перевода на наиболее похожий язык содержит в себе сортировку по похожести языков, а для поиска перевода на текущий язык - только поиск по уникальному ключу. При заполненной базе данных поиск перевода выполняется по одному запросу - поиск перевода на текущий язык. Удалив этот запрос, при при пустой базе данных мы получили бы на 30% меньше запросов для поиска переводов. Но при заполненной базе данных мы выполняли бы такое же количество запросов: один для каждого сообщения, но теперь этот один запрос - гораздо более сложный. Мы выиграли?

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

Ужас! Да, закешировав в переменных сессии запросы к базе данных мы действительно уменьшили бы их количество до минимума при повторных обращениях к сайту. Но зачем, скажите мне, делать кеширование результатов запроса средствами php, если сама MySQL уже кеширует результаты своих запросов! Фактически, получается, мне предлагают сделать кеш для кеша. К тому же гораздо менее производительный, чем кеш запросов в MySQL.

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

Кардинальное решение. Но здесь вопрос упирается в то, почему я выбрал именно такой способ хранения данных? Потому что при хранении переводов в базе данных:

  1. проще искать перевод на наиболее похожий язык в случае, если перевода на нужный язык нет.
  2. можно автоматически добавлять новые сообщения в базу данных перевода. Иначе я должен был бы ходить по сайту и искать, «а где это у меня там появилась новая непереведенная фараза?» Хорошо, если на сайте всего две-три страницы и я - единственный человек, который работает над сайтом.
  3. я могу предоставить администраторам привилегии на добавление новых языков, на редактирование переводов и сделать любой удобный интерфейс для перевода сайта. Иначе я должен был бы либо давать им ftp-аккаунты, либо закачивать вместо них файлы переводов, либо объяснять им настройки php, либо самому настраивать, либо объяснять им, как редактировать файлы на php, либо каким-либо другим способом учавствовать в процессе перевода.
  4. у меня одинаковым способом хранятся как переводы коротких фраз/сообщений, так и все данные, которые зависят от языка. Эти данные есть практически в любом модуле. В чате - названия комнат. В форуме - названия и комментарии к темам. В модуле управления загрузкой изображений - комментарии/заголовки изображений. В службе управления аккаунтами пользователей - названия ролей. А в таких модулях, как служба новостей и служба управления статьями вообще все зависит от языка.
  5. текстовый файл со списком переводов одних лишь надписей для такого простенького сайта, как popoff.donetsk.ua весит порядка 150 КБ. Если говорить о способе хранения базы данных в виде php-скрипта (в виде массива, в виде набора констант или любым другим способом), то я не стану утверждать, что парсить такого размера скрипт и искать переводы в массиве - это быстрее, чем обращаться к базе данных. Просто мне так показалось, хотя на самом деле это может быть и не так.
  6. собственно, из желания все контролировать я отказался от использования встроенной функции GetText().

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

Кроме мультиязычности много sql-запросов может выполняться в следующих случаях:

  • При подсчете статистики - у меня она хранится не в одной таблице, а в нескольких. Поэтому при каждом обращении выполняется поиск/добавление в разные таблицы. На эти таблицы по очереди накладываются и снимаются блокировки, а наложить блокировку и снять блокировку - это два разных sql-запроса. О том, почему в данном случае выгоднее блокировать их разными sql-запросами по очереди, а не сразу все, написано в документации по MySQL в разделе «Оптимизация в MySQL - Вопросы блокировок». Впрочем, статистика будет оптимизирована в будущих версиях.
  • Некоторые элементы страниц невыгодно кешировать, и поэтому они создают дополнительное количество sql-запросов даже при включенном кеше. Это в первую очередь касается тех элементов, содержимое которых меняется при каждом обращении к сайту (например, ротаторы). Наличие элементов этого первого типа не позволяет закешировать ВСЮ генерируемую страницу. Во вторую очередь это касается тех элементов, содержимое которых зависит от сессии (например, у администратора в службе новостей могут появиться ссылки на удаление новостей - эти ссылки зависят от сессии). Поскольку эти элементы второго типа изменяются значительно чаще, чем другие элементы страниц, то кешировать их вместе со всеми остальными элементами не выгодно - выгоднее кешировать отдельно часто изменяющиеся элементы и отдельно - редко изменяющиеся. Отдельный кеш, однако, приводит к генерации отдельных sql-запросов.
  • Я с большой осторожностью отношусь к кешированию данных, которые зависят от непроверенной информации, пришедшей от пользователей. Первый пришедший мне в голову пример - кеширование статей. Если я буду кешировать в зависимости от имени файла, переданного в URL, не проверяя предварительно это имя на существование, то удаленный пользователь, делая много запросов к разным несуществующим страницам, может легко устроить атаку на сервер, в которой размер кеша разрастется до неимоверных размеров. Проверка имени файла на существование требует своего sql-запроса. То же касается и других данных.
  • Эти приведенные выше три пункта - это три места, на которые я обратил внимание, когда создавал подсистему кеширования. Возможно, есть и другие места, на которые я не обратил внимания.

После инсталляции системы при попытке зайти на главную страницу появляется пустая страница.

Постоянный адрес статьи

Если посмотреть исходный текст этой пустой страницы, то можно увидеть РНР-код.

Проблема связана с тем, что РНР-код, записанный в файлах с расширением *.html не выполняется, а отдаётся в браузер как есть. Вот возможные пути решения проблемы:

  • Проверьте внимательно все пути, прописанные в файлах public_html/inc-all.php и options/addr.php. Пути в файле inc-all.php должны указывать на каталог с файлом addr.php.

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

  • Попробуйте в файле .htaccess, который находится в каталоге public_html поменять эту строчку (она самая первая в файле):
    AddHandler application/x-httpd-php .html
    на вот такую:
    AddType application/x-httpd-php .html

  • Если Вы используете локальную версию, то проверьте, разрешена ли у Вас обработка файлов .htaccess в настройках сервера.

    Для этого в файле httpd.conf нужно проверить настройку AllowOverride. Её значение для каталога, в котором установлена система должно быть AllowOverride All. Не забывайте о том, что эта настройка может быть разная для разных каталогов, и что проверить нужно не любое одно вхождение этой настройки в файл httpd.conf, а именно то, которое отвечает за каталог с системой popoff.donetsk.ua/light.

    После внесения изменений не забудьте перезапустить сервер.

  • Если проблема - на хостинге, то задайте этот вопрос Вашему хостеру. При этом обязательно укажите суть проблемы, что в файлах с расширением *.html РНР-код не выполняется, а выдаётся в браузер в исходном виде. Возможно, на Вашем хостинге нужны какие-то особые настройки - такое бывает довольно часто.

    Перед тем, как задавать вопрос хостеру - попробуйте внести описанное в первом пункте изменение в файл .htaccess - поменять AddHandler на AddType.

    Изучите FAQ Вашего хостера. Проблема, с которой Вы столкнулись - часто встречаемая и, возможно, на сайте Вашего хостера уже есть ответ на этот вопрос.

  • Если ничего не помогло, то всё, что я могу сделать - это попросить Вас разобраться с тем, почему у Вас возникает этот эффект и выложить в комментарии к этой странице описание сути проблемы и способа решения проблемы в Вашем конкретном случае.

Смотрите также

Постоянный адрес статьи

Многоязычность в движке для портала
Некоторые особенности устройства подсистемы поддержки многоязычности (вопрос в форуме)

Выбираем лучший инструмент: Объектно-ориентированное и процедурное программирование в PHP
http://phpclub.ru/detail/article/oop-vs-proc

Последняя модификация: 16.06.08 01:19

Не проходите мимо! Оставьте Ваш комментарий в форуме! >>>