29 марта 2006

Автоматическая открывашка

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

Часто движки начинают играться с адресной строкой: я, например, использую PHP FuseBox, и у него есть точка входа - файл "index.php", а все действия задаются через специальную переменную в хвосте адреса.

Остюда рождается сложность - желая изменить поведение какой-то страницы в проекте, нужно:

  1. Посмотреть на адресную строку
  2. Понять, в какой папке лежат файлы
  3. Найти в этой папке конфигурационный файл
  4. Найти имена нужных файлов
  5. Найти файлы и открыть

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

Поэтому я сел и написал открывашку.


Работает так:

  1. Разработчик втыкает в какую-то страницу и понимает, что её надо править
  2. Нажимает в любом месте страницы ПКМ (правую кнопку мыши)
  3. Выбирает опеределённый пункт в меню
  4. В редакторы открываются нужные файлы

Более того, некоторые темплейты ничего не выводят, а ссылка на них имеется (скажем, дибильная ссылка "очистить кэш"). Если во 2 пункте клацнуть по ссылке, то откроются темплейты той страницы.

Как сделано:

  • в реестре прописан пункт меню, при нажатии которого вызывается определённый файл с JavaScript;
  • в этом файле прописан маппинг адреса в броузере адресу на винте (если открыт сайт developers.org.ua, то искать в "c:\www\projects\developers_org_ua\") и ещё несколько параметров;
  • JavaScript идёт туда, открывает файл настроек (через Microsoft.XMLHTTP), выкусывает что надо и через WScript.Shell запускает требуемые PHP-файлы;
  • тут их подхватывает винда и открывает в редакторе по умолчанию. Просто и удобно.

Качайте и переделывайте под свои движки.

28 марта 2006

Колесо

Как известно, колесо изобрёл Иван Колесо, чьим именем девайс, собсно, и назван :]
Зачем изобретать его снова? Вот например, догадайтесь, что делает этот код:

dt = new Date();
rnd = dt.valueOf().toString().substring(7,20);


Этот кусочек я выудил из кода JavaScript-счётчика... На мой взгляд, таким образом программист пытается получить случайную последовательность. Правда, круто?

27 марта 2006

gzip в windows

Часто в веб-разработке приходится иметь дело с gzip-шифрованием, ввиду того, что оно может использоваться для сжатия http-трафика. В данный момент я разрабатываю систему, которая позволяет принимать xml-файлы через хттп, причём эти файлы могут быть загзипованы. Для этой цели на локальном компе, где идёт разработка, нужно иметь возможность создавать такие файлы - для тестов. Для этого я написал-было скриптец на PHP, который гзиповал указанный файл, а потом в старой инсталляхе программы UUCP нашёл gzip.exe, который просто замечательно ужился с Far'ом. Главное, положить этот файл в папку, видимую через переменную окружения Path, например, "C:\Windows".
Кому надо - качайте (36 Кб).

P.S. Интересно, GZip - это "Google Zip"? :]

26 марта 2006

RSS feed для scriptlance.com

Для тех, кто бывает на scriptlance.com, могу предложить свою новую разработку: RSS-фид проектов. Странно, что они сами его не сделали... Разумется, у меня нет доступа к их базе данных проектов, но мой скрипт заходит на страницу со списком проектов, вырезает все проекты, затем накладывает пользовательский фильтр (например, кол-во бидов или наличие определённого текста) или либо выводит всё в аккуратной табличке, либо возвращает XML.

Чтобы порулить этим, надо сходить на веб-страничку моего фильтра и выставить требуемые параметры, по которым вы хотели бы мониторить проекты (например, те, где число бидов = 0, проект не приватный и встречается слово "PHP"), а затем скопировать ссылку "RSS feed" в свой агрегатор.

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

23 марта 2006

Нелегко стать ранней пташкой

Наконец смог перебороть себя и снова начать вставать в девятом часу, а не после обеда. Чёрная полоса длилась довольно долго. Зато я сделал для себя вывод: после нескольких дней воодушевления и горения мыла в попе начинается спад, и ты возвращаешься к привычному ходу дел. Это, на мой взгляд, происходит от ослабления мотивации. Как я уже говорил, важно изначально понимать, зачем ты всё это затеял. И даже если такое понимание есть, острота этого понимания притупляется, и ты расслабляешься: говоришь себе перед сном, мол, всё, кровь из носу, встану завтра в 6 - и лениво встаешь в час дня! А тут, похоже, авральный метод не работает (сегодня посплю, а завтра встану очень рано в отработку за все просыпания) - лучше меньше да регулярно :]

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

