Перейти к основному содержимому

Обзор PHPStorm 1.0

· 5 мин. чтения

Профессия обязывает каждый день писать на php и поэтому первый важнейший инструмент после головы для меня является среда разработки (IDE). До сих пор я сидел на Zend 5.5, но столкнувшись с PhpStorm 1.0 от чехов русских с JetBrains сразу перешёл на него.

Понятно что редактор - дело субъективное и многое зависит от проектов с которыми вы работаете. Zend 5.5 мне нравился удовлетворительной скоростью и простым доступом к ftp. Я знал что там ещё были всякие дебаги, интеграция с SVN и sql-серверами но практически их не смог применить. Я пробовал NetbeansAptana и PDTZend 6 но во все они медленные особенно при индексации файлов и монстроидальный интерфейс с кучами кнопочек. Поэтому и начну сразу с недостатков.

Недостатки

  • Невозможно сразу начать работать при медленных (>5 сек) сетевых соединениях (VPN) и обращению к файловой системе

  • Синхронизация файлов при deployment'е удалённого проекта не совмещает различия, а просто перезаписывает удалённые файлы, что делает невозможным изменение файлов двумя пользователями. Есть возможность ручной проверки одиночного файла, но сверять каждый раз самому неудобно.

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

  • Р****едактирования по FTP нету. Можно файлы читать, но для полноценного редактирования надо делать локальную копию проекта с настройкой синхронизации и deployment'а, а при переходе с одного IDE на другой и большом количестве проектов ждать скачивание каждого - жуть

  • Автосохранение файлов сразу во время редактирования, хотя и компенсируется "локальной версией изменений файла", однако многим может быть непривычно при переходе из других IDE.

  • Глупое автодополнение тэгов в html режиме (вечно мне добавляет comment тэг!). В редактировании php кода методы не подсказываются автоматически а только с нажатием Ctrl+Space, видимо из-за погони за скоростью.

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

  • Пугающие настройки. Их просто много. Разве что они понятней чем в Эклипсе - сразу разбиение на настройки проекта и настройки IDE.

  • Непривычность клавишных связок (hotkey binding) - например у меня несколько раз возникала ситуация когда я двигался назад по истории изменений (Undo), а потом хотел вернуться нажимая Ctrl+Y и вместо этого терял Redo-историю потому что Ctrl-Y на самом деле удаляет строку

  • Мало плагинов. Из серверов управления задачами только Jira и собственній youtrack. То же касается систем версионирования (Есть CVS, SVN, git, perforce). В основном они пишутся для общего редактора IntelliJ idea, а php-просто как частный случай

Как у всех..

Редактор визуально очень похож на все существующие IDE - динамические панели как у eclipse но с меньшим визуальным шумом иконок. Тут собственно меню, панель дерева файлов, панель структуры класса, внизу дополнительные панельки для todo, версионирования, иерархий и удалённого редактирования (появляются по мере необходимости).

Очевидно что редактор не компилятор и не настолько умён что-бы понимать переменные при использовании extract() или при переменных с динамическими именами через $$var — анализ этого на лету просто нереально ожидать и соответсвенно в проектах такие дела подсвечиваются как ошибки деклараций переменных. То же касается закриптованных частей через Ioncube или Zend guard.

Про автодополнение с Ctrl+Space я уже говорил, так же тут и Ctrl+click работает для перехода к собственно декларации метода или класса. И Ctrl+D дублирует строку. Тут есть и закладки строчек через Ctrl+Shift+цифра. Есть тут и поддержка PHPdoc и @todo синтаксиса.

Основные фишки

Главные прелести редактора - хорошая скорость в обычном редактировании текста - ничего не прыгает, не задумывается на три секунды покуда я печатаю.. Вобщем есть "основа" которая дополнена мелочами в которых и кроется секрет хорошего блюда:

  • Поиск классов Ctrl+N и файлов Ctrl+Shift+N в том числе и со звёздочками (wildcard). Очень полезно и быстро, потому что файлы как правило разбросаны в разных ветках дерева и консоль всегда оперативна

  • Скролл при поиске или при навигации по своим закладкам строк через Ctrl + цифра. Очень помогает не потеряться и интуитивно понимаешь в какую сторону файла ты прыгаешь.

  • Рефакторинг имён файлов, классов и методов во всём проекте и/или поиск их использования. Потому что часто просто боишься поменять старое название на более информативное потому что не помнишь где это используется, а искать как фразу через Ctrl+F запаришься

  • Подключение внешних папок. Скажем если у вас 10 проектов в которых используется повторяемый фреймворк (PEAR к примеру) или закриптованный код, то можно подключить внешнюю папку чтобы IDE понимала пространство имён

  • Версионирование. Как встроенная история изменений, так и отлично встраиваемый SVN со всякими диффами, определённо лучше TortoiseSVN.

Приятно удивили и некоторые мелочи

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

  • Иерархия вызовов метода и вызываемых методов в hierarchy блоке

  • Статус и ручная чистка памяти в статус-баре - сразу говорит о заботе

  • Локальная история изменений файла

  • Перетаскивание строки или целого выделенного блока с сохранением табуляции через Ctrl+Shift+Up/Down вместо того что-бы делать Copy-Delete-Paste с ручным форматированием

  • Вернуться к последнему месту редактирования Сtrl+Shift+Backspace

Кроме этого в редакторе есть простор для изучения до которого я ещё не дорос:

  1. XDebug для профилирования скриптов.. Для удалённого проекта надо что-бы расширение на сервере было установлено, поэтому всюду использовать нельзя.
  2. PHPUnit для автоматического тестирования кода
  3. SASS для более гибкого написания css

Infinite scolling

· 2 мин. чтения

Я вот уже больше месяца как делаю социальную сеть pling.ee, которая акцентируется на связи посредством мобильных телефонов (SMS/MMS) и позиционировании людей с их помощью. Достаточно перспективный проект (как твиттер на дрожжах) и популярный среди местной молодёжи тем что можно почти нахаляву общаться.

Но технически возникла небольшая получасовая техническая задачка с навигацией, и раз уж я давно не писал, то может вам тоже будет полезно. Дело в том что в поток сообщений показывается ajax-ом, подгружаясь по X-сообщений  за раз чистым html (для json просто пришлось бы больше писать). Задача - прятать кнопку "ещё" если сообщений больше нет. Очень просто, но как оказывается не всё так очевидно.

Вот возможные решения (от худшего к лучшему)

  1. При первой загрузке страницы делать второй запрос и узнавать какой ID у последнего сообщения и потом детектить его показ с помощью js. Проблема в том что как правило SQL для запроса и так сложный, а тут надо его продублировать с изменением сортировки. Уже пахнет говнокодом.

  2. Если число подгружаемых результатов меньше ожидаемых X элементов на странице то сразу прятать кнопку. Конечно с вероятностью 1/X она всё-таки будет показываться, зато

  3. Сделать что-бы нажатие кнопки сразу показывало спрятанные закешированные результаты (и если их нет - то не показывать кнопку) + делать ajax-запрос и результаты прятать (а если их нет то тоже прятать кнопку). Тут много игры с js и к тому же подгружаются лишние данные (не факт что пользователь всегда нажимает на продолжение)

  4. Использовать SQL_CALC_FOUND_ROWS что-бы расчитать число всех элементов и если их меньше чем offset + число на странице, то просто отметить последний элемент css-классом и через javascript проверить и спрятать кнопку если класс присутсвует

A serious man

· 2 мин. чтения

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

Ларри — рациональный и пожалуй слишком серьёзный человек, со своими проблемами. Но он начинает замечать знаки. Ведь именно так Бог говорит с людьми. Неважно событие - важно что человек чувствует что это знак. Ларри попал в аварию и так же сделал любовник его жены. Знак.

