[...]
(18:12:45) Balancer: Фреймворк на PHP5. Бэкенд данных обычно mysql, но может быть любым, это настраивается. Например, статические страницы я чаще делаю прямо в файловой системе (XML или формат отдельное поле объекта - отдельный файлик)
[...]
(18:19:29) Balancer: http://hg.balancer.ru/bors-core/ - это ядро фреймворка, общее для всех проектов (скачать локально можно через Mercurial: «hg init && hg pull -u http://hg.balancer.ru/bors-core»)
http://hg.balancer.ru/bors-airbase/ - основные расширения Авиабазы.
Комментированый пример (один из немногих) работы: http://balancer.ru/support/2008/11/t64759--Kak-ono-rabotaet.Otobrazhenie-ob~ektov-s.6302.html
(18:19:51) Balancer: Там пример страницы, берущей данные из БД.
[...]
(21:06:19) ????: я не понял как скачать ядро фреймворка.
по ссылке примеры кода, но нет явной ссылки на фреймворк.
поможешь?
(21:08:36) Balancer: Сам фреймворк лежит на hg.balancer.ru
Качать его надо с помощью DVCS (распределённая система контроля версий) Mercurial.
С SVN или CVS знаком?
(21:09:32) Balancer: http://ru.wikipedia.org/wiki/Mercurial
(21:10:12) ????: с системами контроля версий знаком, но не в образе веба.... короче нет. :)
(21:10:30) Balancer: Ну, сам принцип представляешь?
(21:10:37) ????: конечно
(21:12:42) ????: ааа.... вроде понятно стало.... надо скачать Тортоизу и там уже скачать софт?
(21:16:13) Balancer: Распределённые системы контроля версий (Mercurial, Git) отличаются от централизованных (CVS, SVN) тем, что могут не иметь единого центра. Ты из рабочего каталога делаешь коммит не на центральный сервер, а прямо в этот каталог. А потом можешь выпихнуть (push) изменения в любой другой каталог, например, условно назначенный централизованным. Или просто товарищу на другую машину. Или в другой рабочий каталог у себя же. Главное, чтобы доступ был. Можно, наоборот, утянут (pull) изменения из другого каталога.
...
Что с GUI под Mircurial под Windows - не знаю. Привык с командной строки работать, оно удобно :) Качаешь и ставишь Mercurial, идёшь в любой пустой каталог, который будет рабочим. Там:
hg init
это проинициализирует локальный репозиторий в данном каталоге. В принципе, всё, с ним уже можно работать локально - добавлять файлы, коммитить изменения...
Потом пишешь:
hg pull http://hg.balancer.ru/bors-core/
и он утянет все изменения из официального репозитория моего фреймворка. По сути, сам фреймворк утянет. Но в каталог ещё не развернёт, только во внутренний скрытый каталог .hg, на манер, как .svn в SVN.
Потом:
hg up
и всё, в каталоге развернётся вся система.
...
Потом можно настроить более тонко, если что.
(21:17:09) Balancer: DVCS особенно удобны для всякой мелкой локальной работы. Не требуют разворачивания сервера. В любом каталоге hg init - и добавил первоначальный коммит. И работаешь потом локально, не боясь убить или повредить файлы :)
(21:18:04) Balancer: Вот, на офсайте: TortoiseHg 0.6 (with Mercurial 1.1.2)
Т.е. есть адаптация черепахи пот Hg.
(21:18:09) Balancer: s/пот/под/
(21:18:35) Balancer: http://bitbucket.org/tortoisehg/stable/get/095d7aedcc48.zip
(21:19:39) Balancer: Тут главное помнить, что в отличии от SVN есть лишний слой - локальный репозиторий и нет строго центрального сервера, он назначается условно самими разработчиками и может отсутствовать :)
(21:20:59) ????: ага, ясно.
сейчас буду "переваривать"...
[...]
(00:05:48) ????: Такс, черепаху скачал и установил (правда не по твоей ссылке, там были исходники похоже, а скачал инсталлятор под винду).
Репозитарий сделал, борс-коре скачал и поднял по hg up.
... А что дальше? :)
У меня стоит последний Денвер (сборка PHP5 + Мускул). Подсунуть ему ту тьму файлов, что появились после hg up?
(00:14:57) ????: Пошёл спать, завтра на работу с утра...
(04:28:10) Не удаётся отправить сообщение: Сообщение слишком велико.
(04:28:20) Balancer: Да, естественно, что на этом тестовом сайте сделаешь, потом можно перенести будет.
...
По Денверу. Основной принцип фреймворка - нужно все необработанные статически файлы завернуть на файл-загрузчик. Обычно на Апаче это через .htaccess делается. Смотри пример на тестовом сайте. Заворачивается всё на /bors-loader.php
В этом файле прописывается три пути (все три могут лежить где угодно, не обязательно доступными по HTTP):
- к ядру фреймворка (BORS_CORE)
- расширения/настройки характерные для конкретного сервера (BORS_LOCAL)
- расширения/настройки для конкретного виртуального хостинга/сайта (BORS_HOST)
В прицнипе, прописав и запустив его таким образом уже всё должно заработать. Только, понятно, пока нет своих расширений, ничего не будет показываться. Должен ругаться (но уже не Апач, а фреймворк), что страница не найдена.
(04:28:30) Balancer: Свои модули подключаются вешанием пар "регексп-url => имя_php_класса" в файлах handlers/bors_map.php. Эти файлы последовательно загружатся из BORS_HOST, BORS_LOCAL и BORS_CORE и в результатах ищется соответствие ссылки и класса. Если находится, то грузится соответствующий класс и тот отдаётся браузеру.
Если не находится - возвращает состояние "не найдено" или редиректится на какой-нибудь адрес, в зависимости от настроек.
Настройки лежат в файлах config.php, которые тоже последовательно загружаются из BORS_HOST, BORS_LOCAL и BORS_CORE.
BORS_CORE/handlers/bors_map.php в конце, если до него соответствия ссылок и классов не найдены, пытается для всех видов ссылок искать сорцы страницы, положенные в простую файловую систему:
'.* => page_fs_separate(url)',
'.* => page_fs_xml(url)',
Это для простоты задачи plain/text-страниц на сервере, прямо в файловой системе.
Скажем, ты запрашиваешь http://rp.kosh.wrk.ru/contacts/ (пример реальный). Не найдя обработчика раньше, в конце пытается загрузиться класс page_fs_separate. Находится в BORS_CORE/classes/page/fs/separate.php, импользует класс-источник данных storage_fs_separate, расположенный в BORS_CORE/classes/storage/fs/separate.php. Он проверяет, нет ли в каталоге $_SERVER['DOCUMENT_ROOT']/contacts/ файлов .title.txt Если нет - возвращает состояние "не найдено" (и система пытается искать обработчики дальше). Если есть, то считается, что там лежат параметры нужного класса в виде .property.php для скалярных параметров и .[property].txt для массивов. Он инициирует соответствующий класс, загружая эти параметры и отдаёт его браузеру. Обычно самые важные это:
title - заголовок страницы
source - исходный текст контента страницы, обычно BBCode + HTML
Менее важные, но часто встречающиеся:
массив parents - список родителей данной страницы (в общем случае их может быть больше одного)
template - шаблон страницы. Шаблоны ищутся в templates/ в той же тройке BORS_HOST/BORS_LOCAL/BORS_HOST.
create_time - дата создания объекта (по умолчанию - текущее время)
modify_time - дата последнего изменения объекта.
Конкретно в случае РП-шного /contacts/ там лежит ещё чисто РП-шная фишка submenu - это названии секции сайта (там на сайте 4 больших раздела), contacts не принадлежит никому, поэтому там пусто.
(04:28:32) Balancer: Пока хватит, потом продолжу :)
(04:29:07) Balancer: Ой, блин, ты же в аське, а она режет длинные сообщения. Если не дойдёт, то потом повторю по кусочкам, а, лучше, осваивай Jabber ;)
(20:42:24) ????: Прив.
Я всё ещё в непонятках...
Непонятно всё, с самого простого начала. :)
Про то, что на тестовом сайте пока речи не идёт, т.к. я не понимаю принципов построения.
Нужен совсем простой пример, типа "Hello world!", но не на отдельном PHP, а на фреймворке. Есть такой? Чтобы ЛОКАЛЬНО я мог это всё скормить апачу.
Потом нужен пример разметки стартовой страницы. Я так понимаю должно быть что-то типа блоков, как у CMS.
Чем нибудь поможешь?
(20:48:08) Balancer: Да, смогу. Пока разверни и подключи у себя в Денвере ядро фреймворка. Настрой bors-loader.php и .htaccess, чтобы на открытие страниц вызывалось ядро. Потом дальше сделаем уже и hello world.
(20:50:13) ????: Ага, попробую...
(20:51:40) Balancer: Можешь для начала самым примитивным образом:
ErrorDocument 404 /bors-loader.php
Все ненаденные документы будут переадресовываться на загрузчик.
(Хотя более правильно - через mod_rewrite, но это сложнее, потом можно будет сделать)
(20:51:57) Balancer: ErrorDocument 404 /bors-loader.php - это в .htaccess
(21:00:33) ????: ага
(21:15:18) ????: С самого начала: я развернул черепаху по hg up. У меня в этом каталоге появилось куча каталогов и два ПХП файла main.php и config.php.
Мне этот набор перекинуть в директорию для сайтов у Апача? Наверное да, иначе как я вообще что-то запущу...
(21:17:57) Balancer: Этот набор может лежать где угодно. Может в каталоге апача, может в рабочем каталоге. По идее, даже лучше класть в каталог, недоступный для прямых запросов с Web. Из соображений безопасности.
Загрузка делается так.
Апача, видя, что на диске нет запрашиваемой страницы или файла (через обработку 404-й ошибки или через mod_rewrite) переадресует запрос маленькому файлу-загрузчику, который, как раз, доступен через Web. В нашем примере это bors-loader.php, лежащий в корне сайта.
(21:19:06) Balancer: Этот файл через define определяет каталог, где лежит ядро системы (define (BORS_CORE) ) и, опционально, где лежат каталоги расширений ядра (define (BORS_LOCAL) и BORS_HOST).
(21:19:40) Balancer: Потом конфигурит систему, загрузив BORS_CORE/config.php и передаёт управление системе в BORS_CORE/main.php
(21:20:04) Balancer: На этом вопрос вызова завершён. Всё остальное - раширение системы своими модулями.
(21:21:44) ????: Стоп, стоп. Ещё раз плиз:
Я создал виртуальный домен у себя и поместил туда 1 файл "index.html" со словом Хеллоу Ворлд!
Всё работает. :) Т.е. я вижу "хеллоу"
В это место что мне кидать? Борс-лоадер.пхп? И пускать его?
(21:22:28) Balancer: Для начала проверь, что у тебя работает PHP.
Скажем, помести index.php с "<?php phpinfo(); ?>
(21:23:23) ????: :) Да, пхп робит. :)
(21:24:22) Balancer: Приколоться, что ли, и развернуть Денвер под виндой в Вируталбоксе, чтобы было проще самому понять, если какие-то проблемы вылезут...
...
Ладно, дальше. Где у тебя лежит корень сайта, в каком виндовом каталоге?
(21:25:43) ????: C:\WebServers\home\kosh.ru\www\index.php
(21:26:58) Balancer: Давай примем, что ядро фреймворка будет у тебя лежать в C:\WebServers\home\kosh.ru\.bors-core
Туда его и разверни.
(21:28:44) Balancer: Расширения сайта положишь в C:\WebServers\home\kosh.ru\.bors-host
Сторонние модули (надо скачать с http://hg.balancer.ru/bors-third-party/ ) в C:\WebServers\home\kosh.ru\.bors-third-party
(21:32:12) ????: "Туда его и разверни." - это я так понимаю, надо скопировать то, что получилось после hg up? Скопировал.
".bors-host" сделал. А где эти расширения? Или пока их нет?
сторонние качаю...
(21:32:38) Balancer: В .bors-host будет лежать то, что ты будешь сам писать :)
(21:33:39) ????: Ааааааа.... :)
Со сторонними проблема... По ссылке что-то типа форума....
(21:34:06) ????: А, или в files смотреть?
(21:34:20) Balancer: Подразумевается, что в исходники ядра или сторонних компонентов вообще не нужно лазить. Т.е. если какие-то ошибки, или функционал расширить - да, а так, для подключения своей системы - нет.
...
«Разернуть» - да, перекопировать. Кстати, репозитории mercurial не привязаны к конкретному каталогу, так что переносить можно свободно.
(21:34:26) ????: Пеар, геоип, смарти... это?
(21:34:52) Balancer: http://hg.balancer.ru/bors-third-party/ - это точно также качать Меркуриалом.
hg pull http://hg.balancer.ru/bors-third-party/
hg up
(21:35:16) Balancer: А то, что браузер показывает - это для удобства просмотра. Там, например, все коммиты, история изменений и т.п.
(21:40:49) Balancer: При работе с другими фреймворками была постоянная проблема конфликтов модификаций, когда для подключения своих расширений надо было править исходники чужой разработки, а при обновлениях потом вручную разруливать конфликты модификаций.
Поэтому, когда свой делал, один из главных принципов был- подключение расширений без правки кода ядра. Отсюда и разделение строгое. Ядро ты при работе над конкретным проектом вообще не правишь. Также, как и модули сторонних разработчиков. А всё своё пишешь в отдельном каталоге. Тогда обновить ядро до новой версии - это только hg pull && hg up. Ну, или тупо весь каталог переписать :)
(21:47:54) ????: Хм... Черепаха сказала на "hg pull http://hg.balancer.ru/bors-third-party/" - Abort: repository is unrelated.
Что это? :)
(21:48:42) Balancer: hg init пред этим забыл сказать сделать :)
(21:49:21) Balancer: hg init - создаёт локальный репозиторий
hg pull - утягивает изменения с удалённого репозитория в локальный
hg up - обновляет текущую копию
(21:50:00) ????: Так репозитарий у меня уже создан! Инит ругается!
hg pull http://hg.balancer.ru/bors-third-party/ так и не робит (анрелатед).
(21:50:27) Balancer: Хм. Тогда не знаю. Сейчас в Linux ввёл - всё ок. Пойду скачаю черепаху под винду.
(21:50:32) ????: или надо делать МНОГО репозитариев?
(21:50:59) ????: для ядра - один, а для прочего - другой?
(21:51:03) Balancer: Два, минимум :) Один для ядра, другой для расширений третьих сторон.
(21:51:11) ????: :)
(21:51:15) ????: счаз...
(21:51:46) Balancer: По хорошему ещё сделаешь локальный репозиторий для своих файлов, чтобы локти не кусать, что изменение какое-то запорол :) И коммиты туда делать перед каждым чихом.
(21:53:32) Balancer: Кстати, можешь потренироваться. hg init в .bors-host каталоге.
Делаешь тестовый файл или каталог.
"hg add имя_файла" (можно не абсолютное а из текущего каталоге) - включаешь файл под контроль.
"hg ci" - закоммитить изменения.
Потом, скажешь, грохаешь файл, пишешь "hg up" - и он вернёт его последней версией на последний "hg ci".
(21:54:23) Balancer: hg diff тебе выведет список изменений между последним коммитом в репозитории и текущим состоянием каталогов.
(21:55:26) ????: Да, проблема был в том, что расширения НЕ качались в репозитария ядра. :)
(21:55:33) Balancer: угу, понятно :)
(21:56:51) ????: Такс, сторонние модули развернул. Их тупо копировать в каталог, который мы для них сделали?
(21:57:20) Balancer: Так ты прямо в этом каталоге мог и делать hg init + pull + up :)
(21:57:48) Balancer: Копировать лучше прямо вместе с подкаталогом .hg - тогда обновлять сможешь прямо э
(21:57:53) Balancer: прямо этот каталог
(22:02:34) ????: ААААА!!!!! ВОТ он скрытый смысл!!!!! Точно!!!! Счаз всё прям тудыть и брошу. :)
(22:04:30) Balancer: Если с SVN работал, там похоже - .svn подкаталоги. Только они в каждом каталоге лежать. А в Меркуриал - .hg только в корневом каталоге локального репозитория.
(22:07:54) ????: ====================================================
Кстати, можешь потренироваться. hg init в .bors-host каталоге.
Делаешь тестовый файл или каталог.
"hg add имя_файла" (можно не абсолютное а из текущего каталоге) - включаешь файл под контроль.
"hg ci" - закоммитить изменения.
Потом, скажешь, грохаешь файл, пишешь "hg up" - и он вернёт его последней версией на последний "hg ci".
==========================================
Начинаю....
(22:10:13) ????: Ой, он мне на ЦИ спрашивает про какую-то регистрацию....
(22:10:29) Balancer: Ничего такого не должно быть.
(22:10:46) Balancer: ci == commit, коммит
(22:10:48) ????: Не, он спрашивает про юзернейм.
(22:11:01) Balancer: А! Просто ввести не предлагает? Тогда так.
(22:11:20) Balancer: (это имя пользователя, который делал коммит)
делаешь так:
(22:11:59) ????: Да, что-то можно ввести и выбрать:
- global to this accaunt
- local to this account
(22:12:10) Balancer: global давай
(22:12:30) Balancer: Это можно имя задать по умолчанию для тебя на компе (global) или только в этом репозитории
(22:14:38) ????: странно всё....
На hg ci выдаёт мне текст в блокноте
=================================
HG: Enter commit message. Lines beginning with 'HG:' are removed.
HG: --
HG: user: Kosh@MobileKosh.mshome.net
HG: branch 'default'
HG: added adsutil.vbs
==================================
А в консоли пишет:
transaction abort!
rollback completed
abort: empty commit message
(22:16:05) Balancer: Он открывает файл, в котором тебе надо (обязательно) вписать комментарий к этом коммиту. Типа, что ты делал. В качестве подсказки - список файлов, что будут закоммичены (они закомментированы и в тексте комметария итоговом не будут)
(22:16:40) Balancer: Соответственно, ничего не пишешь - он обламывает, что пустой комментарий коммита.
(22:16:51) ????: ааааа
(22:17:41) ????: ага
(22:19:18) ????: Уря! Заработало! (убил файло, hg up и он восстановился) :)
(22:20:51) ????: Хм... А вот изменения в файле НЕ восстановил. :(
Так и должно быть? Т.е. работает только на удаление? Или что-то не так?
(22:22:00) Balancer: для удобного просмотра истории изменений в консоли инструментов нет, но должны быть в tortoisehg.
изменения пропали, потому что ты удалил его не сделав коммит. он восстанавливает только закоммиченные файлы.
(22:22:44) Balancer: исправил файл.
hg ci
ещё исправил
hg ci
Потом поройся в черепахе в контекстном меню на тему истории изменений.
(22:23:18) ????: Да, а если я хочу, чтобы все файлы в каталоге велись с историей, это мне нужно на каждом hg add? Яж помру! :)
(22:25:08) Balancer: hg add добавляет и каталоги. Со всеми подкаталогами :)
(22:26:31) Balancer: Кроме того, в Linux оно добавляет и файлы по маскам, например,
hg add *.php *.html
В Windows - не знаю, сделано или нет (тут разница в обработках звёздочек - в Windows этим занимается программа, она сама должна рыскрутить шаблон и искать файлы, в Linux этим занимается командный процессор, подсунув программе сразу полный список файлов по одному)
(22:26:34) ????: ладно, это работает.
как сделать Хеллоу ворлд? :)
(22:27:00) ????: Под виндой есть ГУИ, там всё увидел.
(22:28:11) Balancer: Ок, давай дальше.
Напиши, скажем, http://localhost/test/
(или что там у тебя в роли текущего сервера - важно, чтобы ввёл несуществующий каталог)
(22:28:31) ????: и вообще, там где сейчас у меня index.php что-нибудь будет лежать или это вообще пустой каталог будет и весь код будет в борс-хост?
(22:28:45) ????: момент...
(22:28:52) Balancer: Должен вернуть 404-ю ошибку... Я тут на тестовом Денвере вижу, что у него свой обработчик этой ошибки, так что увидишь страничку, где будет сказано об этом.
(22:29:31) ????: Не, Денвер ругается, что страница не найдена, видать перехватывает.
(22:29:42) Balancer: Весь код и шаблоны - в .bors-host
В корне сайта будет статика, доступная из браузера, например, картинки. Аплоады разные. Статический кеш страниц, если они будут очень тяжёлые.
(22:29:56) Balancer: Ок, ругается. Значит, сами перехватим :)
(22:30:09) ????: ввёл "http://localhost/ddfdfd". :)
(22:30:43) Balancer: Сделай в корне файл bors-loader.php пустой, или, там, "<?php phpinfo(); ?> и проверь, что он корректно вызывается, обратившись прямо: http://localhost/bors-loader.php
(22:31:03) ????: В корне - это где?
(22:31:25) ????: C:\WebServers\home\kosh.ru\.bors-host\ - это борс-хост
(22:31:38) Balancer: C:\WebServers\home\kosh.ru\www
(22:31:45) ????: ааа
(22:31:54) Balancer: (отбежал)
(22:33:48) ????: Создал борс-лоадер.пхп. Вызывается ок.
Только у меня настроен виртуальный домен и строка такая "http://kosh.ru/bors-loader.php".
(22:34:26) ????: Но, это так, на всякий пожарный.
(22:45:18) ????: Может немного забегаю вперёд, но:
для config.php для строки "/var/www/.bors/bors-core" какой в моём случае будет каталог?
bors-loader лежит в "C:\WebServers\home\kosh.ru\www\".
(22:45:58) ????: C:\WebServers\home\kosh.ru\.bors-core\ ?
(22:47:56) Balancer: config.php твой будет лежать в .bors-host.
Напомню, что в .bors-core тебе нет надобности писать ничего вообще :)
(22:48:13) Balancer: Поехали дальше. Сейчас проверю, как Денвер обрабатывает .htaccess
(22:48:22) ????: Для справки:
Я в каталоге kosh.ru создал каталоги
.bors-core
.bors-host
.bors-third-party
www (изначально был).
Может стоил сделать каталоги как в конфиге, т.е. всё положить в один каталог bors?
(22:48:56) Balancer: Нет, оставь, как есть, всё нормально.
(22:49:40) ????: И config.php в bors-core тоже не править? :)
(22:58:10) Balancer: Да, это по сути не конфиг, а инициатор :)
...
Поехали дальше, я вернулся :)
В корне сайта (т.е. в www) делаешь файл .htacess
Это настройки Апача, для текущего каталога и его подкаталогов.
Нас сейчас интересует директива ErrorDocument
Она принимает два параметра - код перехватываемой ошибки (страница не найдена - это 404-я ошибка) и web-ссылка обработчика этой ошибки.
Т.е. написать в .htaccess надо будет:
ErrorDocument 404 /bors-loader.php
И тогда вместо всех неизвестных страниц будет грузиться /bors-loader.php
Сделай и проверь.
(23:00:17) ????: Пока получил 404-ую ошибку... счаз посмотрю, почему не грузится лоадер...
(23:00:41) Balancer: Нет, стой, скорее всего всё ок. Объясняю :)
(23:00:59) Balancer: Ты, наверное, в bors-loader.php не phpinfo оставил, а что-то своё?
(23:01:28) ????: Упс. :) Ага. "I am bors-loader.php". :)
(23:02:21) ????: Теперь всё ОК!
(23:02:23) Balancer: Браузер, отдавая документ, всегда возвращает статус документа в ответе сервера (браузер его не показывает).
Если всё ок - то статус 200.
404 - не найдено
301 - перемещено в другое место навсегда
и т.п. - многие десятки.
(23:03:06) ????: да, да, я проходил на курсах эти коды, но уже не помню большинство из них. :)
(23:03:14) Balancer: Мы в bors-loader пока не переопределили 404-й статус на 200-й. А смотришь ты, как я понимаю, в IE, который смотрит только на статус и, если он 404-й, то не обращает внимания на контент. Опера или Firefox бы вывели твой текст.
(23:03:33) ????: IE
(23:03:46) Balancer: phpinfo() автоматом до кучи в 200-й статус ставит.
чтобы пока статусом не заморачиваться, пропиши вызов этой функции.
(23:03:48) ????: с пхп кодом борс-лоадер подхватился.
(23:05:08) Balancer: А так, на будущее, в PHP это будет:
header("Status: 200 OK");
Вызвать надо до первого вывода любого контента, т.е. до любых echo, print и т.п. Т.к. браузеру сперва передаётся заголовок, а потом - контент.
(23:06:45) ????: Да, что-то такое припоминаю (а ведь даже года с курсов не прошло, а уже позабывал 50%). :)
(23:06:54) Balancer: Дык, без практики :)
(23:07:11) ????: Всё работает. Что дальше? :)
(23:07:34) Balancer: Можно несколько лет чем-то прозаниматься и помнить в состоянии любого опьянения, а через пару лет бездействия - забыть.
...
Сейчас займёмся вызовом фреймворка.
(23:13:13) Balancer: Пиши в bors-loader.php
<?php
define('BORS_CORE', 'C:/WebServers/home/kosh.ru/.bors-core');
require_once(BORS_CORE.'/config.php');
require_once(BORS_CORE.'/main.php');
(23:13:30) Balancer: И жми F5 в браузере. По идее, должен выдать пустую страницу :)
(23:13:46) Balancer: По умолчанию нет никакой реакции на отсутствие страницы.
(23:14:24) Balancer: Кстати, ты файлы в чём редактируешь?
(23:17:01) ????: По мелочи в фаре, а так в Нотепад++.
(23:17:33) Balancer: В Фаре рекомендую поставить ширину таба в 4, если у тебя дефолтовая в 8 :) А то сильно расползаются сорцы.
(23:18:01) ????: я получил ответ Link error
(23:18:45) ????: Причём не обрамлённый html кодом, а просто строка.
(23:20:16) Balancer: Гм. У меня в Денвере всё вышло.
link error - в браузере? В окне страницы или в попапе?
(23:20:38) Balancer: Ядро лежит в C:/WebServers/home/kosh.ru/.bors-core?
(23:21:11) ????: в окне страницы.
скорее всего ошибка с путём к едру.
счаз точнее проверю
(23:22:08) Balancer: Соответственно, файл должен быть:
C:\WebServers\home\kosh.ru\.bors-core\config.php
(23:23:42) ????: он есть, только там есть ещё определения, а в них всякие "/var/www/.bors/bors-local".
Может в этом дело?
(23:24:01) Balancer: Нет, это другое.
(23:24:21) Balancer: Там, типа, если нет определения такого-то дефайна, то ставим такое-то.
(23:25:17) Balancer: А ссылку другую попробовать? Ты что вводил? М.б. попал случайно на что-то системное? :)
И bors-loader.php из FAR'а глянь, мусора там какого-нибудь нет?
(23:25:25) Balancer: А Апач не упал, вообще?
(23:25:35) ????: config.php 100% запускается, т.к. я туда воткнул вывод текста и увидел его. (счаз всё уберу) :)
(23:26:45) Balancer: а... Ладно, тогда давай так.
В C:\WebServers\home\kosh.ru\.bors-host\config.php
впиши один параметр:
<?php
config_set('404_show', true);
(23:27:06) Balancer: Теперь он, если в остальном всё ок, на отсутствие страницы выдаст текстом, что не найдена.
(23:27:07) ????: "Там, типа, если нет определения такого-то дефайна, то ставим такое-то." - правильно. LOCAL мы не определяем и он определяется из config.php, а это "/var/www/.bors/bors-local", а у меня ВАРОВ-то нет, яж винда!
(23:27:55) Balancer: Нет, и не надо :) Он не грузит оттуда, не проверив, что каталог такой есть. Я же параллельно в VirtualBox'е с Денвером тоже ковыряюсь для тестов, там тоже /var/'ов нету :)
(23:28:31) Balancer: А у меня оно с первого раза завелось. Точно также, сорцы качал Черепахой, Денвер с сайта с дефолтовыми настройками. Только что я в localhost тестирую.
(23:28:39) ????: Хм... С "config_set('404_show', true);" всё равно линк еррор
(23:28:58) Balancer: Можешь что-нибудь в этот config вписать и посмотреть, покажет ли.
(23:29:15) Balancer: По крайней мере, будет ясно, ошибка на этапе конфигурирования или вывода.
(23:29:20) ????: да, яж вписывал и он показывал.
(23:29:31) Balancer: В .bors-host
(23:30:34) ????: В борс-коре/конфиг.пхп я влепил перед пхп-кодом строчку и браузер эту строчку показал, а потом следом показал ЛИНК ЕРРОР.
(23:30:44) ????: В борс-хост?
(23:31:10) Balancer: Тьфу, я тормоз. Это Link error у меня выдаётся. Когда кто-то вызывает bors-loader.php напрямую :) Ты его вызываешь или отсутствующую тестовую страницу?
(23:31:29) ????: я ЕГО вызываю.
(23:31:48) Balancer: Гы. Вызывай какой-нибудь /test/ :)
(23:31:55) ????: ща
(23:32:28) ????: еррор 404
(23:32:49) Balancer: config_set('404_show', true); в .bors-host/config.php стоит?
(23:33:18) ????: а в борс-хосте у меня ВВОБЩЕ пусто! :)
(23:33:36) Balancer: Вот там сделай config.php - через него будешь систему конфигурить.
(23:33:45) ????: похоже путаница между ХОСТ и КОРЕ.
(23:34:07) Balancer: Сделай в ХОСТЕ (который пустой) config.php :)
(23:34:22) Balancer: Он грузится после КОРЕ и позволяет переопределить любые параметры.
(23:35:13) Balancer: core - ядро системы.
host - конкретный сайт.
(23:35:43) Balancer: (ещё есть local - конкретная система, комп, это между ядром и сайтом, но нам в ближайшее время не понадобится)
(23:36:45) ????: Я запутался.
В борс-лоадере в дефайне мы прописали борс-КОРЕ.
ОТКУДА апач поймёт, что надо лезть а конфиг в борс-ХОСТ?
(23:37:42) Balancer: В .bors-core/config.php загляни, в самый верх. 9-я строчка :)
Он его вычисляет, если не указан. Как корень_сайта/../.bors-host/ :)
(23:38:05) Balancer: Если по другому адресу - тогда надо будет указать явно.
(23:38:47) Balancer: Аналогично сторонние расширения ищутся в одном каталоге с .bors-core, в подкаталоге .bors-third-party
(23:40:15) Balancer: Я когда делал систему, старался минимизровать для себя уровень писанины при разворачивании нового сайта :)
(23:40:27) ????: Ага, значит вот что я выяснил:
если запускать борс-лоадер НАПРЯМУЮ, то конфиг в ХОСТ отрабатывает, но получаю ЛИНК ЕРРОР.
если борс-лоадер запускается через ЛЕВУЮ страницу, но в ответ "еррор 404"
(23:40:59) Balancer: Напрямую не вызывай, там блокировка стоит специально, так как прямой вызов смысла не имеет.
Вызывай через левые страницы.
(23:41:05) ????: "но в ответ" = "ТО в ответ"
(23:41:07) Balancer: .bors-host/config.php прописал?
(23:42:06) ????: да.
вот что там
config_set('404_show', true);
?>
(23:42:43) Balancer: Хм. Странно. Должно работать. А этот конфиг вызывается? Впиши туда чего-нить.
(23:43:06) ????: Вызывается ТОЛЬКО при вызове лоадера НАПРЯМУЮ.
(23:43:23) ????: Иначе НЕ вызывается.
(23:44:00) Balancer: Ясно. Значит, у тебя не отрабатывается перехват ошибки.
Проверь .htaccess - там точно:
ErrorDocument 404 /bors-loader.php
?
(23:44:33) ????: Да. Сейчас попробую рестартануть денвер.
(23:45:22) Balancer: Можно вернуться для теста к началу.
Впиши в bors-loader.php только один
<?php phpinfo();
Если при вызове левой страницы выведется php-info- то с перехватом 404-й всё ок.
(23:45:28) ????: Не, рестарт НЕ помог. :(
(23:46:50) ????: Странно, похоже что-то сломалось. Сейчас полазаю.
(23:47:53) Balancer: Файл www\.htaccess
В нём: ErrorDocument 404 /bors-loader.php
(23:48:21) ????: Не, не, похоже что-то с кешем в IE и пр. Счаз победю.
(23:49:35) ????: Так, пхп инфо вызывается на ЛЕВОЙ странице. Иду дальше...
(23:50:22) ????: ВСЁ! ОК!
Я получил "Page 'http://kosh.ru/bors-loader-qqqqqqqqqqqqqqqqqqqqqqqqqqqqqq.php' not found".
ОНО?
(23:50:29) Balancer: :)
(23:50:32) Balancer: Оно.
(23:50:41) ????: Уф...
(23:50:49) Balancer: Теперь небольшая интермедия.
(23:51:36) Balancer: Иди в .bors-core
Там в .hg сделай файл hgrc с таким контентом:
[paths]
default = http://hg.balancer.ru/bors-core/
(23:52:00) Balancer: Это значит, что по pull без указания адреса он будет дёргать изменения с указанного адреса.
(23:52:33) Balancer: Потом снова в каталоге .bors-core сделай hg pull
и потом - hg up
Я там закоммитил несколько сегодняшних правок :)
(23:52:46) Balancer: Разберёшься, как забирать изменения.
(23:53:53) ????: готово.
всё забрал
(23:54:13) Balancer: всё, идём дальше.
(23:54:19) ????: удобно!
Не надо помнить для какого каталога что в пулл писать!
(23:54:47) Balancer: Угу. Аналогично можешь и для .bors-third-party прописать, но он редко обновляется :)
(23:55:35) Balancer: А, да. В эксплорере в этом каталоге в контекстом меню Черепахи можешь вызвать View Changelog и посмотреть что конкретно менялось.
(23:56:12) Balancer: Тоже полезно. Особенно, когда сам будешь работать с локальным репозиторием в .bors-host или других своих проектах, не обязательно web :)
(23:56:34) ????: Ага.
(23:56:45) Balancer: А так - всё, система развёрнута. Можно писать Hello World :)
(23:56:54) ????: Готов писать
(00:01:38) Balancer: Так, поймал первый глюк, связанный с Windows :) Но легко устранимый. Каталог со сторонними пакетами неверно вычисляется, так что пока в bors-loader пропишем явно:
define('BORS_3RD_PARTY', 'C:/WebServers/home/kosh.ru/.bors-third-party');
Это между define BORS_CORE и require config
(00:02:16) Balancer: (а то он от винды получает путь с обратными слешами, а добавляет с прямыми и у PHP сносит башню :) )
(00:03:14) ????: Готово
(00:03:20) Balancer: Дальше, сперва простейший статический тест на готовом движке.
Делаешь каталог www\page1 (т.е. page1 в корне)
В него кидаешь файл .title.txt с любым текстом - это будет заголовок страницы.
(00:04:12) Balancer: Теперь ещё немного настроек. По умолчанию в Денвере разрешён показ каталогов. Если ты вызовешь сейчас http://kosh.ru/page1/, то он покаже этот каталог. Пустой, так как имена, начинающиеся с точки, Апач игнорирует.
(00:04:27) Balancer: (можешь проверить загрузив эту страницу)
(00:04:54) Balancer: Нужно запретить показ каталогов.
Это в .htaccess
команда:
Options -Indexes
(00:05:05) ????: Файл титле.тхт с точкой ПЕРЕ титле?
(00:05:09) ????: ПЕРЕД?
(00:05:09) Balancer: Да.
(00:05:42) Balancer: Теперь при попытке вывода страницы /page1/ должна вылететь 403-я ошибка.
(00:05:52) Balancer: Убедись, что оно так :)
(00:05:58) ????: да, показал ПУСТОЙ каталог.
счаз...
(00:06:43) Balancer: У меня потому все служебные файлы с точек и начинаются. И не только у меня, тот же Апачевский .htaccess - такие файлы Апач не показывает и при попытке считать прямо - не даёт их.
(00:07:02) ????: Получил от денвера "You don't have permission to access /page1/ on this server."
(00:07:26) Balancer: ага
(00:07:37) ????: А в нтакссес есть комментарии?
(00:07:47) ????: Типа //
(00:08:00) ????: Точнее можно их там вставить?
(00:08:17) Balancer: Теперь дальше уже по нкатанной. Нужно повесить обработчик 403-й ошибки:
ErrorDocument 403 /bors-loader.php
В добавление к тому, что там есть.
Комментарии во всех Linux-конфигах (и даже в PHP :)) - # в начале строки.
(00:09:13) ????: ЁЁЁУУУ! Я получил
==================================
I am a Title!
I am a Title!
====================================
(00:09:31) ????: I am a Title! - это текст в титле
(00:10:24) Balancer: :)
Ещё в .source.txt можешь вписать исходный текст страницы.
(00:10:26) ????: Хм.... А теперь сломалось.... Хм....
(00:10:40) ????: Опять 403 ошибка...
(00:11:18) Balancer: А что менял?
(00:12:28) ????: А ничего.
Получил "I am a Title!
I am a Title!", где первый "I am a Title!" - это ссылка. Ткнул туда, получил 403 ошибку. ... И всё, теперь на page1 постоянно 403
(00:12:51) Balancer: А F5? :)
(00:12:57) Balancer: Адрес страницы /page1/ ?
(00:14:05) ????: да, http://kosh.ru/page1/.
Да уже обновлял 100 раз, даже всё перезапустил.
(00:14:54) ????: Странно, опять слетел обработчик 404: на левую страницу говорит 404.
(00:15:16) Balancer: Хы. У меня всё вообще круто :D Ткнулся в ссылку. Получил 403-ю ошибку. Гажал F5 - получил пустой каталог, как с Options Indexes :) Т.е. налицо кеширование. Ещё раз F5 - нормальная страница. Есть у меня мысль, надо проверить сейчас.
(00:18:21) ????: Я вспомнил. Нам на курсах говорили, что у осла надо отрубать автоматическое обновление страниц, точнее ставить его "Обновлять страницы при каждом просмотре"
(00:20:02) ????: Не, всё равно опять не работает перехватчик 404.... чудеса млин...
(00:20:09) Balancer: Нет, не в этом дело. Проблема в Денвере :)
В общем, он в хедер гонит статус не в том формате, как принято.
И в заголовках идёт Statis: 200 Ok, но HTTP/1.1 403 :)
В общем, надо будет подумать над этим, а пока так сделай:
(00:20:53) Balancer: .bors-core\engines\bors\object_show.php
Раскомментировать 11-ю строку:
@header("HTTP/1.1 200 OK");
(00:21:47) Balancer: У меня система оба статуса выдавала, но когда-то на каком-то хостинге 1.1 статус стал ошибки выдавать. Надо выводить этот ответ по условию будет, если Windows-платформа, то отдавать :)
(00:22:37) ????: Сделал.
Титле заработал. Однако ЛЕВАЯ страница всё-равно 404.
(00:22:59) Balancer: Хм. А должно быть "такая-то - не найдено" :)
(00:23:04) Balancer: Сейчас у себя гляну.
(00:23:24) ????: ага, и ведь БЫЛО!
И ведь ничего не менял!
(00:23:34) ????: вроде...
(00:24:07) Balancer: А, ладно, пока забей. Так и должно быть в случае Денвера. Я же перед "не найдено" не вывожу хедеры.
...
А прошлый раз было из-за IE-шной фичи. Он такие страницы через раз то показывает, то ошибку выдаёт :)
(00:24:30) Balancer: Пару минут перерыв :)
(00:24:43) ????: а, нен вопрос, счаз фоксу гляну
(00:25:59) ????: ТОЧНО! Ну IE мать его так разтак! :)
Лиса всё нормально кажет.
(00:27:17) Balancer: Ок, можно дальше.
Варианты:
1) простейшая страница уже со своим кодом, но пока как чёрный ящик.
2) разобрать основной принцип, как работает механизм вывода в только что сделанном статическом варианте?
3) показать, как делать для таких страниц свои шаблоны.
Одно от другого не зависит, так что выбирай, что интереснее :)
(00:27:58) ????: 3
(00:28:55) ????: Я видел в модулях Смарти....
(00:29:44) Balancer: Ага. Знаком с ним, нет?
(00:30:05) ????: Нет, но знаю, что это шаблонизатор и всё. :)
(00:30:52) Balancer: В общем, шаблонизаторы в системе могут быть любые, в т.ч. и сам PHP (он по своей натуре - сам изначально шаблонизатор, просто синтаксис для дизайна неудобный), но по умолчанию у меня используется Smarty.
(00:31:01) ????: Т.е. теории я начитался, аж мозги рвутся. :))
(00:32:25) ????: Я так понимаю, шаблонизатор нужен, чтобы код от разметки отдалить?
(00:33:15) Balancer: При штатном использовании всю заботу по насыщению шаблонов данными и их отдачу берёт на себя система. Важно помнить, что у меня используются шаблоны двух уровне.
1. Шаблон всей страницы. Условно - глобальный. Обычно это базовые шаблоны на весь сайт. Шапка, поддон, всякие панели навигации и т.п. В этот шаблон, наряду с другими параметрами, вставляется тело страницы. Грубо говоря - основной текст.
2. Это тело генерится отдельными шаблонами. Локальными. Т.е. в одном общем дизайне может быть разный контент.
(00:33:56) Balancer: Да, с помощью шаблона код отделяется от дизайна. Если совсем точно - то код подготовки данных от кода вывода, так как в шаблоне тоже может быть свой код - условные операторы, циклы и т.п.
(00:34:01) ????: ага...
(00:35:32) Balancer: Вот, локальные шалбоны обычно валяются рядом со своими классам. Т.е. занимается класс выводом новостей, и шаблон, который из массива новостей слепит внутреннюю часть страницы с текстом лежит рядом с этим классом. Связыванием их тоже фреймворк занимается.
Глобальные лежат в каталогах templates в BORS_CORE/BORS_LOCAL/BORS_HOST.
(00:36:13) Balancer: По умолчанию грузится шаблон default/index.html, который, соответствено, по умолчанию находится в BORS_CORE/templates/default/index.html
(00:36:25) Balancer: Можешь посмотреть, он совсем примитивный.
(00:36:38) Balancer: Даже w3c-невалидный :)
(00:36:57) ????: смотрю...
(00:37:52) ????: открыл его в браузере.
вполне стройно
(00:38:45) Balancer: В принципе, по тем элементам, что там используются, должно быть понятно,что к чему. Переменные, условие.
Комментария требует только {module} - это расширение, которое грузит класс фреймворка. В данном случае - рисующий навигацию.
(00:38:58) Balancer: (верхняя сылка)
(00:39:22) ????: ага, примерно так и понял
(00:39:46) Balancer: Чтобы использовать свой шаблон, его кидать нужно в BORS_HOST/templates, например. Можешь скопировать туда этот, по тому же адресу, и поломать его :)
(00:40:20) Balancer: Из браузера, кстати, смотреть фигово, чуть посложнее - и врать будет. У тебя Far с плагином Colorer?
(00:40:38) ????: Т.е. шаблоны сначало ищутся в текущем каталоге и если есть то юзаются, а если нет - то и коре?
(00:40:43) Balancer: да
(00:41:06) Balancer: И эта идеология на всё распространяется - на шаблоны, классы, расширения разные.
(00:41:12) ????: Счаз гляну про плугин
(00:41:36) Balancer: Это синтаксическая раскраска Far'овского редактора. Я не представляю, как без неё жить можно :)
(00:41:44) ????: Не, кулера нет, стоят стандартные
(00:41:56) Balancer: Не cooler, а colorer :) Сейчас найду.
(00:42:05) ????: поэтому и юзаю Нотепад++
(00:42:07) ????: :)
(00:43:13) Balancer: А, попутно.
Можешь скачать и кинуть куде-нить в %PATH:
http://users.ugent.be/~bpuype/wget/#download
wget - аналог линуксовой качалки файлов. Может пригодиться потом для изучения ответов сервера. Я сегодня проблему с 403-й ошибкой им ловил.
(00:43:40) Balancer: А вот colorer: http://colorer.sourceforge.net/farplugin.html
(00:47:13) ????: Забадяжил изменённый шаблон в ХОСТ - работает. :)
[...]
(17:21:47) ????: Да не, до БД ещё я даже не дошёл.
Я так и не понял как передать управление кому-нибудь типа main.php и пр.
(17:25:11) Balancer: В каталогах handlers (в нашей триаде BORS_CORE/BORS_LOCAL/BORS_HOST) в файлах bors_map.php лежат привязки регекспов URL'ов к классам, которые их обрабатывают. Система перебирает всё подряд, если находит подходящий регексп, пытается загрузить класс. Если удачно - запускает отображение страницы этим классом. Нет - перебирает дальше.
Классы грузятся (в той же триаде) из подкаталогов classes/ или classes/bors/ по принципу - имя класса режется на куски пути по подчерками. Т.е. class rp1990_project будет искаться в classes/bors/rp1990/project.php (сделано, чтобы не мучиться с длинными именами файлов).
(17:27:54) ????: Ааа! А я то думаю, что за структура каталогов такая запутанная!?
Да, видел я этот map.
(22:04:07) ????: Я готов позаниматься. :)
Правильно-ли я понял, как всё работает:
1. Борс-лоадер передаёт управление ядру (main.php).
2. Ядро перебирает последовательно BORS_CORE/BORS_LOCAL/BORS_HOST, ищет карту в каталогах handlers. Если карта, к примеру, найдена в BORS_LOCAL, и в этой карте указан класс, который существует, то ядро запускает этот класс.... А дальше что? Т.е. класс выполнился и отдал управление ядру, которое пошло дальше парсить карты или найдя 1 удачный класс, ядро отдаёт ему управление и всё, с концами.
(22:29:23) Balancer: Да, с началом - всё ок. Правильно понял. После того, как класс найден и успешно загружен, дальше формированием вывода занимается он. Блок, загрузивший класс дёргает его метод content() и потом выводит полученное в браузер.
(22:29:31) ????: Да, ещё: а для чего разделение на BORS_LOCAL и BORS_HOST?
(22:30:59) ????: Так после успешного запуска первого найденного класса, ядро запускает остальные классы в карте или нет?
(22:31:51) ????: И ещё по поводу регэкспов: они там обязательны? Просто я не знаю синтсксис регэкспов...
(22:32:05) Balancer: На одном сервере может быть несколько сайтов. Настройки и классы могут касаться одного конкретного сайта (виртуального хостинга, BORS_HOST), а могут - всего компьютера (BORS_LOCAL - локальные, имеется в виду относительно ядра, общего для всех проектов).
(22:32:29) Balancer: После успешной загрузки класса следующие не грузятся. Ядро завершает работу.
(22:35:37) Balancer: Регекспы обязательны. Синтаксис очень простой. Ближайшая аналогия - маски файлов в DOS/Windows. Тут то же самое, но немного шире.
Например, звёздочка обозначает 0 или более символов. Но, если в случае масок символы любые, то в регекспах - только указанные. Поэтому перед звёздочкой будет указан символ, которых может быть 0 или более. Кроме явных символов, типа a-z, 0-9 и т.п. есть группы символов.
Например, точка указывает на любой символ вообще. Т.е. при просмотре в DOS всех текстовых файлов маска будет "*.txt", а в случае регекспов маска будет ".*\.txt" - обратный слеш перед второй точкой - это экранирование. Чтобы эта точка рассматривалась как простой символ, а не метасимвол.
(22:36:01) Balancer: Есть другие метасимволы. Например:
\s - любой пробел
\d - любая цифра
(22:37:12) Balancer: Модификатор "?" как и в случае масок обозначает 0 или 1 символ. Т.е. необязательный символ.
"/test/?" - этой маске будут отвечать и "/test" и "/test/", но не "/test1", например.
(22:38:20) ????: ага...
(22:38:29) Balancer: Модификатор "+" аналога в дос-масках не имеет - это один или более символов. Например:
"/news/\d+/\d+/\d+/" - этой маске будут отвечать строки вида "/news/2009/02/12/". Равно как и "/news/09/2/12/" - т.е. всюду символов 1 или более указано.
(22:38:42) Balancer: Не любых символов, а цифр.
(22:40:15) ????: ну да.
(22:40:28) Balancer: Можно задавать перечисления символов в квадратных скобках.
Например, \d - это то же самое, что [0123456789]
Т.е. квадратные скобки обозначают символ, но один из перечисленных.
"/news/[0123456789]+/"
(22:42:25) Balancer: Гораздо чаще в квадратных скобках указывают диапазоны символов через минус. Он заменит все символы между тем, что слева от него и тем, что справа. Т.е. тот же \d - это [0-9]
"/news/[0-9]+/"
Можно задавать несколько диапазонов:
[0-9a-zA-Z] - это все буквы или цифры.
Есть метасимвол \w - он заменяет любые алфавитно-цифровые символы. Т.е. [0-9A-Za-z_] (подчерк тоже входит)
(22:45:58) Balancer: При регексповом поиске можно выделять определённые цепочки символов, чтобы потом использовать. Делается это скобками.
"/news/(\d+)/" - позволит потом вытащить сразу год.
Есть такое понятие, например, как замена по регекспам. В PHP для этого служит функция preg_replace($from, $to, $str);
$from обязательно в начале к конце содержит символ ограничитель. Например, "!".
Тогда замена вида
echo preg_replace("!/news/(\d+)/!", "year=$1", "/news/2009/");
выведет year=2009.
Это важно, если что-то тут непонятно - спроси.
(22:46:11) ????: Т.е. по маску "/news/[0-9]+/" подходят:
1. "/news/5вввввв/"
2. "/news/3333333/"
3. "/news/0аааааааааааа3434ооооооооооооо3434343ооооооооо09090909кк3384738473/"
Так?
(22:47:06) Balancer: нет. Только 2.
(22:47:34) Balancer: Т.е. /news/, потом любое число цифр и только цифр, потом - слеш. Этому только 2-й пример отвечает.
(22:47:56) ????: Т.е. "+" - это цифры?
(22:48:29) ????: Или "+" смотрит на предыдущие символы?
(22:48:31) Balancer: + - это один или более символов, указанных перед ним. В нашем случае это [0-9]
(22:48:37) Balancer: Да, + - это модификатор
(22:50:27) Balancer: /news/[0-9]/ - этому отвечает /news/1/ или /news/5/, но не /news/55/ - т.к. указано, что цифра между слешами только одна.
А вот /news/[0-9]+/ - это и /news/55/. Но не /news/55z/, так как кроме цифр между слешами ничего не указано.
(22:51:11) Balancer: А вот /news/[a-z0-9]+/ - это и /news/55x/ и /news/76sdc76sdcsdc/ - любое число букв и цифр.
(22:51:59) Balancer: А вот так:
/news/[0-9]+[a-z]+/ - это /news/789as/, но не /news/as789/ - так как между слешами строго сперва любое число цифр, потом- любое число букв.
(22:53:14) Balancer: И это не /news/768/, так как букв указано 1 или более, т.е. хотя бы одна нужна.
А вот /news/[0-9]+[a-z]*/ - это и /news/999zzz/ и /news/0/ - тут цифры обязательны ("+"), буквы - нет ("*").
(22:53:39) Balancer: Для /news/[0-9]*[a-z]*/ подойдёт даже /news// :)
(22:55:35) Balancer: (пока понятно)?
(22:55:38) ????: =========================
Тогда замена вида
echo preg_replace("!/news/(\d+)/!", "year=$1", "/news/2009/");
выведет year=2009.
===========================
Тут с $from более-менее понятно. А вот откуда $1? Это специальное обозначение?
(22:57:00) Balancer: $1 - это специальное обозначение первой пары скобок. Точно также можно использовать \1.
echo preg_replace("!/news/(\d+)/(\d+)/!", "year=$1, month=$2", "/news/2009/02/");
выдаст: year=2009, month=02
(22:57:32) ????: И по поводу $str. Она в данном случае может быть такой: "кекеке5/вывывыв/43434/news/2009/еененене/"?
(22:58:54) ????: Или мне надо специально подготавливать $str из которой я буду вырезать что-то?
(22:59:00) Balancer: Да, в данном случае подойдёт под первый вариант. Результат будет:
кекеке5/вывывыв/43434/year=2009еененене/
(22:59:13) Balancer: Т.е. идёт замена подстроки.
(22:59:36) Balancer: Если подстрока соответствующая не находится - то замены не происходит, результат - исходная строка без изменений.
(23:00:20) Balancer: Есть спецсимволы, обозначающие начало и конец строки - "^" и "$".
Т.е. если шаблон будет "!^/news/(\d+)/$", то твоя строка не пройдёт.
(23:00:43) Balancer: Но пройдёт под такой шаблон: "!^.*/news/(\d+)/.*$!" - понятно, почему?
(23:01:23) ????: Стоп. Если эта замена возвращает всю строку, к примеру вернёт "кекеке5/вывывыв/43434/year=2009еененене/", то нафига она мне? Мне же нужно только "year=2009". :)
Или я что-то не понял?
(23:02:13) ????: Т.к. звёздочки любое кол-во символов?
(23:03:04) Balancer: Мой последний шаблон вернёт только то, что нужно. Потому что .* указано. Поэтому будет рассмотрено, но в результат не передастся.
"*" - 0 или более символа, указанного перед ней.
"." - любой символ
".*" - любое число любых символов.
(23:03:16) ????: ааааа...
(23:04:30) ????: А зачем мне менять регэкспом что-то в строке?
Вот я понимаю: распарсить строку и вытащить из неё, к примеру, год/месяц/день. :)
(23:04:31) Balancer: "a*" - любое число букв а, в том числе нулевое.
...
Вот пример - как в строке все переводы строк, числом больше одного заменить на один:
$str = preg_replace("!\n+!", "\n", $str);
(23:04:59) Balancer: Вот это и используется в файле bors_map и к чему я подвожу :) Сейчас пример.
(23:07:37) Balancer: Сперва - не очень удачный, потом объясню почему:
"/news/(\d+)/(\d+)/(\d+)/ => my_super_calendar(NULL,year=1,month=2,day=3)
Тут нету $ перед номером группы для упрощения, всё равно у меня там обработка идёт большая. Перед маской всегда принудительно дописан "^", после - "$".
NULL в начале- так как там обязательно ID объекта класса. Последующие параметры парсер засунет в массив и передаст классу как аргументы. Можно потом вызвать как $y=$this->args('year');
(23:10:35) ????: Кстати, мы в PHP не юзали классы ВООБЩЕ.
ООП было у нас только на Java.
Поэтому я не очень понимаю, что означают стрелки "=>" и "->" и т.п.
Можешь чуток пояснить...
(23:10:58) Balancer: Но тут пример класса не удачен. Так как рекомендован принцип - класс должен полностью идентифицироваться своим ID. Это позволяет кешировать класс. Так что лучше не разбирать параметры ссылки, а отдать в класс целиком в качестве идентификатора и разобрать уже в нём:
"/news/(\d+/\d+/\d+)/ => my_another_calendar(1)"
А в классе уже, если нужно, можно так:
list($year, $month, $day) = explode("/", $this->id());
explode - разрезает строку на массив подстрок, используя в качестве разделителя указанный символ
list(...) - позвояет присвоить указанным переменным сразу массив, разложив по порядку элементы.
(23:12:13) Balancer: В этом примере "=>" - это не конструкция языка, это разделитель, который я использую.
"->" - доступ к элементу класса. Как "." в Java. Синтаксис взят из Си++, там оба варианта, "." для доступа к объектам, которые лежат в переменных, "->" - если в переменной не сам объект, а указатель на него.
(23:12:32) Balancer: Т.е. $this->id() - это как this.id() в Java
(23:12:51) Balancer: Или там self.id() - уже вылетело из головы :)
(23:13:06) ????: Ааааа.... Ё-моё... А через . я могу писать в PHP? Мне так роднее. :)
(23:13:35) Balancer: Нет, через точку в этом случае нельзя. Там через точку только доступ к именованным элементам хеш-массива.
(23:14:38) Balancer: Но в языке "=>" тоже есть. Так хэш-массивы заполняются. В Java класс HashMap изучали? Ассоциативные массивы?
(23:15:19) ????: Ясно.
Резюме:
Если $my_param - это ссылка, то его id получаю как $my_param->id().
А если $my_param - это объект? Или такого не может быть?
(23:16:04) Balancer: В PHP все объекты передаются по ссылкам. Как и в Java :)
$x = new Class();
и в $x у тебя ссылка на объект класса Class.
(23:16:07) ????: Это где ключ может быть любым?
(23:16:12) Balancer: Да.
(23:16:48) ????: Да, но я уже не помню нюансы. В 1C это зато сплошь и рядом. :)
(23:18:14) ????: А, ну да, ну да... Это меня 1С испортило, там я могу получить ОБЪЕКТ. :)
(23:18:57) ????: Да, я знаю эти массивы.
(23:19:28) ????: В 1С они называются структурами.
(23:19:32) Balancer: Вот, такой массив можно сразу и так инициализировать:
$a = array("qwe", "test" => "asd");
(23:19:52) Balancer: У меня такой метод очень часто используется для описания полей БД.
(23:20:39) ????: ага, припоминаю, мы тоже это проходили... надо будет тетрадку достать (я прилежно учился, аж красный диплом получил :) ).
(23:21:21) Balancer: :)
(23:22:17) Balancer: Давай пока ещё вопросы, надо это всё разобрать, прежде чем дальше пойдём. Особенно - регекспы, раз про вызовы класса задумались.
(23:25:54) ????: Помню особенно были в восторге преподы ASP.NET и Java.
На ASP.NET я с лёгкостью решил какую-то хитрую задачку, там на форму выводился алфавит, каждая буква была ссылкой и при нажатии на неё по таблице был отбор по этой нажатой букве.
А на Java, помнится, я наваял инет магазин, который работал на Oracle, везде используя хранимые процедуры... я чуть голову не сломал, пока это изобретал, зато препод был просто в восторге.
Да... мемориз... :) Ой, я что-то отвлёкся. :)
(23:27:01) Balancer: :)
(23:27:52) Balancer: Я с ASP.Net не работал никогда, а на Java курировал большой проект LineageII сервера. Там что-то на многие магабайты только исходников :)
(23:27:56) ????: Да что по регэкспам.... яж их плохо знаю, поэтому мне нечего особо спросить... Я уж когда вспоткнусь обо что-нибудь, тогда и спрошу, ок?
(23:28:26) Balancer: Ну, короче, будешь в bors_map.php смотреть, что непонятно - спросишь :)
Ок, давай дальше. По порядку генерации страницы?
(23:29:44) ????: Ага.
Ок, наверное.
Мне что интересно, запустить локально rp! Можно просто по порядку, как и что там работает. :)
(23:30:25) Balancer: До rp ещё долго. Там БД понадобится. Если хочешь, могу залить мелкий проект, где работа без БД идёт :) www.tibr.info :)
(23:30:25) ????: Просто, когда я буду ВИДЕТЬ результат, пускай и с ошибками, я смогу ЭКСПЕРИМЕНТИРОВАТЬ!
(23:30:41) ????: Ок, конечно!
(23:31:30) ????: Начинать-то надо с простого! А то rp уж слишком запутанным оказался. :)
(23:32:24) Balancer: Да, он хоть и сильно уступает по структуре тому же www.aviaport.ru, но среди моих сторонних проектов- на втором месте по сложности, наверное :)
(23:33:52) ????: Ааааа, ну кудаж мне тогда вот так сразу в нём и разобраться! :)
Это, наверное, как пещёрному человеку жигули дать и сказать, что ОНО ЕЗДИТ, РАЗБИРАЙСЯ. :)) :))
(23:35:43) Balancer: Закинул тебе tibr на kosh.wrk.ru (не на сайт, а уровнем выше, корень FTP)
(23:35:53) ????: О, как раз и меню несколько уровневое есть на тибре....
(23:36:06) ????: Ага, я понял.
(23:36:40) Balancer: Только там вёрстка ужасная. Дизайн делал человек, далёкий от веба, и перевёрстывать за ним меня ломало, так что очень грубо на шаблоны перевёл. Вот РП - там дизайн сторонний, а вёрстка уже моя.
(23:37:14) ????: Тибр - это архив борс-локал.рар?
(23:37:32) Balancer: Да, что-то я его именовал криво :)
(23:37:54) ????: да ладно, сойдёт
(23:38:56) Balancer: У Тибра бэкенд данных страниц, источник данных, не БД, и не простая статика - там данные для страниц лежат в *.xml в каталоге data.
(23:39:13) Balancer: Путь к нему в config.php прописан.
(23:39:21) ????: Ага, там ВЕЗДЕ хмл. :)
(23:40:03) Balancer: Вообще, это пока на практике первый и ещё единственный эксперимент с таким бэкендом. Многое ещё сыро и надо выправлять для красивого и правильного решения :)
(23:40:35) ????: Т.е. НЕ рекомендуешь делать данные через хмл?
(23:41:01) Balancer: Практическая польза только одна - быстро развернуть примитивный хостинг, когда лениво БД настраивать :) Минусы очень серьёзные - нельзя, например, делать быстрый поиск, запрашивая группы объектов по какому-то критерию.
(23:41:11) Balancer: Для статических страниц использовать можно.
(23:43:15) ????: Под статическими ты понимаешь страницы:
1. Которые ВООБЩЕ программно не изменить.
2. В которых нет PHP/шаблонов?
(23:45:47) ????: Что-то я не то написал....
Спрошу по-другому: если мне надо, к примеру, сделать страницу "О компании", но при этом сам текст этой страницы пользователь должен мочь менять сам (через админку), то как лучше этот текст хранить?
(23:53:47) Balancer: В данном случае страницы и меняются, и шаблоны использую, и выдаются PHP. Так что я термин некорректно использовал. Имеется в виду страницы, которые не выбираются в БД по каким-то критериям. Скажем, нельзя просто и быстро посмотреть десяток последних изменённых страниц.
(23:54:21) Balancer: Т.е. для небольшого сайта можно сделать пробежку по файловой системе и это особо тормозить не будет, но на крупном уже не прокатит.
(23:56:23) ????: а, ясно.
...
Давай на сегодня закончим. Я буду переваривать. :)
(23:57:39) Balancer: давай :)
(23:58:34) Balancer: А я пойду с Авиапортом ковыряться и с www.forexpf.ru :) Последний сайт по дизайну и функционалу не сложный, но внутри - смерть. Там и MySQL, и MSSQL, и Oracle и 4000 человек одновременно на сайте :D
(23:58:59) ????: ага. :)
(23:59:08) Balancer: (он пока не на моём движке сидит, но работаю над его переделкой)
(12.02.2009 10:28:47) ????: Привет.
Выкачал я рп, полазал по нему фаром и у меня сложилось впечатление, что буквально каждую страницу мне придётся делать руками (не код вывода, а именно представление её в html). Это несколько пугает. :)
Вот, к примеру, у меня есть титульная страница, со сделанной такой разметкой: сверху логотип, снизу футер с подписью, слева меню, справа банеры, а по центру контекст. Далее я перехожу на другую страницу (через меню, к примеру) и на этой
(12.02.2009 10:28:47) ????: новой странице меняется только контекст в центре, а всё остальное должно остаться.
В чистом php это делалось инклюдами на каждой странице. А как это делается во фреймворке?
(12.02.2009 10:32:26) ????: А также ещё сложилось мнение, что рп практически НЕ использует мускул, и всё лежит на винте. А как же тогда делается возможность изменения всяких разделов и пр.? Файлики на винте правятся?
(12:52:37) Balancer: Во фреймворке это делается одним общим шаблоном в templates :) В случае РП это templates/default/*.html
Собственно шаблон страницы - index.html и в нём много include
(12:53:16) Balancer: А то, что рядом с файлами классов валяется - это шаблон внутренней части страницы. Только тот, "меняющийся в центре контент" :)
(13:09:24) ????: ага.
(13:11:57) Balancer: Тут главное помнить, что я ОЧЕНЬ ленив и поэтому где только можно часть работы с себя переложить на компьютер, я это делаю :) Если тебе что-то кажется сложным и требующим много возни - спрашивай, возможно, не с той стороны к вопросу подошёл :)
(13:12:20) ????: ок.
(18:06:42) ????: Ром, пытаюсь запустить тибр локально, но что-то не так, думаю я неправильно задаю что-то в карте (да, сам борс-мап запускается и массив создаётся).
Файл main.php лежит в "\classes\tibr\admin\main.php".
Я пишу в карту 1 строку '(/)tibr/admin/main/ => tibr_admin_main', но что-то не работает.
Перечитал нашу переписку по регэкспам, но так и не въехал. Хелп!
В main.php объявление класса и функция "function local_template_data_set()"...
(18:11:23) ????: Почитал сайт... попробовал так: '(/tibr/admin/)main/ => tibr_admin_main', но тоже что-то не-то...
(18:14:55) ????: Да, от фреймворка получаю "Page not found тра-та-та"....
(18:18:47) Balancer: Погоди. Карта там уже должна быть. В архиве.
Кроме того, ты вызывать пытаешься по http://tibr.local/tibr/admin/main/ ? :) [домен - по вкусу]
В карте все пути - относительно корня сайта. Т.е. если ты хочешь вызвать http://tibr.local/admin/, то регексп должен быть вида (/)admin/ =>
(первая группа - это выделение родительской ссылки для автоматической навигации, вобщем случае может отсутствовать, если своих навигационных родителей класс указывает явно.)
(18:19:21) Balancer: В карте запись:
'/admin/ => tibr_admin_main',
(18:19:40) Balancer: bors-local/handlers/bors_map.php есть в архиве
(18:19:48) ????: НЕТ там карты. Свою сделал. :)
Получилось запустить класс на 50% вот такой записью '/ => tibr_admin_main'
(18:20:01) ????: Непонятно правда почему....
(18:20:14) Balancer: Не может быть, чтобы я bors-local тебе для ТИБРа не запаковал :)
(18:20:48) Balancer: Ха. Да, нету такого в архиве :)
(18:21:08) Balancer: И templates там нет. Сейчас перепакую. rar что-то сглючил.
(18:21:39) Balancer: Выложил архив тебе на kosh
(18:23:19) ????: Ага.
========================
В карте все пути - относительно корня сайта.
========================
А за что фрейворк считает корень сайта?
(18:23:51) Balancer: Как и все остальные - то, где "/" :)
(18:24:26) ????: Т.е. каталог www он же htdocs&
(18:24:29) ????: ?
(18:25:47) Balancer: Т.е. если тебе надо обработать http://tibr/test/, то этот адрес состоит из домена tibr и пути /test/
То есть в карте именно этот /test/ и фигурирует.
А куда он отображается на файловой системе карты не касается. Это задача веб-сервера и его конфигов. PHP-скрипты получают об этом информацию из переменной $_SERVER['DOCUMENT_ROOT'] - туда веб-сервер положет полный путь к каталогу, который соответствует пути "/" в ссылке.
(18:26:57) ????: Ясно. Спсб.
(11:26:57) ????: С добрым утром, Москва! :)
Пытаюсь запустить тибр локально....
Вроде что-то запускается, проходит инициализацию смарти (ругался на смарти, т.к. он был версии 21 - поправил), но странно ругается теперь так:
Fatal error: Cannot redeclare remove_last_slash() (previously declared in V:\home\tibrlocal.ru\.bors-core\inc\strings.php:2) in V:\home\tibrlocal.ru\.bors-core\inc\strings.php on line 5
Код этой функции такой:
==================================================
function remove_last_slash($s)
{
return $s[strlen($s)-1]=='/' ? substr($s,0,-1) : $s;
}
==================================================
"redeclare" - это же вроде переобъявить? Вообщем что-то я не очень понимаю... Хелп.
(11:33:13) ????: Я взял тупо закоментировал весь strings.php и тибр запустился ещё дальше (показал логотип тибра и кое-какую разметку), но теперь упал с ошибкой: Fatal error: Call to undefined method base_page::children() in V:\home\tibrlocal.ru\.bors-core\classes\page\fs\xml.php on line 17. :)
Что-то явно не так... :) Поможешь?
(13:34:53) ????: На сколько я понимаю у класса base_page нет(?) метода children() или это глюк.
Я закоментировал в ядре :) ошибочную строку и тибр загрузился, правда без меню...
(14:00:56) Balancer: Нужно посмотреть, откуда вызывается. Скорее всего require/include, а не require_once/include_once. Поэтому дважды и грузит.
...
А, нет, стои. Один раз в 5-й строке, другой во 2-й? Сейчас гляну.
(14:01:39) Balancer: children есть у кого-то из суперклассов base_page. Наверное, у base_object.
(14:03:17) Balancer: Гм. В inc/strings.php вижу только одно объявление этой функции, во 2-й строке. Посмотри в strings.php у себя.
(17:43:20) ????: С redeclare всё намного страннее! Дело в том, что ЛЮБАЯ(!) функция, присутствующая в inc/strings.php вызывает ошибку "Fatal error: Cannot redeclare...".
К примеру функция перекодировки из utf-8 тоже: "Fatal error: Cannot redeclare utf8_win() (previously declared in V:\home\tibrlocal.ru\.bors-core\inc\strings.php:7) in V:\home\tibrlocal.ru\.bors-core\inc\strings.php on line 43".
Я даже создал СВОЮ функцию в inc/strings.php
function kosh($text) { return $text; }
...и тоже получил ошибку редекларе!!!! =-O
"Fatal error: Cannot redeclare kosh() (previously declared in V:\home\tibrlocal.ru\.bors-core\inc\strings.php:86) in V:\home\tibrlocal.ru\.bors-core\inc\strings.php on line 86"
Т.е. это всё ЯВНО НЕ связано с дублем функций, т.к. функции kosh() явно нигде больше нет. :)
(18:56:05) ????: Всё, я разобрался с ошибкой редекларе...
inc\strings.php вызывался дважды. Я закоментировал инклюд стринга в 00-save_tags_format.php и всё стало ок.
(18:56:34) ????: Странно, что у тебя эта ошибка на сайтах не вылазит...
(19:08:39) ????: Проблема с отсутствием parent::children() пока осталась.
class page_fs_xml extends base_page
...
...
function children() { return $this->_children ? $this->_children : parent::children(); }
...
...
(19:17:08) ????: Уф, решил я проблему с children(). :)
Надо было не children(), а cache_children().
Однако я не пойму, как такое могло оставаться незамеченным... :)
(19:22:40) Balancer: 1. По поводу двойного вызова - я ранее обращал твоё внимание, что нужно проверить на предмет include/require вместо include_once/require_once. Видно, где-то опечатка. ... ну, да, в 00-save_tags_format.php так и есть. Там не комментировать надо, а заменять на include_once() :)
2.children и cache_chldren - это разные методы. Первый возвращает список потомков по навигации. Второй - список объектов, зависящих при кешировании. Т.е. кеш которых надо сбрасывать, если меняется текущий объект.
Ошибка, походу, вылезла от того, что у тебя где-то неправильно грузится бэкенд. Сейчас посмотрел, cache_children определяется в classes/page/fs/xml.php - это XML-бэкенд. На Тибре используется только он, поэтому ошибки там не было. На других сайтах нигде не используется поиск детей текущей страницы. Поэтому там тоже нет. У тебя, видно, бэкенд потерялся и вывод ищет children уже у базовой страницы base_page :)
(19:37:02) ????: 1. "Там не комментировать надо, а заменять на include_once()". Да, сначала закоментил, а потом поставил once.
2. "Сейчас посмотрел, cache_children определяется в classes/page/fs/xml.php" ???? Определяется? Да в файле xml.php о cache_children вообще не было ни слова, пока я туда его не вставил. :))
А изменил я это:
было: function children() { return $this->_children ? $this->_children : parent::children(); }
стало: function children() { return $this->_children ? $this->_children : parent::cache_children(); }
Почему я решил, что этот children() ищется в base_page:
Класс page_fs_xml наследует base_page (class page_fs_xml extends base_page).
И код "parent::children()" я понял, как вызов метода children() у родителя, т.е. у base_page.
Я правильно понял?
Тем не менее, тибр запустился и работает, что меня радует и я могу приступать к препарированию оного. :)
(19:39:18) Balancer: Тьфу, просто children.
...
>function children() { return $this->_children ? $this->_children : parent::cache_children(); }
Неправильно, это _разные_ функции :)
(19:39:25) Balancer: Секунду.
(19:40:05) ????: Может у меня ДРЕВНИЙ фреймворк? :)
(19:41:25) Balancer: Вот, оно определяется в base_object:
var $stb_children = array();
Если нет какой-то функции, то PHP5 вызывает метод __call.
А он у меня смотрит наличие переменной с таким же, как искомая функция именем и префиксом stb_
Если находит - возвращает её значение (или устанавливает, если вызывалось set_{name})
Нет - возвращает ошибку.
(19:42:20) Balancer: Если он не находит children() у base_object - это что-то с PHP у тебя не то :) Или PHP4 (но тогда масса других бы ошибок вылезла), или с настройками что-то, или ещё где-то :)
(19:43:02) ????: %) О как всё хитро....
(19:44:02) ????: Не, пых 5-ый стоит.
(19:44:42) ????: Вообще стоит пакет "Денвер-3" (это так, на всякий случай говорю).
(19:45:22) Balancer: В общем, погляди в base_object функцию __call()
Это сделано для резкого уменьшения писанины при описании конечных объектов.
В общем случае даже переменную задавать не надо.
Я описываю поля в БД. Когда драйвер инициирует объект, он значения потом в объект пишет по stb_* переменным, даже если их до этого не было. И PHP тогда сам переменные создаёт. И при чтении функциями возвращает корректное значение. Поэтому одно поле MySQL - одна запись в массиве. При лобовом описании - потребовалась бы эта же запись плюс три строки - описание переменной и две функции, на чтение и на запись, вторая - достаточно длинная :)
(19:46:15) Balancer: Так что верни вызов parent::children() и попробуй понять, почему он ошибку даёт, хотя не должен :) parent::children должен вызвать __call() у base_object.
(19:46:30) Balancer: (а я тут отбегу на час-полтора :) )
(19:46:49) ????: Ок, покапаюсь...
(19:47:22) Balancer: И напомню посмотреть http://balancer.ru/support/2008/11/t64759--Kak-ono-rabotaet.Otobrazhenie-ob~ektov-s.6302.html , если ещё не смотрел :)