22 марта 2006

Третья передача

Как-то прочитал фразу С. Пояркова, очень успешного художника, что на западе он, как и все там, летает на первой передаче скоростей, а у нас приходится переключаться на 2, а то и 3-ью. Сегодня я понял, что не кто-то там, а я сам езжу на 3 передаче: была у меня супер-идея, но спросить не у кого толком, как её сделать, и в итоге я выбрал самый "лучший" путь: ходил и думал, как бы так всё реализовать быстро, хорошо и безопасно; и заняло у меня это думание полгода... А сегодня глядь - висит моя идея, реализована другим дядей. И клиентов он нашёл, и материал, и разрешения получил. А я не смог, всё боялся ходил. И обижаться не на что - времени был вагон - а всё равно обидно: вроде и не тупой сильно, и руки - не крюки, а вот результат на лицо...

Быстрее надо думать и делать.

20 марта 2006

Составляй своё мнение

Это высказывание надо взять за правило. Дело в том, что фразы "Windows suxx" и "Оутглюк - остой" надёжно оседают в подкорке, и, скажем, когда мне понадобился простой и удобный органайзер на компе, только в последнюю очередь обратил внимание на "недо-" MS Outlook - и был поражён, что всё, что мне надо, здесь есть и достаточно удобно в использовании.

Видно, взрослею...

19 марта 2006

Зафлудить Blogger

Ну вот, пишешь-пишешь, а потом у гугла место для меня кончается...


Так недолго и хакиры начнут флудить... Вчера, говорят, и гугл, и гмейл не были досутпны...

Баллистическая траектория полёта спермы

Прикинул я тут на досуге, какой путь проходит человеческий организм в своём физическом и психическом развитии, даже набросал схемку, получилась дуга, прямо баллистическая такая. Сразу скажу, что моё "исследование" не претендует на научность, это так, мысли вслух. Часть этой траектории я помню и знаю сам, остальное восполнил чтением и распрашиванием. Вот что у меня получилось:

Paint, мышь, начало XXI века
Итак, пройдусь по вехам и поведаю свои мысли:
  • начало координат - это выстрел из пушки, которой, как вы догадываетесь, является пенис. За первые 3 месяца из сперматозоида+яйцеклетки получается эмбрион, за это время развиваясь с такой безумной скоростью, что если бы плод продолжал развиваться так и дальше, то новорождённый весил бы 14 тонн;
  • далее плод развивается немного медленее, но всё равно очень быстро. Его уже можно понемножку тренировать - узнавать папин-мамин голос итд.
  • далее малыш начинает постигать новый мир. Я себе всегда очень живо представляю этот процесс: представьте, если вы вдруг попали в мир, где не три измерения, а больше - вы не знаете, как двигаться, что делать, как есть, как взаимодействовать с миром; лежите, какаете и иногда кричите. Тогда заболивые люди N-го измерения потихоньку приучают вас к телепатии для общения, телекинезу для взаимодействия с предметами и левитации для перемещения. Легко? Что меня поразило в какой-то умной книжке по детской психологии - до определённого возраста малыш не делает разницы между мячиком и своей рукой: для него это всё предметы внешнего мира, т.е. понятие "это - часть меня" отсутствует.
  • с 6 до 17 лет ребёнок учиться в школе. Он уже умеет мыслить, а тут ему объясняют, как мыслить. Здесь закладываются всякие социально-удобные ограничители типа "будь послушным" и "уважай старших", чтобы будущий человек не мешал, а помогал всему коллективу. Ещё он постигает весь материал накопившихся на данный момент знаний: чем дальше, тем больше, поэтому мамы всегда будут жаловаться, что их дети должны учить всё больше и интенсивнее.
  • в университете чистое развитие начинает перемешиваться с работой - добычей денег в реальной жизни, подработками, халтурками.
  • после универа развитие ещё немного, лет пять, очень немного растёт, потом долго идёт по практически прямой - ненужные знания выветриваются (к 40 годам человек забудет имена многих своих одноклассников), новые появляются только ввиду необходимости. Тело начинает дряхлеть, потому что обязательных занятий спортом больше нет, а самому делать лень.
  • ну дальше постепенное дряхление
  • и смерть. Хотел плавно спустить линию к нулю, но потом вспомнил, что люди не всегда становятся полными дибилами, перед тем как умереть.