В середине фильма Ларри беседует с Сайем о том что математика — самая что ли не настоящая рациональность. Проблема в том что теория вероятности самая хаотичная её часть. И именно так определяются знаки — это ценимая получателем информация среди фонового шума (это сцена с антенной).

Moon 2112

· 3 мин. чтения

воскресенье, 18 октября 2009 г. в 16:43:27

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

Девять — мультфильм Тима Бёртона и Тимура Бекмамбетова явно показывает на недостатки современных достижений компьютерных технологий. В частности это полностью детерминистическая и формальная математическая машина, не способная самоизменяться и эволюционировать. Вобщем она лишена всего что мы привыкли считать живым, поэтому она кажется чуждой и хладнокровной. В фильме проблему одухотворённости учёный решил с помощью некоего артефакта из древностей. Не бог весть как понятно и зачем машине поглощать души или зачем души рисовать в виде прозрачного желе. Я объясняю себе это лишь как стремление получить новую информацию. Похожие фильмы — Final fantasy и общая идея про крестражи у Роулинг.

Moon 2112 — ещё один красивый фильм затрагивающий вопросы этики, памяти и души. Когда я смотрел «Star Wars: Clone wars» то было не по себе от того как клоны не считаются людьми. Тоесть клон ведь просто генетическая копия оригинала и хотя он имеет многие предрасположенности к заболеваниям и даже наклонностям, общие черты характера формируются на протяжение всей жизни, поэтому ускоренно выращенные воины выглядели скорей как дети с промытыми мозгами, готовые воевать за своих хозяинов (Республику). В Moon 2112 очень похожая идея, хотя и очень предсказуемый сценарий.

Избранность

· 4 мин. чтения

Избранность — атрибут скромности

Избранность происходит от славянского «берѫ», близко к «бремя» и англ. «burden» со смыслами ношы, рождения, награды. Тоесть получается что избранный это человек рождённый впереди своего времени, острие всего общества и его будущее. Впрочем всегда возникает вопрос.. если избран, то кем? Для какой цели? А что будет после её достижения?

Настройка unit-тестирования с PHPUnit и PhpStorm IDE

· 2 мин. чтения

Unit-тестирование это хорошо. Много хороших статей написано о том как прекрасно это взять класс и для него написать юнит-тест. Позавчера вот Андрей Солнцев даже про расширение к TDD рассказывал — BDD. А большинство программистов по прежнему не используют.. просто потому что сложно даже настроить. Вот попробуем это для php сделать.

Прежде всего понадобится свой локально установленный php — я поставил последнюю 5.3.3 thread safe x86 версию. До этого я пробовал всякие WAMP, XAMPP, Apache2triad, Денвер.. и отсюда все проблемы которые далее возникли.

Цифровая подпись документов в Эстонии с помощью DigiDocService

· 7 мин. чтения

В Эстонии с 2000 года вступил в силу закон о цифровых подписях, которые стали юридически равноценны обычным рукописным. Вскоре была создана и техническая основа - компания SertifitseerimisKeskus (буквально - «центр сертификации») принадлежащая банкам и телекоммуникацонным операторам (а не государству, представляете себе!) и схема обмена данными по X.509 стандарту. Эта статья расчитана в большей мере на программистов.

Цифровая подпись?

Подпись как оказывается очень важна, а признаваемая государством - тем более. Снижаются затраты на распечатку и/или доставку счетов по оплате, договоров между работником и работодателем. Я уже не говорю про обычное подтверждение что документ прислан точно нужным человеком, а не хакером. Спасает положение то что у каждого гражданина Эстоини есть сертификат подписи, но его недостаточно. Проблема в том что одной подписи-закарючки в IT-мире недостаточно. Подпись в расширенном виде на самом деле включает в себя набор данные, в том числе не статичные.

  1. Стороны подписывающие документ

  2. Собственно документ или его отпечаток (говорящий о неизменном состоянии со времени подписания)

  3. Свидетели (нотариус) и роль сторон

  4. Время, место

Контейнер всей этой информации решили сделать на XML и назвать .ddoc расширением и связать с онлайн-сервисом создания и подтверждения подписей — Digidoc. За основу берутся основные свойства эстонской ID-карточки - авторизацияподпись и шифрование и в результате имеем:

  • цифровая подпись файлов (DigiDoc клиент, портал или третья сторона через DigiDocService)
  • шифрование и дешифрование файлов (DigiDoc клиент)
  • подтверждение действительности (digidoccheck)
  • подпись электронной почты
  • подпись или авторизация с помощью мобильного телефона (Mobiil-ID)

Контейнер со времени создания претерпел некоторые изменения, сейчас есть версия 1.3 основана на стандарте XAdES-X-L расширенных электронных подписей.

Процесс создания подписи с DigiDocService

Теперь собственно о главном что может понадобится на любом сайте. Допустим вы продаёте рога и копыта и хотите всё юридически правильно оформить. По-старинке это было бы типичный checkbox мол «согласен с условиями». Теперь же можно получить юридически действительную подпись клиента под любым договором, распиской купли-продажи или договора предоставления услуги.


Что-бы это у себя сделать Sertifitseerimiskeskus предоставляет услугу DigiDocService по SOAP, и для этого опубликованы следующие списки WSDL-методов: http://www.sk.ee/DigiDocService/DigiDocService_2_3.wsdl //почти live https://digidocservice.sk.ee/?wsdl //live - работает с CURL только вместе с Juur-SK.crt https://www.openxades.org:8443/?wsdl //test
В обмене данными участвуют следующие стороны

  • Клиент с нормальной ид-карточкой и софтом

  • Наше серверное приложение

  • Digidoc-узел (см. wsdl выше)

  • OCSP сервер, публикующий устаревшие или отозванные сертификаты id-карт

Если опустить очевидное, то процесс в общем выглядит так

  1. Создание сессии между приложением и digidoc (StartSession) с передачей инфы о контейнере (который может включать несколько подписываемых файлов) — либо целиком файлы, либо их SHA1-хэш. Запоминаем вернувшися SessionCode у себя

  2. Можно запросить с помощью GetSignatureModules сразу готовый html (со всякими апплетами, activex компонентами..) для того что-бы получить сертификаты клиента

  3. Клиент авторизуется передавая данные серверу, который вызывает PrepareSignature (signCertHex, signCertId), получает обратно бинарный хэш контейнера документов SignedInfoDigest который клиент должен подписать

  4. Клиент подписывает SignedInfoDigest введя PIN2 — генерируется подпись signValueHex и передаётся в FinalizeSignature(). На этом моменте digidoc проверяет действительность сертификата пользователя у OSCP

  5. В успешном случае можно уже скачать .ddoc файл. Если оригинальные файлы не отсылались, то их в base64-форме внедряют в вернувшийся xml. Сессия закрывается CloseSession.

Авторизацию и подпись можно поставить и с помощью мобильного телефона, где добавляются ещё и сторона оператора (MSSP), но я этот случай здесь не рассматриваю.

О качестве ddservice

Поставляемый php-пакет в качестве примера полон багов и говнокода — написанный под php4 надо постараться что-бы прикрутить его к PEAR под php5, надо увеличить таймаут curl во всех запросах с 4 секунд на что-либо существенное.

У меня в процессе вылетали ошибкииспользовал test-среду вместо live 200: Failed to get signature confirmation/notary // используйте live среду вместо test Validation constraint violation: data type mismatch xsd:string in element 'Sesscode' //приведите сессию в int-тип

Чтение сертификата с ID-карты

