Предлагаю познакомиться с текущими наработками системы. Целью написания данного поста является поиск заинтересованных лиц и единомышленников с которыми представится возможность вместе заниматься дальнейшей разработкой данной системы Ниже расписаны некоторые моменты, конечно это далеко не всё, по этому предлагаю задавать вопросы, буду стараться на все достаточно подробно ответить, хотя некоторые вещи в какой-то степени расписаны в вики http://smart-core.org/wiki/. Предназначение движка. - Создание веб-сайтов различной сложности и направленности, например: блоги, новостные сайты, интернет-магазины, просто визитки и т.д. - Сайты созданные на движке обладают лаконичным и удобным интерфейсом управления т.е. их сайты можно смело и спокойно передавать клиенту, который не является профессионалом в ИТ - В будущем система будет включать возможности для распределённых проектов. Преимущества. - Движок разрабатывается из рассчета на низкое потребления ресурсов сервера, сейчас можно оценить потребление памяти и скорость выполнения скриптов. - Достаточно лёгкое написание модулей. - Также достаточно лёгкое внедрение тем оформления. - Использование современных технологий, хотя пока и поддерживается PHP линейки 5.2, но в будущем будет только 5.3+. Также планируется внедрение поддержки PostgreSQL, SQLite, MongoDB, Memcache, Redis и т.д. Текущий статус. На данные момент уже заложены в архитектуру системы и реализованы следующие вещи: - Система шаблонизации. - Управление базовыми сущностями системы: папки, ноды, контейнеры и т.д. - Мультисайтовость — возможность на одной инсталляции системы обеспечить работу нескольких независимых сайтов. - Концептуальные наработки по фонт-енд админке. - Кэширование страниц целиком для гостей. - Система прав доступа для папок и нод. - Подсистема почтовых рассылок.. - Система запуска задач по расписанию. - Некоторые базовые функциональные модули: авторизации и регистрации юзеров, текстовын блоки, простая фотогалерея, новости и каталог на компоненте «юникат», веб-формы... - Особая особенность в движке, это компонент «юникат», весьма гибкая и мощная система управления каталогизированных данных. Юникат в целом уже весьма рабочий, но еще в разработке и требует доработки для работы с некоторыми типами данных и внедрения кеширования. - Возможность применение единой базы пользователей для разных сайтов, в том числе расположенных на разных серверах. Для коллективной разработки подняты вики, форум и планировщик задач (так же изместный, как баг трекер), основной репозиторий Git насположен на http://sourceforge.net/projects/smart-core-cmf/. Планы на развитие. - В архитектуре системы скорее всего будет внесены небольшие изменения, хотя они могут коснуться в большей части толкьо программного кода. - Допиливание базовых модулей: комментарии, профили пользователей, интернет-магазин. - Оптимизация под высокие нагрузки, внедрение поддержки разнообразных систем кеширования. - Мультиязычность, как контента, так и пользовательских интерфейсов. Кому проект может быть интересен. - Практикующим разработчикам сайтов. На данный момент можно сделать пока несложные проекты и частично проекты средней сложности. Но в системе заложен понтециал для весьма сложных систем, например социальные сети и мультиблоги. - Разработчикам, которые применяют различные готовые системы и чувствуют некоторую неудобвленность этих систем т.е. есть идеи что должно быть в системе, чтобы было действительно удобно. - Начинающие разработчики, которые хотят изучить принципы работы систем управления проектов, а также самим поучавствовать в развитии движка. Кому проект скорее всего будет НЕ интересен - Людям, которые не занимаются созданием веб-сайтов. - Сторонникам параноидального ООП, где каждая рюшечка должна быть оформлена в виде каскада наследуемых классов и обязательно всё подкрепрено тестированием т.е. тестирование и ооп это хорошо, но всему есть мера. - Ищущим уже полностью готовое и развитое решение. Где взять Скачать архив с демо-версией можно отсюда https://sourceforge.net/projects/smart-core-cmf/files/, здесь архив подготовленный для простого разворачивания на хосте, включающий все таблицы и демо-данные для 2-х сайтов привязанным к доменам loc и loc2. Также в git доступны скрипты для инсталляции, но с ними есть некоторые тонкости по этому для знакомства с системой лучше использовать именно полный архив с демкой. ЗЫ: срачникам привет! можете поднимать вонь на сколько у вас мощи найдется ))
что по поводу архитектуры системы скажете? т.е. не про ООП и не про быдрокодные буковки, а именно про архитектуру задумки проекта.
Код (Text): function cf_format_filesize($input, $metric = NULL) { if (!$metric) $metric = array('байт', 'Кб', 'Мб'); if (is_file($input)) $input = filesize($input); Правильно ли я понял, если я передаю в функцию число, но в текущей папке у меня оказывается файл например "23234879243" то функция даст мне не тот результат которого я жду ? ИМХО автоматика не всегда хорошо, я бы всё же явно указывал при вызове файл передаётся или нет... И далее идёт кстати шедевр Код (Text): elseif (isset($metric[1]) && (($input = $input / 1024) < 1024)) $unit = $metric[1]; elseif (isset($metric[2]) && (($input = $input / 1024) < 1024)) $unit = $metric[2]; elseif (isset($metric[3]) && (($input = $input / 1024) < 1024)) $unit = $metric[3]; elseif (isset($metric[4]) && (($input = $input / 1024) < 1024)) $unit = $metric[4]; Поищите по форуму, помню мы тут флудили на эту тему, много красивых решений было... А то что у вас это простите "быдлокод" ЗЫ: и вам тоже привет!
cf_format_filesize() не я писал, откудато спер просто потому что мне надо было конвертировать размеры файлов в человероконятный вид. к архитектуре системы это не относится, если у вас есть более грамотная реализация какого-либо фрагмента кода, то проект опенсорц, пожалуйста вливайтесь
Да и сам по себе $metric опциональным делать я бы не стал, его надо подключать либо из языкового файла (если есть поддержка мультиязычности) либо вообще убрать (если поддержки нет и не предвидится)
Описание концепции архитектуры выложил в вики, вот по этому адресу: http://smart-core.org/wiki/Основы_архитектуры Можно было бы и тут запостить, но подумал, что во первых многовато текста, а во вторых сама статья будет еще дописываться, по этому лучше ссылкой Vladson, вот тут http://smart-core.org/wiki/ есть раздельчик: Что надо сделать, и там есть пункт, 4. Мультиязычность. Т.е. мультиязычность предвидется, а сейчас её почти нет, но есть рассчет, что будет и подготовлены например таблицы БД для этого... По поводу cf_format_filesize() посмотрите где он используется и вопросы отпадут почему он именно такой лучше обсудить архитектуру самой системы (не прогаммного кода), а по реализации я сам могу много чего наговорить
Они не отпадут, если сначала писать код а потом думать и даже мечтать в будущем поправить, то рано или поздно упрёшься в тупик. Сначала надо планировать, а уже потом писать. Неожиданности всё равно будут, но когда их меньше, то есть шанс их уладить.
согласен, но абсолютно всё и сразу в одиночку я не могу предусмотреть будем считать, что это одна из неожиданностей притом ну очень несущественная, которую можно прям сейчас вырезать из кода и ничего не изменится а по архитектуре у вас есть замечания? или хотябы не по функции cf_format_filesize() )
Vladson Недавно вот читал где-то, кажется на хабре... Ну в общем там смысл был противоположный твоим словам Типа, не стоит долго думать, начинайте писать, все проблемы и вопросы будут намного быстрее решаться по ходу написания, чем если сидеть и днями размышлять на тему "как же сделать лучше" Так никогда ничего и не сделаете и то место, которое мог занять ваш сайт - займут другие
Об этом говорил Ашманов, но имел в виду совсем другое, быдлокодеры же его славами стали прикрывать своё ламерство. (и на хабре таких очень много, особенно РНР-шников у которых от инвайта на хабр выросло самомнение) Да, в WEB часто нужна модель мягкого ввода, т.е надо выкладывать бету раньше всех, а потом допиливать. Для этого и нужны готовые фреймворки (в них уже всё продумано, т.е за 10 минут пишешь например блог а потом ты только допиливаешь его до уровня например хабра) Писать же свой фреймворк, это другое дело, если он не разрабатывался с умом, и если в его планирование не ушло 90% времени и не учтены все мелочи, то очень скоро будут выскакивать незапланированные мелочи и разработка как самого фреймворка так и того что с его помощью пишут зайдёт в тупик.
Ну в данном конкретном случае скорее всего просто цитировали Ашманова... (он достаточно авторитетный дядька) другое дело что его слова выдрали из контекста
По замечаниям с форумов проведен некоторый рефакторинг кода, теперь стало больше «магии» имхо стало красивее, да и на скорость не повлияло. Также из новых функций добавлена возможность кеширования нод, как фрагменты html кода. Пока настройка кеширования нод выполняется ручками через свойства ноды в формате yaml, а также надо включить флаг в файле _temporary.php, дальше будет реализована более првильная админка Провел первые тесты на выносливость и скорость. Пока тестировал только apache bench с параметрами -c500 -t60 -k -H "Accept-Encoding: gzip", а также -с1. При одном юзере при включенном кеше страниц для гостей показатель очень вкусный, обычно страница отдаётся примерно за 0.002 сек т.е. быстренько выпуливается из кеша а без кеша страницы отдаются в среднем за 0.03-0.07 сек, что в прицнипе хорошо. Приглашаю снова покрутить код, а также посмотреть в действии систему, для этого надо скачать с сурсфорга последний .zip архив и установить на своём сервере (в будущем обязательно будет доступен публичный тестовый сайт). Все замечания и предложения привествуются, а также приглашаются все желающие принять участие в развитии данного проекта! На всякий случай еще раз напомню ссылку на страничку проекта: http://smart-core.org/ оттуда же можно и скачать и выйти на вики и форум.
Ммм, 0.002 сек для кеша, это не быстренько. У меня на порядок меньше на средненьком сервере. Смотри, например, mosreklama.net, внизу (если там показано кол-во запросов, то нужно перезагрузить). Но, конечно, смотря что и как кешировать.
d1gi cf_format_filesize() не я писал Такая функция вобще не нужна в таком виде. Есть функция получения размера в пхп. Нужна функция пересчета размера в человекоудобоваримый вид. Кому нужно узнать размер файла в КБ тот сначала запросит размер файла, а потом прогонит через эту функу. Вот это правльный подход. вот кстати моя если чо. кто кстати назовет это быдлокодом - тот лох! PHP: <? function HumanBytes($size) { $filesizename = array(" Bytes", " KB", " MB", " GB", " TB", " PB", " EB", " ZB", " YB"); return $size ? round($size / pow(1024, ($i = floor(log($size, 1024)))), 2) . $filesizename[$i] : '0 Bytes'; } шутка. критика всегда приветствуется.
d1gi мультиязычность предвидется, а сейчас её почти нет, но есть рассчет, что будет и подготовлены например таблицы БД для этого... мультиязычность делается через одну таблицу с тремя или четырьмя полями.
Vladson РНР-шников у которых от инвайта на хабр выросло самомнение) Мне! Мне очень надо подрастить самомнение, так что если у кого есть инвайт - я буду оч рад принять его =)
к функции нет вопросов, но в именовании согласно стандарту нужно human_bytes, и также 1024 ---> 1 КиБ, а не КБ, такие дела.
кеширование тестил так: 1. Хост-машина: core-i3-530 2.9МГц/4г рам/win7-32bit 2. Виртуальная машина: virtualbox-4.1.8/768м рам/100%cpu/VT-x и NestedPaging включены 3. Архитектура веб-сервера: nginx на фронте, apache+mod_php на бакенде. 4. Конфигурация php тут: http://smart-core.org/vbox-phpinfo.html с хостовой машины запускаю ab с ключами ab.exe -c1 -t60 -v0 -k -H "Accept-Encoding: gzip" http://10.4.4.4/SmartCore/ в результате получаю 0.0017 сек, что округлил до 0.002 а вот например один файл с командой echo "123"; выдаёт 0.00065 сек, т.е. примерно всего в 2.5 раза быстрее. опишите на словах как именно, по какому алгоритму у вас выдаётся страница из кеша для гостей? igordata, да действительно отличная идея, вынести "человекизацию" разных метрик в отдельный класс! ) даже думаю лучше тудаже добавить возможности переводить меры масс, длины, времени и т.д. ) благодарю на наводку по поводу мультиязычночсти: пихать все переводы разных сущностей в отну таблицу нехочу... чувствую что это несовсем верно... пока остановился на решении хранения переводов каждой сущности в отдельной таблице... на самом деле кол-во этих таблиц будет очень невелико, например сейчас созданы таблицы для "папок", тектовых блоков, меню и вебформы... и более того структуры этих таблицы разные, например для пунктов меню ненужны мета-данные, для в вебформе, к переводу относится кнопка подтверждения и т.д...
d1gi по поводу мультиязычночсти: пихать все переводы разных сущностей в отну таблицу нехочу... я тебя не спрашиваю и не советую =) все переводы ДОЛЖНЫ жить в одной таблице по простым причинам, нравится нам это или нет. Это не от нашего желания и ощущения зависит. 1 - это переводы, это таблица для переводов, они живут в ней. 2 - все переводы одинаковые. они лезут в таблицу с такой структурой: id (не обязательно), язык, номер сообщения, сообщение. 3 - выборка осуществляется одним и тем же запросом к одной и той же таблице, что прекрасно. 4 - все модули всегда не зависимо от языка знают куда писать перевод и где его искать. =) А в остальном ты конечно можешь полагаться на свое чутьё! =) внесу пять копеек моего говнокода. сразу скопом с предыдущей функой PHP: <? //////////////////////////////////////////////////////////////////////////////////////// // <editor-fold defaultstate="collapsed" desc="Превращение даты и прочего в человекочитаемый вид"> public static function HumanDate($date) { $date = strtotime($date); $diff = time() - $date; $days = floor($diff / 86400); $hd = ''; if ($days == 0) { //сегодня $hd = 'сегодня в ' . date('H:i', $date); } else { if ($days > 0) { //прошлое switch ($days) { case 1: $hd = 'вчера в ' . date('H:i', $date); break; case 2: $hd = 'позавчера в ' . date('H:i', $date); break; } } else { //будущее switch ($days) { case -1: $hd = 'завтра в ' . date('H:i', $date); break; case -2: $hd = 'послезавтра в ' . date('H:i', $date); break; case -3: $hd = 'через три дня'; break; } } } if ($hd == '') { $hd = date('d.m.Y H:i', $date); } return '<acronym title="' . date('d.m.Y H:i', $date) . '">' . $hd . '</acronym>'; } public static function HumanDatePrecise($date) { $r = false; $a = preg_split("/[:\.\s-]+/", $date); $d = time() - strtotime($date); if ($d > 0) { if ($d < 3600) { //минут назад switch (floor($d / 60)) { case 0: case 1: return "<acronym title='$date'>только что</acronym>"; break; case 2: return "<acronym title='$date'>только что</acronym>"; break; case 3: return "<acronym title='$date'>три минуты назад</acronym>"; break; case 4: return "<acronym title='$date'>четыре минуты назад</acronym>"; break; case 5: return "<acronym title='$date'>пять минут минуты назад</acronym>"; break; default: return "<acronym title='$date'>" . floor($d / 60) . ' мин. назад</acronym>'; break; }; } elseif ($d < 18000) { //часов назад switch (floor($d / 3600)) { case 1: return "<acronym title='$date'>час назад</acronym>"; break; case 2: return "<acronym title='$date'>два часа назад</acronym>"; break; case 3: return "<acronym title='$date'>три часа назад</acronym>"; break; case 4: return "<acronym title='$date'>четыре часа назад</acronym>"; break; }; } elseif ($d < 172800) { //сегодня //2011-07-14 16:20:44 // 0 1 2 3 4 5 if (date('d') == $a[2]) { return "<acronym title='$date'>сегодня в {$a[3]}:{$a[4]}</acronym>"; } if (date('d', time() - 86400) == $a[2]) { return "<acronym title='$date'>вчера в {$a[3]}:{$a[4]}</acronym>"; } if (date('d', time() - 172800) == $a[2]) { return "<acronym title='$date'>позавчера в {$a[3]}:{$a[4]}</acronym>"; } } } else { //////////////////////////////////////////////////////////////////////////////////////// // В будущем <editor-fold defaultstate="collapsed" desc="В будущем"> $d *= -1; if ($d < 3600) { //минут назад switch (floor($d / 60)) { case 0: case 1: return "<acronym title='$date'>сейчас</acronym>"; break; case 2: return "<acronym title='$date'>через две минуты</acronym>"; break; case 3: return "<acronym title='$date'>через три минуты</acronym>"; break; case 4: return "<acronym title='$date'>через четыре минуты</acronym>"; break; case 5: return "<acronym title='$date'>через пять минут</acronym>"; break; default: return "<acronym title='$date'>через " . floor($d / 60) . ' мин.</acronym>'; break; }; } elseif ($d < 18000) { //часов назад switch (floor($d / 3600)) { case 1: return "<acronym title='$date'>через час</acronym>"; break; case 2: return "<acronym title='$date'>через два часа</acronym>"; break; case 3: return "<acronym title='$date'>через три часа</acronym>"; break; case 4: return "<acronym title='$date'>через четыре часа</acronym>"; break; }; } elseif ($d < 172800) { //сегодня //2011-07-14 16:20:44 // 0 1 2 3 4 5 if (date('d') == $a[2]) { return "<acronym title='$date'>сегодня в {$a[3]}:{$a[4]}</acronym>"; } if (date('d', time() - 86400) == $a[2]) { return "<acronym title='$date'>завтра в {$a[3]}:{$a[4]}</acronym>"; } if (date('d', time() - 172800) == $a[2]) { return "<acronym title='$date'>послезавтра в {$a[3]}:{$a[4]}</acronym>"; } } $d *= -1; //, В будущем </editor-fold> ////////////////////////////////////////////////////////////////////////////////////////. } $r = "{$a[2]}.{$a[1]}"; if ($a[0] != date('Y') OR $d > 0) { $r .= '.' . $a[0]; } $r .= " {$a[3]}:{$a[4]}"; return "<acronym title='$date'>$r</acronym>"; } public static function HumanBytes($size) { $filesizename = array(" Bytes", " KB", " MB", " GB", " TB", " PB", " EB", " ZB", " YB"); return $size ? round($size / pow(1024, ($i = floor(log($size, 1024)))), 2) . $filesizename[$i] : '0 Bytes'; } //, Превращение даты и прочего в человекочитаемый вид </editor-fold> ///////////////////////////////////////////////////////////////////////////////////////.
"Захардкоденые" (какое-то новое слово, на phpclub услышал) в функции "только что", "через четыре часа" и пр. не очень состыковываются с многоязычностью... А вообще мне кажется, что формат даты 8 Января 2012, 23:51 8 January 2012, 23:51 более чем достаточно...
d1gi, ну если так , то, конечно, не сравнить. У меня echo выводило где-то за 0.0001 и меньше. Очень сильно время увеличивается на операциях чтения из файла, а также получения статистики (время последнего изменения файла, размера и т.д.). Так что желательно максимально уменьшить количество запросов к диску. Сначала функцией file_exists($name) ищется кеш с уникальным именем вида "7e9a8105ebd66...", потом считывается $ct=@file_get_contents($name). Кстати, имя создается из обработанного ранее пути $path: $name='cache/'.md5($path.$salt). Потом проверяю, не пусто ли в том файле if(strlen($out)>10), и вырезаю первые 10 символов-цифр - там время, до которого позволительно жить кешу. Остальные символы в файле - html код, который нужно выдать браузеру. Если время истекло, то идем далее, инклудим остальные важные фрагменты и классы, подключаемся к БД и т.д. Если не истекло время жизни, то выдаем символы из кеша (со своими заголовками, если надо, инфу о которых можно запихнуть в тот же кеш в первые строчки). Итого получаем всего два запроса (из скрипта) к ФС в надежде, что кэш актуален: file_exists и file_get_contents. Ну остальное мелочи Это, конечно, самый простой случай кеширования. Если нужно устанавливать время жизни разным блокам, то, возможно, запихивать их в файлы, а потом читать, будет уже не оптимальный путь. Тогда лучше подключиться к БД.