Наверно, надо сделать какие-то выводы... Например, чем выше поднимаешь планку до 22 лет, тем дольше будешь планировать в верхней части (хотя, кажется, Честерфильд писал про 18-летний предел).

15 марта 2006

Error #2

К вопросу об информативности сообщений об ошибках:

Маленький фикс счётчика

Тут в комментах kpumuk заметил, что счётчик может показывать дизинфу, если скрипт будет неправильно учитывать перенос строки как дополнительный символ. У меня это учитывается при инкременте счётчика, но я поперва забил учитывать это в считывателе счётчика. По идее, при считывании код должен прибавлять 1 к результату, если это не первая строка:

function get_todays()
{
  global $file;
  $cont = file($file);
  $size = sizeof($cont);
  return ($size<2 ? strlen($cont[0]) : strlen($cont[$size-1])+1);
}


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

  return strlen($cont[sizeof($cont)-1])+1;


Что приятно - народу много оказывается :]

Browser Error

Что-то никак не уживутся мой броузер и мой блог: искать одним в другом просто невозможно:

14 марта 2006

Применение моего быстрого счётчика

Стало мне интересно, сколько же народу пользуется моим доморощенным RSS-фидом. "Доморощенным" - потому что самопал: PHP лезет на этот блог и делает из ссылок справа с надписью "Previous Posts" нормальный XML RSS файл.

Для измерений я использовал свой мега-счётчик, который я описывал раньше.

Итак, куда я его воткнул (можете посмотреть сорцы): в исходниках этого блога для картинки с надписью "RSS" (рядом с атомом) я прописал свойство id, равное "RSSImg". После этого, сразу после картинки, вставил JavaScript:

<script src="http://nic-nac-project.de/~a4/blog/rss_count.php"></script>


PHP-скрипт, указанный выше, возвращает JavaScript-код, прописывающий данные по статистике обращений к RSS-фиду в свойство alt многострадальной картинки с надписью "RSS" - можете подвести мышку и убедиться. Надпись на инглише, потому как сразу в кодировке утф8 я писать не умею.

Чудо-PHP-скрипт, который возвращает JavaScript-код, прост:

<?
$file = "data.txt";
function get_size()
{
  global $file;
  return filesize($file);
}
function get_todays()
{
  global $file;
  $cont = file($file);
  return strlen($cont[sizeof($cont)-1]);
}
?>var i=document.getElementById("RSSImg");if(i!=null)i.alt='Total downloads: <?=get_size()?>\nToday: <?=get_todays()?>';


Заметил минус: чтобы данные реально обновились в поле alt, нужно нажать Ctrl+F5. Кто-то кого-то где-то закэшировал втихаря...

12 марта 2006

Встраиваем AJAX в IE

Есть у меня прожка, называется Get File Size: она встраивается в контекстное меню Internet Explorer, и при клике по ссылке на файл она показывает размер файла (всегда полезно знать, сколько этот файл весит ешё ДО скачивания). Мне стало интересно, а можно ли такое сделать без дополнительной проги. Сразу отвечу: немного пое... попариться - и всё получится.

Итак, берём молоток: статья "Как добавить свой пункт в контекстное меню IE", где доходчиво описано, как встроить что-то в контестное меню броузера ИЕ. Я добавил пункт "Размер файла", который появляется только при щелчке на ссылке правой кнопкой мыши. При щелчке по этому пункту меню вызывается прописанный в реестре URL, который возвращает хтмл с куском JavaScript'a, который в свою очередь вызывает РНР-скрипт, который в свою очередь лезет в интернет и по заголовкам требуемой ссылки определяет размер файла и вываливает это вот таким приятным сообщением:

Окно с размером удалённого файлаМожете попробовать всю эту красоту. Для этого надо скачать/запустить маленький reg-файл и перезапустить броузер.