Возвращаемся к двум основным пунктам подписи. До вызова PrepareSignature метода, на странице есть компонент (Applet, ActiveX либо зависимый от браузера plugin) который считывает два параметра

  • signCertHex — сертификат подписи переведённый из цифрового DER формата в HEX

  • signCertId — идентификатор приватного ключа

В качестве компонента DigiDocService возвращает ActiveX для IE (EIDCard.cab файлик) и аплет для остальных ( SignApplet_sig.jar,iaikPkcs11Wrapper_sig.jar ). ActiveX в плане интеграции довольно прост - можно javascriptом вызвать оба метода, следовательно прикрутить их к любому дизайну, другое дело что у меня этот компонент не работает (уж и драйверы переустанавливал - не помогло). А вот аплет мало того что подгружает яву, так и в дизайн не вписывается со своими кнопками.

Firefox - EstEID XPCOM v0.4

В идеале каждый браузер мог бы завести свой plugin который бы поддерживал обработку созданного в RIA

<object type="application/x-esteid" />

Но глядя как это тянется c 2006 года в Opera, очевидно что это будет долго. Впрочем Firefox уже умеет использовать onepin-opensc-pkcs11.dll как с помощью SK'шного хака, так и с помощью плагина EstEID XPCOM v0.4 написанного в RIA и Smartlink. В результате имеем красивую картинку в Firefox и нет нужды читать страшные мануалы по копированию dll-файлов и ошибок «Teie arvutisse on vaja installeerida PKCS#11 ohjurprogramm

Этот компонент успешно может яваскриптом выкачивать данные об id-карте к примеру— document.getElementById('esteid').signCert.cert. Но этот сертификат подписи для DigiDoc надо первести в шестнадцатиричный формат из PEM. Примерно так:
        $sTempKey=str_replace(array(         "-----BEGIN CERTIFICATE-----",         "-----END CERTIFICATE-----",         "\n"         ),'',$sTempKey);         $sTempKey=base64_decode($sTempKey);         $sTempKey=bin2hex($sTempKey);
EstID-плагин теперь переехал и выпускается как open-source

Internet explorer - EIDCard / dsiglite2 + idutil

EIDCard.cab компонент судя по существующему коду прост - создаёшь объект, ссылаешься на этот файл, потом через vbscript спрашиваешь сертификат или запрашиваешь подпись digest'а - всё как в Firefox. Что-бы он заработал нормально надо соблюдать следующие заповеди

  1. Выключить автоматическое удаление сертификатов в ID-card tool если вы под Windows Vista с правами администратора
  2. Держать объект EIDCard за пределами формы, иначе он не будет доступен вовсе
  3. При создании подписи VBscript по умолчанию пытается записать результат в поле signValueHex, вот только видимо кто-то использует такую же переменную в компоненте из-за чего подпись не передаётся серверу.

dsiglite2.cab это альтернатива для создания подписи, правда его найти удалось только у swedbank'а на странице и он слишком низкоуровневый, пришлось отказаться. Третий компонент очень полезен - idutil.cab понимает события вытаскивания карточки, хоть и с использованием JScript'а (в итоге получается каша из трёх ECMAscript диалектов)

<!--Использование idutil для чтения личных данных в IE--> <div id="mTag"></div> <OBJECT  ID="myCard" CLASSID="CLSID:7F9F89F2-F12B-4B25-9C69-7358F38B898B" CodeBase="idutil.cab"></OBJECT> <SCRIPT LANGUAGE="JScript" FOR="myCard" EVENT="CardInserted() ">     var mTag = document.getElementById("mTag");     mTag.innerHTML = "Reading data...";     timerId = window.setInterval("reading()",500); </SCRIPT> <SCRIPT LANGUAGE="JScript" FOR="myCard" EVENT="CardRemoved() ">     var mTag = document.getElementById("mTag");     window.clearInterval(timerId);     mTag.innerHTML = "Card removed"; </SCRIPT> <SCRIPT LANGUAGE="JScript"> var timerId; function reading(){     var mTag = document.getElementById("mTag");     window.clearInterval(timerId);     mTag.innerHTML = "";     try {         myCard.ReadCard();         mTag.innerHTML='Hello,'+myCard.familyName+' '+myCard.personalCode;         }     catch(e) {         mTag.innerHTML="Reading failed";         }     } </SCRIPT>

Если вы «переписываете» ddservice, то имеет смысл сохранить корень (wsdl класс) и переписать обёртку. Обратите внимание что после чтения сертификата и PREPARE, нельзя перенаправлять на другую страницу - надо делать POST на ту же самую страницу, иначе аплет будет ругаться. Вторая проблема - правильно заменять маркеры вида 1 на реальные данные. Ну и третья проблема - расставить пути к jar-файлам если у вас используется ЧПУ, иначе плагины будут искаться в локальной несуществующей папке.

Validity confirmation

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

  • Данные о файле и пользователе - приходят в ответе FinalizeSignature. Там очень просто - ходи по массиву и выдёргивай что тебе надо.

  • Серийный номер сертификата - десятичная версия  находится в ['SignedDocInfo']->SignatureInfo->Signer->Certificate->IssuerSerial и легко переводится в hex

  • Сертифицирующая сторона (собственно SK) в явном виде отсутсвует, надо выдирать из ['SignedDocInfo']->SignatureInfo->Confirmation->ResponderCertificate->Issuer

  • Хеш публичного ключа сертифицирующей стороны. На данный момент это ESTEID-SK 2007 и он есть на сайте, но правильней конечно запрашивать его динамически через WSDL метод GetSignersCertificate(). В php к результату надо приделать "-----BEGIN CERTIFICATE-----" и концовку (что-бы получить PEM формат) и взять от него openssl_x509_parse(). Внутри и будет находится заветная 4806DEBE ... Вариант захардкодить и обновлять каждые X лет я не рассматриваю

  • Хеш OCSP-сертификата о действительности карточки (HASH VALUE OF VALIDITY CONFIRMATION (OCSP RESPONSE)) берётся из WSDL метода getNotary() из которого OcspData попадает в sha1(base64_decode(...))

Ваш покорный слуга на время написания статьи нашёл мега-баг в том листочке что генерирует Digidoc Client - там OCSP responce hash всегда одинаковый. Кроме того я бы добавил хеши самих документов для печати, иначе слишком много зависимости от памяти SK. Ну и в подарок - метод hex2bin

        function hex2bin($data) {             $len = strlen($data);             for($i=0;$i<$len;$i+=2) {             $newdata .= pack("C",hexdec(substr($data,$i,2)));             }             return $newdata;         }

CSS фреймворки

· 3 мин. чтения

четверг, 31 декабря 2009 г. в 14:45:52

CSS frameworks это набор подходов по упорядочиванию кода описывающего внешний вид страницы (representation) с учётом смысла содержания (семантики) для повышения эффективности.Кроме ускорения работы побочные эффекты — стандартизация и как результат плюсы в коммандной работе, более простой, понятный и единый код. Хотя тема затрагивает больше дизайнеров и верстальщиков которые занимаются созданием css+html страниц из psd -макетов, тут и backend-программисты найдут для себя что-нибудь интересное.

Выключатели

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

Сетки

Grids нужны для облегчения восприятия. Человеку нравится видеть порядок в парках и дорогах, зданиях и страничках в интернете. Вертикальные или горизонтальные линии с равномерными отступами - основа сетки. Обычно вёрстка либо фиксированная (px), либо динамическая-резиновая (%, em). Смешанные достаточно сложно делать.

Из вертикальных сеток существуют:

  • Blueprint - Полотно 950px с вертикальной сеткой. Последние элементы имеют класс last

  • 960 grid system - Первые и последние элементы alpha и omega классы соответсвенно.

  • YUI grids - наглядный пример как не стоит называть классы

  • YAML