Если кто-то хочет поковырять, как я это сделал, могут скачать всё решение в одном архиве.

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

Кстати, почему я про AJAX упомянул. Надо ж было как-то передавать переменные из JavaScript в PHP, вот я стыбрил соответствующий кусок из AJAX-движка JsHttpRequest.

11 марта 2006

Моё отношение к Януковичу

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

И всё это в итоге отдалённо напоминает мне высказывания Дали из "Дневника одного гения" (с той разницей, что Дали научился извлекать из этого пользу для творчества):

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

Не хочу задеть ничьих чувств-c, но вот такое бывает извращённое восприятие реальности :]

SQL RAND()

Как известно, SQL-функция RAND() возвращает случайное число, большее 0 и меньшее 1. Чтобы получить целое число в определённом диапазоне, можно использовать такой код:

SET @a = 7;

SET @b = 12;

SELECT FLOOR(@a + (RAND() * (@b - @a + 1)))


Хотя потом я подумал, что для моей задачи - а ей являлся т.н. "word verification": показ случайной картинки с написанным в ней текстом для формы регистрации пользователя, типа такой:

Поди распознай FineReader'ом :]
- лучше использовать другой запрос. Ведь картинка должна быть случайной, если пользователь только что открыл страницу с картинкой; если же он уже что-то под ней вписал, то надо показать ту же картинку.

$sql = "SELECT *
FROM `code_images`

".(0 == $id ? "ORDER BY RAND()" : "WHERE `id`=".$id)."
LIMIT 1";

Империя Google

Новый сервис от Гугле - Writely (Web Word Processor) - наводит на размышления двойственного характера... С одной стороны, потихоньку сбываются предсказания предтеч вроде Якоба Нельсона о том, что много видов работы будет перенесено в веб; с этой точки зрения Гугл буквально тащит остальной мир на себе вперёд к светлому будущему, причём бесплатно :]

С другой стороны, Гугл, которой я рассматриваю как потенциального работодателя лично для себя, вызывает смутные ассоциации с компанией Umbrella из Resident Evil: помните, какая это была могущественная и вездесущая организация - даже обручальное кольцо на руке главной героини было маркировано этим логотипом. Мне кажется, что Гугл хочет собрать всю информацию у себя. Пишете вы документы в Writely, ведёте блог на Blogger, читаете почту на Gmail, смотрите статистику своего сайта, собранную их скриптами - всё это может храниться на серверах Гугла. Да, возможно, это такая маленькая паранойя, но не стоит забывать, что
  1. зачем-то они раздают 2 гига (уже 2.7) места под бесплатную почту;
  2. не стали делать регистрацию новых пользователей Gmail: вход по пригласительным. Теперь у них есть дерево отношений всех своих пользователей: кто кого пригласил и кто кем был приглашён;
  3. ребята, содержимое вашего винта тоже в их руках :] Я имею ввиду Desktop Search.
В общем, я сам пока не знаю, куда я клоню, но централизация инфы до добра не доводит, и это её первые звоночки...

P.S. На тему баталий "Конкурент ли Майкрософту Гугл" - теперь "да" не только в поисковой отрасли.

09 марта 2006

Первые приятности от CSV-класса

Как я уже писал, я запостил класс для быстрой загрузки CSV-файлов в БД на phpclasses.org. Бонусы этого шага:
  1. Теперь я всегда имею под рукой вылизанный класс, который нужно просто скачать, а не выдирать из кода своих прошлых проектов.
  2. Как оказалось, класс был скачан уже 373 раза. Вау.
  3. Из-за этих разов я теперь вхожу в топ-10 всего сайта по числу скачиваний...
  4. Три раза мне писали иностранные коллеги, чтобы выразить свою благодарность и а) сделать предложение на улучшение кода, б) попросить помощи в инсталляции (после чего я сдалал косметические изменения для обратной совместимости с PHP3), в) предложить за деньги сделать хитрый апдейт, но мы не договорились в цене, хотя идея интересная :]

В общем, приятно. Рекомендую делиться знанием :]

Web Development Bookmarklets

Прикольные маленькие ссылки на ЯваСкрипте для уёб-девелоперов - их можно здорово добавить в специальную папку в Избранном и при необходимости вызывать оттеда.

08 марта 2006

8осьмое марта

Поздравляю всех прелестниц с их праздником!
Вы наши самые любимые!

07 марта 2006

Якоб Нельсон сделал непристойное предложение

Вот такую "прелесть" "предложил" знаменитый Якоб Нельсон на полях обсуждения "Once Again, MSFT Says It Will Be Better, Just You Wait":
Якоб Нельсон предложил новый анал
разумеется, это результат дурацкого обрезания по N символов, после лицезрения которого я сделал два вывода:
  • совсем не трудно придумывать заголовки для желтой прессы;
  • после такого обрезания нужно ещё раз делать обрезку, но уже до предыдущего пробела, таким образом и символов не много, и смысл не потерялся по пути.

Do you know MySQL as I'm going to do?

Я готовлюсь потихоньку к экзаменам по MySQL, ну и читаю мануал. Попадаются интересные куски:

  • The official way to pronounce “MySQL” is “My Ess Que Ell” (not “my sequel”), but we don't mind if you pronounce it as “my sequel” or in some other localized way.

    [
    Мой вольный перевод: официальное произношение MySQL - "май эс кью эль", но авторы не против, если вы будете называть его по-свойски]

  • The derivation of the name MySQL is not clear. Our base directory and a large number of our libraries and tools have had the prefix “my” for well over 10 years. However, co-founder Monty Widenius's daughter is also named My. Which of the two gave its name to MySQL is still a mystery, even for us.

    [Происхождение названия MySQL до конца не ясно. Огромное число папок, библиотек и инструментов авторов имеют префикс "Mай" ("мой" по-английски), кроме того, дочь одного из со-авторов тоже зовут Май. Что означает префикс "Май" в названии продукта, не помнят даже его создатели.]


  • The name of the MySQL Dolphin (our logo) is “Sakila,” which was chosen by the founders of MySQL AB from a huge list of names suggested by users in our “Name the Dolphin” contest. The winning name was submitted by Ambrose Twebaze, an Open Source software developer from Swaziland, Africa. According to Ambrose, the feminine name Sakila has its roots in SiSwati, the local language of Swaziland. Sakila is also the name of a town in Arusha, Tanzania, near Ambrose's country of origin, Uganda.

    [
    дельфина на логотипе MySQL зовут Сакила. Имя было выбрано по результатам специального конкурса среди пользователей. Это такое женское имя в Свизиленде, а также название города в Танзании.]

  • We also know of users who use MySQL Server with 60,000 tables and about 5,000,000,000 rows.

    [Есть люди, у которых в базе 60 тыщ таблиц и 5 милиардов строк (а я боялся, что MySQL - слабоватая система - прим. перев. :] ) ]


  • To see an example of very advanced sorting, look at the Czech sorting code.

    [Хочешь пример "крутой" сортировки - смотри исходник сортировки для чешского языка]

06 марта 2006

Крутая дампилка dBug

Нашёл недавно хорошую дампилку для РНР. Сделана она неплохо, по аналогии с встроенной функцией дампа из ColdFusion.
Что умеет:

  • выводит разные дампы для разных типов данных: скалярные переменные (строки, числа), объекты, табличку с результатами запроса к БД по передаче переменной с ресурсом, XML. Для каждого типа настроен свой CSS, так что весьма наглядно;
  • дампы по идее не имеют ограничений по вложенности, т.е. свободно дампятся массивы структур, вложенные массивы, итд;
  • если весь дамп либо какая-то его ветка занимают слишком много места, то их можно свернуть/развернуть щелчком мыши (JavaScript разумеется).