В целом все эти сетки говно, потому что несемантичны и нужны ленивым верстальщикам что-бы писать меньше кода - вместо style="width:960px;" - class="block-24"

Чем дальше в лес

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

Но зачем останавливаться только на этом? Можно ведь и вместо html писать иерархии в питоновском стиле -haml. Это уже не xml конечно, но фантазия уже начинает бурлить.. тут не возникнет проблем с потерянными и не закрытыми тэгами. Но вернёмся к внешнему слою.

Самоорганизация

Как вы организовываете стили в своей папке? В идеале я вижу примерно такую картинку

  • Отдельные файлы под необычные экраны - print, projector, pda/iphone

  • Отдельные файлы-костыли под не строгие w3c браузеры и оси. Грабли для IE6, Mac, pngfixы, закруглённые уголки и тп.

  • Один сгенерированный screen.css для открытой страницы только с тем что необходимо (типа css autoload)

    • Reset

    • Layout - основная структура страницы. Ключевые слова классов - menu, content, article, search, breadcrumbs, comments, feedback, navigation, contact, paginator, gallery, news, login. По возможности по-минимому использовать нефункциональные "sidebar, header, footer, left, right" и служебные "wrapper, container, inner, outer"

    • Иконки и флаги, наверняка спрайт

    • Кнопки и табы, тоже спрайт

    • Skin/Theme - в случае каких-то динамических стилей (в зависимости от сезона, группы пользователя, идентификации продукта) можно разным цветом раскрашивать элементы и имеет смысл выделить цвет в отдельный файл

    • Content - основная составляющая статьи. Включает заголовки, списки, таблицы перечисления, формы ввода, обводы картинок, цитат и тп.

  • Левые библиотеки которые приходится порой подправлять, типа jquery ui, thickbox, fancybox, lightbox...

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

Dragon Age Origins

· 5 мин. чтения

Dragon Age - симпатишная тактическо-групповая RPG от Bioware с элементами паузы боя, эдакая смесь Neverwinter nights, Elder's Scrolls: Oblivion, Dungeon Siege, Fallout 3, Witcher. Прочувствовать можно на мини-игре Dragon Age Journeys. Дальше возможные спойлеры..

Предпринимательство в Эстонии

· 7 мин. чтения

Предприниматель (enterpreneur , эст. ettevõtja) - активный человек который что-либо производит или предоставляет услугу потребителю и в условиях конкуренции стремится к использованию более эффективных методов получения прибыли. Концепция предпринимателя появилась в 18 веке с развитием частного права и индустриализации.

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

  1. Определение потребностей и возможного рынка (разведка)
  2. Разработка товара или услуг с концентрацией и ресурсов (тут есть риск неправильной оценки рынка)
  3. Развитие в зависимости от ситуации (перегруппировка сил, приспособление)

Формы предприятий (в Эстонии)

Точно так же как кровеностная система делится по размерам артерий и вен, так и компаниями могут объединяться и работать как

  • Физическое частное лицо (FIE, füüsilisest isikust ettevõtja) - предприниматель как частное лицо. Простота регистрации, упрощённая бухгалтерия, полная материальная ответсвенность, ограничение максимального капитала.
  • Полное товарищество (TÜ, täisühing) - два или более владельцев, полностью отвечающих за обязательства своим имуществом, нет требования в минимальном капитале
  • Договорное товарищество (UÜ, usaldusüging) - два или более владельцев, где один отвечает за обязательства своим имуществом, а остальные - в согласно договору
  • Предприятие с ограниченной ответсвенностью (, osaühing) - акционерный капитал (минимум 40 тыс крон) поделен на акции между акционерами, которые не несут личной ответсвенности перед обязательствами предприятия. Минимальная цена 100 крон за акцию. При капитале более 400 тыс обязателен аудитор.
  • Открытая акционерная компания (AS, aktsiaselts) - акции открыто продаются общественности, минимум 400 тыс начальный капитал., отсутсвие влияние одного человека на судьбу всей компании.

В сторонке стоят:

  • Некоммерческие объединение (MTÜ, mittetulundusühing) - предприятие, стремящееся к определённым (социальным) целям, ограничено в распределении доходов между членами.
  • Государственные органы и самоуправления - могут предоставлять услуги открытому сектору
  • Благотворительные организации - налогами не облагаются