Минусы:

  • я использую каркас Fusebox 4, и там все такие "плагины" подключаются в самом начала работы приолжения. Так вот этот самый дампер херит мой валидный хтмл тем, что сразу выводит свои функции и цсс-классы ещё до заветного <html>. Автор упоминает это в комментах, и это чинится разрезанием класса на 3 части: JavaScript, CSS и PHP по отдельности (это не трудно, всё разграничено);
  • плохо дампит строки: если дампить строку, в которой есть хтмл-код, то он будет проинтерпретирован, а также пропадают переносы строк. Поэтому я сделал небольшую правку, после которой этот плагин начинает замечательно работать со скалярными типами, просто любо-дорого теперь работать. Правки такие:
  1. В РНР-классе в функции checkType() находится единственный switch(), вот в дефолт-часть оного надо вставить это
    $this->makeTableHeader("scalar", gettype($var));
    echo "<tr>\n<td align=\"left\">";
    echo (empty($var)) ? "[empty string]" : nl2br(htmlspecialchars($var));
    echo "</td>\n</tr>\n</table>";
    break;
  2. В CSS надо вставить такие объявления (тут можно настроить свою цветовую гамму):
    /* scalar */
    table.dBug_scalar { background-color:#a0a; }
    table.dBug_scalar td { background-color:#FFFFFF; }
    table.dBug_scalar td.dBug_scalarHeader { background-color:#dfd; }
    table.dBug_scalar td.dBug_scalarKey { background-color:#FCF; }

04 марта 2006

Куча пользы от пения в душе

Петь в душе вообще здорово и рекомендуется, а мы поговорим о пении в душе (такие мысли стали набегать ко мне в голову в последнее время :] )

Итак, распевая лихие песни в душе, вы, таким образом:
  • сигнализируете, что душ сейчас занят: не у всех есть шпингалет на двери;
  • тренируете свои вокальные таланты: петь караоке вам, скорее всего, стеснительно из-за страха перед публичным унижением, а в душе шум воды создаёт иллюзию приватности, таким образом вы вольны, например, варьировать высоту от баса до баритонального дисканта;
  • делаете релаксацию: психологи давно заметили, что пение является отличным анти-депрессантом. Поскольку ни с того ни с сего затянуть "Чёрного ворона" посреди офиса немного неудобно, душ - идеальное место; вы выйдете из него ещё более отдохувшим и свежим;
  • тренируете фантазию: зачастую текст исполняемой композиции приобретает колоритные оттенки...
  • опять же, даёте знать своим близким, что с вами всё отлично и вы ещё не захлебнулись.

03 марта 2006

Скриптлансу посвящается...

Одно время я очень увлекался таким хобби: заходил на scriptlance.com, выбирал проекты, которые мало кто готов делать, и делал - хорошая разминка для хвоста.

Но была одна проблема: на этом сайте всегда много проектов, и парит выбирать глазами те, где количество бидов (голосов программеров, готовых сделать проект) мало (2,1 или 0). Тогда я написал небольшой "парсер", который идёт на адрес, где перечислены все биды, берёт хтмл страницы и режет его на аккуратные кусочки, делая из них обычный PHP-массив (это всё работает, пока тамошние ребята не догадаются сменить дизайн, хотя уже около года всё чики-чики). После этого из массива выводятся только нужные строки - либо те, у которых кол-во бидов попадает в заданный диапазон, либо те, в которых есть заданная строка. В общем, удобно, тем паче, что моя выходная страница ещё и гзипуется, чем экономится мой трафик.

В будущем можно добавить дополнительные колонки в выходную таблицу: бюджет проекта, описание и прочее, но для этого придётся немного усложнить логику: нужно сходить на страницу с деталями каждого из проектов-победителей (попавших в выходной массив) и вычленить из её текста нужную инфу, что займёт немало времени. Ну посмотрим, пока такой необходимости нет, потому как интересными являются максимум 10% даже из этих немногих "вырезок".

Сие чудо доступно здесь. Кто хочет, могу поделиться исходником.

02 марта 2006

Быстрый счётчик посещений

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

А почему бы не использовать атрибуты файла? Ну например, размер? За каждое обращение счётчик тупо дописывает 1 символ в файл, а когда нужно получить общую сумму, просто возвращает размер файла. Просто? Да. Быстро? Очень. Я погонял вот эти две функции получения общего количества значений, результат таков: 0.6 секунды занял мой новый вариант против 10.7 секунд традиционного. Обе функции пускались 50 тыщ раз.

function func()
{
  global $file;
  return filesize($file);
}

function func2()
{
  global $file2;
  $fp = fopen($file2, "r");
  $count = (int)fread($fp, 10);
  fclose($fp);
  return $count;
}

Это всё хорошо, скажите вы, а что с записью? Ну тут не такое уж ускорение, и всё же... Вот две функции увеличения на 1 количества обращений:

function func()
{
  global $file;
  $fp = fopen($file, 'a');
  fwrite($fp, "1");
  fclose($fp);
  return 1;
}

function func2()
{
  global $file2;
  $fp = fopen($file2, "r");
  $count = (int)fread($fp, 10);
  fclose($fp);
  $fp = fopen($file2, "w");
  fwrite($fp, $count+1);
  fclose($fp);
  return 1;
}


Эти функцайки я тоже пустил 50 тыщ раз. 14 vs 30 секунд - первый вариант более чем в 2 раза быстрее. Что приятно: оба счётчика вернули в конце одинаковый результат. Что менее приятно: мой способ жрёт больше места - "мой" файл после теста стал весить 50000 байт, а "традиционный" - 5.

Зато! Зато мой способ легко может использоваться для сбора ежедневной статистики помимо общей: перед записью нужно проверить, менялся ли файл сегодня: если да, то просто дописываем единичку в конец, а если нет, то дописываем перенос строки; таким образом, для каждого дня будем иметь строку с числом посещений (в первый день зашло 10 человек, значит, 10 единичек; во второй день - 20 человек, значит, имеем 1 перенос строки + 19 единичек), можно графики строить! И считывание счётчика не будет врать. В традиционном способе тоже можно выдялить по строке на день, но и попариться со считыванием-инкрементом-записью придётся немного больше.

При тесте производительности ни одной функции не пострадало. Для тестов использовался измерительный движок Дмитрия Бородина.

01 марта 2006

Быстрая загрузка Excel-файла в БэДэ

Ну и наконец обсудим третий популярный формат хранения данных,
часто требующих переноса в базу данных - Excel-формат (xls-файл).

Когда встал такой вопрос, я немного погуглил и нашёл парсер,
написанный на PHP, который я немного переработал под свои нескромные нужды.

Алгоритм остаётся тот же:

  • преобразовать Excel-файл в массив;
  • закатать весь массив в CSV-файл;
  • использовать быструю загрузку CSV в БД.

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

Где брал парсер - не помню, поэтому просто перевыкладываю его у себя, а быстрая загрузка CSV в БД никуда пока не убежала из позапрошлого поста.

Быстрая загрузка XML-файла в бабу занных

Итак, продолжаем серию заметок об убыстрённых методах загрузки файлов разных типов в базу данных.

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

Да, возможно есть более современные способы переноса данных из XML-файла в базу данных, однако я поперва воспользовался таким алгоритмом:
  • преобразовать XML в массив;
  • сформировать из массива серию INSERT-запросов;
  • выполнить эти запросы.

Сразу скажу, что этот метод очень медленный во-первых и требует много памяти во-вторых. По умолчанию PHP владеет аж 8 мегабайтами оперативки, и попытки оперативно работать с массивами, преобразованными из 40-мегабайтных прайс-листов в XML-формате - жалкое зрелище.

Другой замедляющий момент - обилие запросов к базе. Даже если веб-сервер и БД стоят на одной машине - просто капец. Как решение, можно использовать группировку INSERT-запросов: один большой INSERT вместо множества маленьких. Но эта же проблема была и при загрузке CSV-файла...

Поэтому совершенно случайно :] мне пришла в голову идея попробовать такой алгоритм:

  • преобразовать XML в массив;
  • закатать весь массив в CSV-файл;
  • использовать быструю загрузку CSV в БД.

И о чудо! Всё летает и свистит! Все счастливы и довольны, хотя PHP по-прежнему тягает безумные по размерам массивы :] Можно попробовать ускорить этот процесс ещё более тем, что закатывать в файл набежавший блок данных, скажем, каждые N строк или при пересечении массивом предела в объёме.

В комментах на php.net есть масса вариантов функций, преобразующих XML в массив, советую брать оттеда, потому что процесс этот не простой.

Закатать весь массив в CSV-файл вполне можно через fputcsv(), только не забудьте проапдейтить PHP до пятой версии либо пишите свой вариант (который будет несомненно медленнее в виду своей интерпретируемости).

Ну а о использовании быстрой загрузки CSV в БД читай предыдущий гет пост.

И всех с началом Весны!