Компании могут объединяться в группы

  • Консорциум - объединение предприятий для одной цели-продукта, где каждое предприятие оптимально в своей области.

  • Картель - объединение компаний близкой рыночной области для контроля цен, оставаясь независимыми во всём остальном

  • Синдикат - объединение компаний с потерей сбытовой самостоятельности

  • Концерн - объединение компаний горизонтально по близкой области (все пивоварни), вертикально (весь процесс добычи-разработки-сбыта) или смешанно (конгломерат)

  • Франчайзер-франчайзи - предоставление права использования торговой марки и технологий ведения бизнеса, как правило при строгих условиях (например McDonald's, Columbia sportsware, 1C)

  • Филиал - представительство иностранной компании

Компания как объект экономической системы состоит из

  1. Внутренней среды - управляющие, владельцы и работники
  2. Внешней микросреды - потребители, подрядчики, конкуренты, человеческие ресурсы (потенциальные работники), финансовые ресурсы (потенциальные инвесторы)
  3. Внешней макросреды - политической, экономической, социальной, технологической, природной и международной обстановки. Законодательное влияние воплощено в законах о трудовом договореконкуренцииналогообложенииAcquis Communautaire

Бизнес идея и бизнес план

Бизнес-идея не возникает из ниоткуда. Всё появляется на основе уже существующего опыта. Бизнес идея воплощаясь в бизнес-плане отвечает на множество вопросов — что, кому, как, когда, кем (производится продукт или услуга).

Новая идея это:

  • инновация (техническое воплощение научных открытий)

  • эмоции (сделать более человечески приятный подход к клиенту)

  • функции (больше, удобней, легче)

  • морфология (другие цвета, форма упаковки, дизайн-идея, реклама, персонализация)

  • дешевле (оптимизация, скидки)

Все эти идеи приходят либо от старых продуктов (71%), халтур или хобби (7%), системных поисков решения (4%), путешествий (1%) и проч. Однако, наличие бизнес-идеи не говорит об успешной бизнес-возможности.

Анализ бизнес-возможностей дело не простое — сколько у целевой аудитории денег, кто они по возрастам, профессиям, как лучше всего им продавать товар, как изменяются потребности и демография потребителей со временем и местом. И в зависимости какой товар (нишевый он или массовый, эстетически ценный, cверх-функциональный, модный, прочный, надёжный, экологичный) надо продумать весь жизненный цикл (как он устанавливается, используется, обслуживается, обновляется)

На каждом этапе жизненного цикла продукта он имеет свою цену:

  • Производство - воплощение форма товара и его переработка (recycling)

  • Транспорт - пространственная ценность (сколько места занимает в автомобиле)

  • Логистика - ценность пространственного и временного перемещения (насколько далеко и быстро можно перевозить)

  • Торговля - ценность владения

SWOT-таблица (Strengths,Weaknesses,Opportunities,Threats) в бизнес-плане это хороший способ увидеть перспективы продукта на рынке. Он включает и анализ рынка и состояние микро-макро среды предприятие, возможные изменения

Маркетинг

Торговля (marketing) это часть процесса управления предприятием с целями нахождения и продажи продукта/услуги потребителю (или более общими словами - в удовлетворении спроса предложением). Есть несколько психологических способов продаж (концепций):

  1. Производственная — масштабное конвейерное производство. В больших объёмах выходит дешевле, а универсальность охватывает многие аудитории (телефоны, автомобили)

  2. Продуктная — идёт работа над улучшением качества одной линейки продуктов (skype, windows)

  3. Рекламная — клиент не купит покуда не узнает (продукты питания, косметика)

  4. Торговая — сделать лучше чем у конкурентов (телефонная связь)

  5. Социальная — направленная на конкретную (узкую) аудиторию (магазин комиксов)

  6. Общительная — создание постоянной связи с клиентом (парихмахер, юрист, дантист)

  7. Ценностная

Диаграмма оценки компаний по перспективностиТеория 4P говорит о маркетинговом планировании с помощью четырёх «координат продукта» (продукта, цены, продвижения и местоположения), тогда как теория 4C говорит больше о клиенте (потребитель, цена, удобство, связь). Товарный знак/марка — предмет права интеллектуальной собственности и служит для обозначения товара.

Цена товара может формироваться несколькими способами

  1. Сколько клиент готов платить
  2. Сколько стоит у конкурентов
  3. Принцип самоокупаемости

Бостонская матрица — один из способов описания состояния продукта на рынке и его динамику. В идеале продукт должен находится в области «дойной коровы», тогда наблюдается постоянная прибыль с малыми изменениями на рынке. Продукты-«звёзды» это потенциальные победители в скачках, покуда индустрия не успокоится. «Трудные дети» это стартапы — они могут захватить рынок при нужном управлении

Налоги в Эстонии

Прямые налоги:

  • Налог с оборота (käibemaks = НДС = VAT) — 20% от стоимости товара или услуги (с 1 июля 2009 г.) платит продавец государству (но включает налог уже в цену) каждый месяц 20го числа. Если у продавца оборот менее 18 тыс евро в год, то налог не платится.
  • Социальный налог — 33% от заработной платы работника (c 2003 г.) платится работодателем государству, которое пускает его на пенсионное обеспечение (20%) и медицинское страхование (13%).
  • Налог по безработице — 1.5% от брутто-зарплаты работника (формально 0.5% от работодателя и 1% от работника)

Косвенные налоги:

  • Подоходный налог (tulumaks) — 21% от выплачиваемой прибыли работникам (kasum), выплачиваются государству 10 числа каждого месяца. Если все доходы остаются в компании то платить не надо
  • Акцизы — дополнительные налоги на второстепенные товары (алкоголь, табак, топливо, автомобили, упаковку)
  • Таможенные пошлины (tollimaks) — взимается с импорта

Бухгалтерия

У бухгалтера сложная работа, потому что постоянно надо писать отчёты в Maksu- ja Tolliamet, поэтому выгодней нанимать профессионала, что бы не сесть в лужу с этими "простыми" расчётами.

  1. Каждый год — отчёт за хозяйственный год (вместе с управленческим отчётом). Состоит из баланса, отчёта о прибыли, отчёт о денежных потоках, а также отчёт об изменении собственного капитала.

  2. Каждое 10 число месяца - декларация уплаты налогов с зарплаты (TSD, INF1, INF11)

  3. Каждое 20 число месяца - декларация уплаты налогов с оборота

А вот основные формулы:
Имущество = обязательства + собственный капитал
Доход = общая прибыль - общие расходы
Оборот = кредит - дебит

Баланс

Баланс показывает финансовое состояние предприятия на определённый промежуток времени. Состоит из двух равных частей:

Баланс АО Рога и Копыта
АктивПассив
Оборотное имуществоОбязательства
ДеньгиСчета к оплате (поставщикам)
Ликвидные ценные бумаги (купленные с целью перепродажи)Задолженность по налогам (государству)
Счета к получению (от клиентов)Долгосрочные обязательства (займы, облигации)
Товары и материальные запасы (в том числе незавершённые товары)Прочие обязательства
Основное имуществоСобственный капитал
Здания и оборудованиеАкционерный капитал
Прочие долгосрочные активыНераспределённая прибыль

Баланс Актива и Пассива появляется за счёт разницы - Собственного капитала, который показывает какая часть имущества принадлежит владельцам после погашения обязательств.

Отчёт о прибыли

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

По теме

Unity3D

· 7 мин. чтения

Unity3D это игровой движок 3D-игр в основном стрелялок и аркад, но при большой сноровке можно реализовать и RPG, RTS, квесты, 2D-игры, встраиваемые в браузер, iPhone и с использованием сети. Движок понимает множество разные форматы файлов

  • 3д модели и анимация из Maya, Cinema 4D, 3ds Max, Cheetah3D, Modo, Lightwave, Blender. Форматы 3ds, fbx и dae
  • практически все растровые изображения для маск и текстур
  • звуковые mp3, wav форматы для эффектов и фона

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

IDE

Графическая оболочка разработчика (IDE) состоит из 4 основных панелей

  1. Графическое поле, переключающееся / вид игры (Game & Scene)
  2. Иерархия объектов (Hierarchy)
  3. Инспектор объекта (Inspector)
  4. Библиотека доступных ресурсов (Assets)

По используемости самое важное место это Инспектор, потому что именно в нём видны внутренности объекта (GameObject)

Создание карты

Карта (Terrain) создаётся очень просто из меню и по умолчанию уже есть. Курсором как в фотошопе можно изменять высоту рельефа (в том числе используя Shift). Более продвинутые господа придумали как импортировать карты из реального мира с помощью google earth, openTDD, делая так называемые heightmaps. Встроенный импорт работает только с raw форматами, надо использовать хак. Недавно вышел генератор карт

Игровой объект Unity

Игровой объект может состоять из скриптов-компонентов, некоторые из них встроенные, некоторые надо писать самому, тоесть:

Свои скрипты добавляются очень легко перетаскиванием в инспектор и публичные переменные сразу переводятся в названия с пробелами и значением по умолчанию. Для игрового объекта добавленные компоненты и с точки зрения ООП являются инкапсулированными объектами, хотя и играют в большинстве своём роль свойств (т.е. прилагательных - движущийся, крутящийся, выбираемый и тп.). По синтаксису скрипты пишутся на Javascript, C# или Boo скриптах со своими прибамбасами - глобальными объектами Unity, некоторыми своими ключевыми словами..


Взаимодействие объектов

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

Поскольку объекты можно вкладывать друг в друга как dom-блоки, то искать по иерархии объекты можно несколькими путями. Жалко что ребята изобретали велосипед, вместо того что-бы взять существующие аналоги из html/js

  • Сразу писать название компонента скажем myWorkerGuy.someColorParam

  • Поиск по иерархии - transform.Find("MyWorkerGuy") - аналог html'ного getElementById

  • По тєгам, через GameObject.FindWithTag ("Worker")

Компонент объекта доступен через - GetComponent("Moveable").

Ещё одно мощное решение - вместо поиска объекта с проверкой наличия метода и затем вызова его, можно просто послать сообщение - gameObject.SendMessage("BegForFood",true), причём метод вызывается у всех компонентов.

Каждый компонент наследует класс Monobehaviour (в Javascript синтаксисе объявлять не нужно) и именно с ним приходится работать описывая логику и расширяя наследуемые методы которые сами вызываются когда движок решит это нужным, например:

  • Invoke - вызов третьего метода, в том числе периодический, аналог call_user_method в php + cron

  • Awake - своего рода конструктор, вызывающийся когда все объекты уже существуют.

  • Start - конструктор второго рода, вызывается после Awake

  • Update - вызывается каждый фрейм. Сюда идёт основная логика.

  • FixedUpdate - вызывается каждый n-фрейм, полезен для вычислений твёрдых тел

  • LateUpdate - вызов после всех Update вызовов, полезен для камеры

  • OnGui - сюда идёт показ кнопок, цифр для управления

Реальные нужды

После того как вы придумаете историю, надо продумать основные технические моменты. К этому моменту вы знаете что есть объекты и их характеристики (компоненты), но из чего состоит процесс игры?

Рождение (Spawn) юнитов и врагов. Объект создаётся с указанием, где и с каким вращательным моментом. Как оказывается нарожать много умных юнитов с поддержкой всех фич (в частности физики) очень нагружает процессор.

GameObject go = Instantiate (building,hit.point,Quaternion.identity) as GameObject;

Управление камерой. Существуют уже заранее сделанные компоненты-скрипты на всякие случаи жизни, которые учитывают в том числе столкновение камеры со стеной и тп. Вот часть кода для изометрической камеры (добавьте остальные направления сами)

if (Input.GetKey("up") && transform.position.z < terrain.terrainData.size.z) {
transform.position += linearSpeed * Vector3.forward * Time.deltaTime;
}

if(Input.GetAxis("Mouse ScrollWheel") > 0 && transform.position.y > 1){
transform.position -= linearSpeed * Vector3.up * Time.deltaTime;
}

Выделение юнитов мышкой. Достаточно сложная задача - в кратце на камеру вешается обработчик нажатий и передвижения курсора. Независимо создаётся singleton-объект для хранения всех юнитов. При нажатии и передвижении курсора происходит проекция прямоугольника с маской ландшафта. Задача не из лёгких, потому что обрабатывать надо и deselect, учитывать клики для передвижения и атаки, рождение юнитов и тп. Возможно singleton не самое хорошее решение и лучше это сделать тэгами.

mouseButton1UpPoint = screenPosition;
var hit : RaycastHit;
ray = Camera.main.ScreenPointToRay (screenPosition);
if ( Physics.Raycast (ray, hit, raycastLength, terrainLayerMask) ){
selectionPointEnd = hit.point;
UnitManager.GetInstance().SelectUnitsInArea(selectionPointStart, selectionPointEnd);
}

Поиск пути (Pathfinding) и передвижение юнита кликами мышки очень алгоритмически увлекательная задача. К счастью существует отличное решение Арона Гранберга. Алгоритм A* интересно в теории, но в редакторе можно и запутаться. Основная идея в том что юниты имеют дискретную сетку клеток для расчёта передвижения. 

Сетка генерируется из ландшафта и можно задать ограничения по углу наклона, максимальной высоте и тп. В плане кода - очень сложная штука. На практике его решение подразумевает что у каждого передвигаемого объекта есть Seeker компонент которому прицеплена цель куда надо дойти. При установки цели буквально надо выполнить

GetComponent("Seeker").StartPath (transform.position,destinationPoint);

Seeker расчитает путь по которому можно добраться до цели (обычно это ломанная кривая из 3х отрезков) и дальше уже своими силами надо реализовывать передвижение по этим точкам.

Движение юнитов. Пожалуй самое сложное, поскольку если юниты обладают физикой то это усложняет задачу. Надо просто понимать что нельзя сказать юниту x=x+1 через фиксированные участки времени. По идее надо использовать rigidbody.AddForce и учитывать ситуации OnCollision. Ещё одна проблема - повороты объекта. Они далеко не простые

transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);

Минусы и сложности

Эта статья написана в 2010 году, поэтому вероятно эти минусы уже исчезли, но всё-таки..

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

Падения. Движок падает в разных случаях - как от неосторожного движения с интерфейсом, пробного Run с косячным скриптом, так и просто при работе. Порой обидно что «не сохранился».

Глюки интерфейса. Это не так критично как падения, но мозги плавятся. Например проблема с зумом колёсиком мышки - камера перелетает килопиксели , не давая плавно подобраться к нужной сцене. Или например если вы импортировали модель с большим числом текстур или mesh-форм, будьте уверены что в следующий раз диалоги с таким содержанием будут забиты ненужными значениями.

Глупый GUI. Во времена когда HTML5 реализуется всеми браузерами, тут приходится писать очень странный код, напоминающий layout в Java Swing (sic!) и порой вычитывать недокументированные особенности на форуме (например что при декларации кнопки его onclick event сразу внутри скобок, а вот как получить onmouseover и другие события или изменить её дизайн - та ещё тайна).

Синтаксис. Согласен - трёхмерный мир это сложно и я даже могу понять почему используются математические термины типа кватерниона вместо "поворота в пространстве", но почему нельзя использовать короткие методы для основных функций, или почему нельзя в JS создавать глобальные объекты.

Дебаг. Из-за того что код размыт на объекты-компоненты очень сложно организовывать нормально проект и как следствие сложно дебагить, даже несмотря на консоль, подсветку и возможность поменять значения на лету. Сложно и оттого что Scite который по умолчанию редактирует скрипты не знает никаких подсказок о пространстве переменных Unity, не умеет ничего подсказать, нельзя перепрыгнуть в нужное место как то привычно в других языка и IDE.

Расширения

Unity позволяет не только писать скрипты под существующие объекты, но и изменять саму IDE добавляя новые панели управления и меню, то движок можно расширить своими мини-фреймворками

  • Explosion- многопараметрические взрывы (цвет, взрывная волна, дым, размеры)
  • Locomotion - движение людей и зверюшек c вызовом нужной анимации при соответсвующих вводах с клавиатуры
  • Skydome - динамическое небо
  • Last Bastion Games - диалоги, recorder, прототип RTS и гонок

Обязательно гляньте:

  • LearnMeSilly - набор основных уроков по работе с редактором, объектами

  • Blender - бесплатный редактор. Можно в нём создать модели и экспортировать в 3ds

  • Turbosquid - коллекции 3д моделей (в т.ч. платные)

  • Unity3D Answers - своего рода база проблем и решений

PHP frameworks

· 5 мин. чтения

суббота, 10 октября 2009 г. в 23:32:55

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

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

Codeigniter 1.7.6 - легковесный (1 mb) и простой в освоении. За основу берётся MVC-паттерн, популяризированная в ruby on rails. Основное приложение лежит в application папке, делится в свою очередь на контоллеры, шаблоны и модели, кроме того папки - errors, helpers, language, config и hooks.  Классы контроллеров соответсвенно наследуют Controller и по умолчанию запускается index-метод, шаблоны показываются через this->load->view(имя_шаблона, передаваемые_переменные).

Из полезного замечены классы валидации форм, работы с изображениями (imagemagick, watermark), trackback-запросов для статей в блогах, автогенерация кода (scaffolding). Само собой поддержка разных бд (mssql, mysql, postgre, oracle, sqlite). Итого получается достаточно типично - одно приложение, разбитое по контроллерам. Идеальный фреймворк для минималистов типа меня.

Сайт очень позитивный - вики, видео примеры, форумы и багтрекер.

Symfony 1.3a от Sensio Labs позиционируется как более тяжёлый каркас (15 mb!). Та же MVC, но теперь с использованием ORM (Propel или Doctrine). Из ещё полезных фишек - кеширование шаблонов, scaffolding, многоязычность, чпу, недоступность исполняемых файлов от публичного каталога апача (как следствие - безопасность), настройка среды где проект вертится (development, testing, production). В минусы я бы отнёс привязку к JS библиотеке (Prototype), достаточная тяжеловесность по оперативке и времени из-за отсутсвия lazy loading классов (sic!) и опять же ORM.

Ещё одной особенностью является использование YAML в качестве файлов настроек. Если смотреть пример установки тестового (sandbox) приложения то видно что есть работа с консолью по автогенерации файлов моделей. Приложения в свою очередь состоят не только из моделей (обеспечивающим интерфейсы к бд), но и из модулей (с CRUD-действиями и интерфейсами).

По запуску процесса мне показалось очень сложным. Надо прописывать настройки в .yml файлах, что-бы сгенерировать всей файлы. Потом по идее грузится front controller, который вызвает модуль и в нём уже метод (по умолчанию - executeIndex) и вызывает шаблон indexSuccess.php

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

CakePHP 1.2.6 позиционируется как клон RoR и пожалуй с него слизан был Codeigniter (в том числе и поддержка старого php 4 ). Понимание как работает CakePHP это по сути понимание как работают остальные похожие каркасы или почему они работают неправильно. Почему именно это решение не стало очень популярным - сложно сказать, может дело в названии и не все такие сладкоежки.

"Пирожок" в общем быстрей чем Codeigniter и Yii, весит 7 мб и в общем предполагает тоже определённые названия классов (AppController, AppModel). В шаблон данные из контроллера передаются через $this->set(). Что понравилось - есть возможность юнит тестирования, очистки данных (Sanitize::paranoid), автогенерации кода (Cake bake), использования модели как дерева (и его показ методом generatetreelist)

Zend Framework 1.9 скачать проблематичней - надо регистрироваться на сайте этой Zend-компании которая и имеет то преимущество что выпускает свой IDE, Optimizer и сервер. IDE у них глючный, поэтому к каркасу приложений я так же скептически отношусь. И не зря - этот монстр выпускается в двух версиях и минимальная из них весит 20 мб! Названия классов всюду фигурируют с Zend префиксом. В общем сразу видно отношение к разработчикам.

В плюсы - большая независимость классов. Можно взять тот же Zend_DB и использовать только его в своём проекте, подобно библиотеке PEAR, ещё в Zend_DB уже есть выборка данных методами fetchPairs, fetchAll (которые я давно использую в своём движке), переводы в зависимости от числительности (Zend_Translate::plural), интеграцию с PHPunit, разделение на приватный и публичный каталог, ограничение прав (Zend_Acl).

По структуре.. Контроллеры наследуют Zend_Controller_Action и по умолчанию запускают indexAction метод. Данные в шаблон передаются через переменную контроллера $this->view. Шаблоны хранятся в .phtml файлах.

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

Поскольку ZF достаточно популярен, то с документацией и обучением проблем не встанет, разве что постигать надо достаточно много. Наверняка используется в больших проектах 

Akelos в основном продвигает Bermi Fermer и сразу признаётся в том что это максимально полный клон RoR и весит приличные 9 мб. Запуск очень аналогичен вышеназванным каркасам, поэтому я не удивляюсь что контроллер наследует ApplicationController и по умолчанию тоже вызывается index-метод. Переводы в контроллере можно получить через AK::t() метод, что странно и непропорционально относительно названий других объектов и методов.

Данные в шаблон летят через $this->saveAttribute(). Вобщем ничего отличительного что вы в руби не видели. Интересная выборка с использованием ActiveRecord и множественностью ассоциаций между моделями (has_one, belongs_to). Использование AdoDB в качестве адаптера к базе данных, хранение сессий в базе.

Минусы - интеграция с Prototype.js и scriptaculous, отсутствие документации, хранение переводов в ассоциативном массиве, практически нулевая популярность и сообщество разработчиков. Вряд ли пока стоит брать на вооружение.

Yii PHP Framework 1.0.9 на удивление хорошо документируется в рунете, целиком объектный и хвастающийся что он быстрей даже чем CodeIgniter, хотя скорость по идее зависит от многих вещей кроме скелета. Развился из Prado, весит неплохие 7 мб.

По запуску - вызывается контроллер который наследует CController, потом в зависимости от запрашиваемого URL вызывается более низкий класс который наследует CAction. Для всяких дополнительных проверок на права можно использовать фильтры - CFilter. Модели могут быть двух типов - Active Record либо CFormModel. Шаблоны показываются в контроллере через $this->render().

Префикс "C" как и с "Zend" даёт какую-никакую совместимость но и добавляет шума. В целом мне показался каркас удобней чем Symfony, но чуть более корпоративный чем CodeIgniter.

Читайте также

Drag-n-drop file upload

· 3 мин. чтения

суббота, 26 сентября 2009 г. в 22:21:16

В продолжение статьи о новинках в html5, вот нашёл демо где уже работает загрузка файлов обычным перетаскиванием в браузер Firefox 3.6. Обычный drag-n-drop файлов пока в стабильных браузерах максимально что могут — создать события аналогичные перетаскиванию dom-элементов в определённые контейнеры.

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

event.dataTransfer.files event.dataTransfer.mozTypesAt(0) event.dataTransfer.files[0].getAsBinary()

А для отсылки файла используется обычный аяксный объект у которого появляется метод sendAsBinary(). Вобщем пока это выглядит как хак и видимо что надо больше внимания уделить спецификации html5, что-бы пользователь случайно не загрузил весь C:\Windows, что-бы можно было временно отложить загрузку или отфильтровать что конкретно надо загружать, или до какой глубины надо структуру подгружать и как обрабатывать.

Jquery dnd-upload

Написал два jquery-плагина - один для поддержки Firefox 3.6 (Namoroka) HTML5 загрузки, другой для поддержки Google gears. Можно использовать оба вместе..

Самый простой вариант для gears:

$('#drop_area').uploadg({gate:'http://somesite.com/upload_here_path/'});

Заметьте что ключ получаемого у сервера файла будет "file" (в пхп соответсвенно $_FILES['file']). А вот расширенный пример кода инициализации..

var dragndropConfig={ beforeLoad:function(){ this.gate=some_dynamic_file_upload_url+'?parentID='+SomeOtherDynamicObject.ID; if(SomeDisableReason){  this.can_proceed=false; } }, onProgress:function(event) { if (event.lengthComputable) { var percentage = Math.round((event.loaded * 100) / event.total); if (percentage &lt; 100) {  $('#some_progress_div').html('Uploading file..'+percentage+'%'); } } }, onComplete:function(event,txt) { $('#some_progress_div').html('done');  } }; if (window.google && google.gears){ $('#drop_area').uploadg(dragndropConfig); } else{ $('#drop_area').upload5(dragndropConfig); }

Осторожно, Google gears всё ещё имеют баги связанные с такой загрузкой.

/**
* HTML5 drag and drop file jquery file uploading
*
* @author Artjom Kurapov <artkurapov@gmail.com>
**/
$.upload5=function(input, opt){
var ME=this;
ME.option = {
gate:'',
can_proceed:true,

dragEnterColor:'#ffc',
dragExitColor:'#fff',

beforeLoad:function() {},
onProgress:function(event) {},
onComplete:function(event) {}
};

if(typeof(opt)=='string'){
opt={'gate':opt};
}

ME.option = $.extend(this.option,opt);


ME.upload = function (event) {

event.stopPropagation();
event.preventDefault();

ME.option.beforeLoad();
if(!ME.option.can_proceed){
return false;
}

var data = event.dataTransfer;

/*
for (var i = 0; i < data.files.length; i++) {
$('#image_list').prepend($('<img src="img/spinner.gif" width="16" height="16" />').css("padding", "33px"));
}
*/

var boundary = '------multipartformboundary' + (new Date).getTime();
var dashdash = '--';
var crlf = '\r\n';

/* Build RFC2388 string. */
var builder = '';

builder += dashdash;
builder += boundary;
builder += crlf;

var xhr = new XMLHttpRequest()


xhr.upload.addEventListener("progress", ME.option.onProgress, false);

xhr.open("POST", ME.option.gate, true);

if($.browser.safari){
var formData = new FormData();
formData.append("file", data.files.item());
xhr.send(formData);
}
else{


for (var i = 0; i < data.files.length; i++) {
var file = data.files[i];

/* Generate headers. */
builder += 'Content-Disposition: form-data; name="file[]"';
if (file.fileName) {
builder += '; filename="' + file.fileName + '"';
}
builder += crlf;

builder += 'Content-Type: application/octet-stream';
builder += crlf;
builder += crlf;

/* Append binary data. */
builder += file.getAsBinary();
builder += crlf;

/* Write boundary. */
builder += dashdash;
builder += boundary;
builder += crlf;
}


/* Mark end of the request. */
builder += dashdash;
builder += boundary;
builder += dashdash;
builder += crlf;

xhr.setRequestHeader('content-type', 'multipart/form-data; boundary=' + boundary);

try{
xhr.sendAsBinary(builder);
}
catch(err){
Note.set('error',t("Upload failed - use only latin-encoded filenames"),13);
return false;
}
}

xhr.onload = function(event){
ME.option.onComplete(event,xhr.responseText);
};
}

$(input).get(0).addEventListener('drop', ME.upload, false);

$(input).get(0).addEventListener('dragenter', function(event) {
$(input).css("background-color", ME.option.dragEnterColor);
event.stopPropagation();
event.preventDefault();
}, false);

$(input).get(0).addEventListener('dragover', function(event) {
$(input).css("background-color", ME.option.dragEnterColor);
event.stopPropagation();
event.preventDefault();
}, false);

$(input).get(0).addEventListener('dragexit', function(event) { $(input).css("background-color", ME.option.dragExitColor); }, false);

return ME;
}

$.fn.upload5 = function upload5(options){
this.each(function() {
var input = this;
new jQuery.upload5(input, options);
});

return this;
};

League of legends

· 7 мин. чтения

League of legends — это сетевая игра, двух групп игроков (по 5 или 3 человека) друг против друга. Это наследник мода Warcraft 3 DOTA, который породил ещё с десяток игр, в том числе DemigodHoN и будущую Dota2. Помоему игра вызывает привыкание даже больше чем WoW, из-за коротких битв (30-60 мин).

Игра бесплатна, живёт на продаже скинов, постоянно обновляется и получает новых персонажей. Весит в районе 600 мб + апдейты (300 мб), крутится на adobe air + directx с чем-то. Есть неоффицальный клиент для мака на основе wine.

О тестировании web-приложений (ITI0120)

· 10 мин. чтения

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

А если отвлечься и рассматривать системно, то роль тестера на самом деле лежит в каждом человеке. Если смотреть на проект как на человека, то роли

  • управляющего проектом это позвоночник и вегетативная нервная система
  • программисты это скелет и моторика
  • аналитики это органы чувств
  • тестеры это совесть

Home

· 4 мин. чтения

Посмотрел документальный фильм «Home» о земле как единой экосистеме и вмешательстве человека. Один из тех «зелёных» фильмов, которые энергетики и промышленники так не любят.

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

Или ещё один пример — великое вымирание 96% всего живого в палеозое (пермский период) произошло по всей видимости из-за застойности воды в океане. Большие океанические течения просто перестали гонять воду между экватором и полюсами, возник недостаток кислорода (аноксия).

Deadman

· 2 мин. чтения

Христос, которого я чту,
Враждебен твоему Христу.

С горбатым носом твой Христос,
А мой, как я, слегка курнос.

Твой - друг всем людям без различья,
А мой слепым читает притчи.

Что ты считаешь райским садом,
Я назову кромешным адом.

Сократ милетов идеал
Народным бедствием считал.

И был Кайафа убежден,
Что благодетельствует он.

Мы смотрим в Библию весь день:
Я вижу свет, ты видишь тень.

Спиральная динамика

· 1 мин. чтения

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

А ещё взял у Давыдова неплохое, хотя и слишком длинное видео от БиБиСи бесконечности и хаосе в науке - Кантор, Больцман, Тьюринг и Гёдель пытались понять хаос и бесконечность.. с неприятными концовками. Короче говоря если всякая теорема неполна поскольку основана на аксиомах истинность которых невозможно доказать, то получается что быть уверенным во всём невозможно. Мне кажется именно такое мышление должно быть у жёлтого и бирюзового цвета.

Кстати не стоит путать эту цветную психологию с методом "Шести шляп мышления"

О проектировании космического корабля

· 4 мин. чтения

Посмотрел «Andromeda» — очередной космический сериал по принципу Star Trek, Babylon 5, но более близкий к «Firefly» и постарался представить какие будут космические корабли в будующем. Проблема в том что проектирования формы корабля всегда зависит от начинки и назначения, а эти характеристики неизменно приводят к двум вещам — физике и социальной организации.

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

Основные отличия HTML5

· 3 мин. чтения

Недавно вышел HTML5, и хотя я надеялся что де-факто стандартом станет XHTML2, видимо этому не судьба. Следование веб-стандартам впринципе дело самодисциплины — кто-то пишет как умеет, а для кого-то это средство подчеркнуть свой проффесионализм.

Тэги

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

Структурные тэгиТэги содержания
- header — понятное дело, шапка с логотипом, логином, навигацией..- nav — навигация.. как меню, так и «хлебные крошки»- footer — подвал с копирайтами, контактами- article — очевидно влияние блогосферы и rss- section — подраздел документа- aside — боковая панель (видимо с коментариями, самыми популярными статьями, тэгами и тп)- video и audio — как альтернатива flash-плеерам. Врядли заменит флеш из-за проблем с кодеками и отсутствии поддержки уже созданных .flv видео. Мало поддерживается пока браузерами.- progress — полоса завершённости процесса. Полезно при заполнении форм- time — полезно для указания точного времени элемента- details — просто дополнительная информация- datalist — нечто типа автозаполнения, но с прописанными вариантами


Формы

Что особенно радует что работа форм улучшена новыми типами input-элементов.

  • date, datetime, time, month, week
  • email, url
  • range, number
  • color

Их давно пора было вводить в стандарт, потому что число компонентов на js+dom которые делают эту работу растут постоянно (календарики для выбора даты, бегунки), более того - пишутся даже специальные надстройки типа jquery ui. Кроме новых типов, введены интересные параметры, в частности параметр multiple для массовой загрузки файлов. И опять прийдётся распрощаться с uploadify и swfupload. Впрочем не обязательно.

Перетащи в браузер

С давних пор я не понимал почему нельзя было сделать удобное перетаскивание чего-то с рабочего стола внутрь браузера. Точней перетащить то можно, но браузер как правило не поймёт что это за файлы или текст вы в него суёте. HTML5 предполагает распознавание таких случаев с помощью javascript drop-событий, при которых к содержанию получается доступ с помощью e.dataTransfer.getData() метода. Опять же - досвидания java аплеты и google gears.

Данные на стороне клиента

Ещё одной отличительной особенностью стала возможность кэшировать чистые данные на стороне клиента без необходимости постоянно пересылать их с каждым обновлением страницы (т.е. явно не конкурент json-объектам), а объём достигает 5-10 мб (уже не конкурент cookies).

Web storage очень полезная особенно для мобильных устройств. Без HTML5 на это способна лишь Google gears.

А сейчас как быть?

HTML5 всё ещё в режиме черновика, многие браузерные движки лишь пробуют внедрять новые возможности в бета-версиях (особенно заметен Presto). Надо дважды подумать перед тем как перепрыгивать со скачущей лошади на ещё теоретический мотоцикл, особенно если вас заботит совместимость с IE. Для него даже надо прописывать существование тэгов

document.createElement('header'); document.createElement('footer'); document.createElement('section'); document.createElement('aside'); document.createElement('nav'); document.createElement('article');

См. также