программирование

PHP 5.2.12 → PHP 5.3.1

Поставил новый «Денвер» с PHP 5.3.1 (до этого версия была 5.2.12), сразу же поймал баг — одна из программулин, которую я тихонечко пишу в свободное время стала подвисать вместе с интерпретатором при определённых условиях.

Прокрутив код в голове, я понял, что есть одно место в коде, которое вызывает у меня сомнение — блокировка (flock) файла, убрал обе блокировки, код заработал. Развернул по памяти всю объектную структура проекта, понял, что основной объект, который является точкой доступа к файлам создаётся два раза, у меня забрезжило смутное подозрение. Переделал основную точку входа в обработку файлов на синглетоны. Заработало как часы.

Я не уверен, потому что вполне могу что-то не улавливать, но в 5.3.x изменился сборщик мусора и, похоже, некоторые объекты стали жить (охохо) дольше. Блокировка файла у меня снимается в деструкторе объектной обёртки над файлом, да так, что могла вызвать теоритический dead lock, если объект не сдохнет вовремя. Что ж, завязываться на такие особенности интерпретатора неправильно, но PHP меня совершеннейше расслабляет тем, что для него в природе существует ровно один интерпретатор, да и такие серьёзные изменения в нём происходили давненько.

В общем, не ждите, что миграция при смене версии на 5.3 гарантированно произойдёт без проблем.

Добавлено 15 февраля 04:21: а ещё у меня 5.3 (под Windows) зависает при использовании функции crypt (алгоритм Blowfish, другие не проверял), не всегда зависает, но если входные данные разнообразны, то рано или поздно это происходит.

2 комментария

IPv6

Так как по прогнозам в следующем году, возможно, уже кончатся IPv4, то я уже какое-то время присматриваюсь к IPv6. У меня в загашнике уже есть функции на PHP, которые конвертируют IPv6 в бинарный формат и обратно (по типу ip2long и long2ip) и я иногда вижу как в $_SERVER[’REMOTE_ADDR’] проскакивают длинные адреса.

C IPv6 связано два очень распространнёных заблуждения.

Первое — значение цифры «шесть» в названии протокола. Многие думают, что это длина адреса в байтах. Это не так. Адрес в IPv6 длиной 128 бит (16 байт), например, давайте попробуем запросить IPv6 адрес «Гугла»:

bolk-dev ~ $ host -t aaaa ipv6.google.com
ipv6.google.com         CNAME   ipv6.l.google.com
ipv6.l.google.com       AAAA    2A00:1450:8001:0:0:0:0:69
ipv6.l.google.com       AAAA    2A00:1450:8001:0:0:0:0:67
ipv6.l.google.com       AAAA    2A00:1450:8001:0:0:0:0:93
ipv6.l.google.com       AAAA    2A00:1450:8001:0:0:0:0:63
ipv6.l.google.com       AAAA    2A00:1450:8001:0:0:0:0:68
ipv6.l.google.com       AAAA    2A00:1450:8001:0:0:0:0:6A

Вот типичный адрес этого протокола: «2A00:1450:8001:0:0:0:0:69», в полной форме он будет выглядеть как «2A00:1450:8001:0000:0000:0000:0000:0069», как видите — 16 байт. «Шестёрка» на самом деле относится к версии протокола (v6 — это «version 6»), есть так же IPv5.

Кстати, можно записать рассмотренный адрес ещё короче: «2A00:1450:8001::69». В краткой записи одна (только одна) последовательность нулей в адресе может быть заменена на «::».

Второе заблуждение — что в IPv6 поменялась только длина адреса. Опять же, это не так. Не буду переписывать «Википедию», там можно почитать подробнее, для краткости перечислю основные отличия: оптимизация обработки, автоконфигурация без сохранения состояния, защита данных (основана на IPSec) и мобильность. Другое дело, что с внедрением новых функций есть весьма специфические проблемы, но это другая тема.

Несмотря на то, что адреса IPv4 кончаются, интернет на IPv6 мы увидим ещё не скоро. Тому есть масса причин, от инерции (куча оборудования работает только на v4), до технологических (некоторые вещи в v6 работают иначе).

Придумана масса костылей, чтобы не переходить на новую версию. Например, LSN — широкомасштабный NAT, который пропускает через себя трафик для NAT’ов поменьше или смешная штука PRR, которая позволяет выделять провайдеру не просто фиксированный IPv4-адрес, а адрес и фиксированный набор портов (а другие порты будет использовать другой провайдер).

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

Но готовиться уже надо: в сети есть устройства, которые ходят только через IPv6, я их ооооочень редко, но встречал в логах.

12 комментариев

Как сделать PHP ещё хуже

В Facebook реализовали мою детскую мечту: сделали расширение XHP, которое позволяет писать XML как строку. С тех пор как я увидел E4X (ECMAScript for XML), я страстно хотел увидеть это в PHP.

Потом я подрос и понял, что в PHP это зло:

<?php
// note: includes omitted
if ($_POST['name']) {
  echo <span>Hello, {$_POST['name']}</span>;
} else {
  echo
    <form method="post">
      What is your name?<br />
      <input type="text" name="name" />
      <input type="submit" />
    </form>;
}

С другой стороны я верю в Facebook работают неглупые ребята, что-то они увидели в этой концепции «PHP, язык встраиваемый в HTML» новое и свежее интересное.

По правде сказать, XHP чуть больше, чем упрощённый HEREDOC, он умеет самостоятельно экранировать HTML из суперглобалов или делать это по просьбе программиста, валидировать XML по структуре, описанной прямо на PHP и удалять лишние пробелы.

4 комментария

HipHop PHP

Как я и думал, HipHop for PHP, о котором все говорят, оказался транслятором PHP на компилируемый язык, со всеми вытекающими:

ipHop for PHP isn’t technically a compiler itself. Rather it is a source code transformer. HipHop programmatically transforms your PHP source code into highly optimized C++ and then uses g++ to compile it. HipHop executes the source code in a semantically equivalent manner and sacrifices some rarely used features — such as eval() — in exchange for improved performance.

В данном случае, трансляция идёт в C++. Вытекает из этого то, что вещи, которые трудно компилировать, просто выкинут из языка. В тексте упоминается eval, но наверняка из языка исключили create_function, переменные переменные ($$var, $$$var и так далее), возможно — вызов метода через переменную ($obj->$method), может что-то ещё, сходу трудно сообразить. Различные тонкости тоже вряд ли учтут.

Но даже в таком варианте это неплохо.

Кстати, ничего не ново под луной, семь лет назад какие-то ребята уже делали транслятор из PHP в C++, проект благополучно помер. Я, кстати, думаю, может проект и не помер, может это он и есть и его только-только до ума довели?

4 комментария

bigsync vs. rsync

Bigsync is a tool to incrementally backup a big file to a slow destination (think network media or a cheap NAS). The most common cases for bigsync are disk images or virtual OSes or encrypted volumes.

Bigsync will read the source file in chunks calculating checksums for each one. It will compare them with previously stored values for the destination file and overwrite changed chunks if checksums differ.

Насколько я понял идею, bsync не проходится по удалённому файлу, что ускоряет процесс, если на другом конце медленный накопитель.

2 комментария

PyCamp Киев

Сижу на PyCamp Kyiv, зарегистрировался, всё хорошо. Единственное приключение (кроме того, что прогноз погоды промахнулся на 10 градусов), что в поезде чуть было не почистил зубы спортивным разогревающим кремом.

P.S. Вот и пригодилась SIP-телефония, которую я настраивал ранее. Точнее, стала единственным выходом — позвонил жене через бесплатную WiFi-точку, сказал, что всё в порядке, роуминга у меня нет.

15 комментариев

Альтернативный CTCS

Мой CTCS (45.95КиБ)

Вчера слегка приболел и так как сегодня в дорогу (в Киев, на PyCamp), решил остаться дома, чтобы не заболеть серьёзнее. Пока болел, поковырял протокол обмена между веб-мордой «Yet anOther Dummy CTCS» и его бакэндом. YODCTCS — это такой страшное, как смрад от народного ополчения, огромное (около мегабайта JS) и работающее только под FireFox поделие.

Предназначен YODCTCS для пуска «Enhanced CTorrent» и отображения его данных. «Enhanced CTorrent» — это консольный Torrent-клиент, который умеет работать на урезанном донельзя чём-то линуксообразном моего роутера.

Веб-морда написана на Java и транслированна в JavaScript каким-то чудовищным колдунством, что мне, кстати, помогло — искать в мегабайтном невразумительном JS как происходит авторизация мне не понравилось бы, а подсмотреть это в Java оказалось гораздо проще. Остальной протокол разламывал просто сравнением и анализом.

В итоге накидал небольшую веб-морду, которая пока умеет только отображать информацию (и занимает 88КБ), потом доделаю остальное — это уже много проще. Если кому-то надо, потом могу выложить, когда доделаю.

10 комментариев

30 января: я в Киеве, на PyCamp

PyCamp (5.80КиБ)

30-го января буду в Киеве на «PyCamp Kyiv, программа нравится. Особенно доклады по оптимизации скорости Python, хранилищу Google App Engine, Redis, расширению и встраиваиванию Python, WebSockets в Twisted, интернатиализации в Python и работе из Python c системами оплаты.

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

11 комментариев

Сайт, RSS и браузерный XSLT

Мне последние три года не даёт покоя мысль: вот у нас есть RSS на сайтах, он же — XML, что мешает взять его за основу, наложить на него XLST через браузерный движок и получить оформленный сайт? Зачем делать аж два разные источника?

Листалки вперёд/назад, ссылки на комментарии — всё есть в расширениях, для остального RSS можно расширить самостоятельно. Никто ещё ничего такого не сделал?

27 комментариев

JavaScript: это IE?

Aleko придумал новый (более короткий, чем известный до этого) JavaScript-хак, позволяющий определить является ли браузер Internet Explorer’ом:

if(-[1,]) {
    // код для нормальных браузеров 
} else {
    // код для IE 
}

Подробный принцип действия хорошо описан в блоге у Aleko. Основан хак на старом баге JavaScript в IE, который Microsoft пока не исправила (и неизвестно будет ли исправлять), но с IE9, я считаю, надо быть осторожными — там грядут очень уж глобальные изменения, хак может и не работать.

Оставить комментарий

Pure PHP class LZF decompression (lzf_decompress)

Разбирая архивы на старом компьютере в Казани, наткнулся на свою реализацию PHP-функции lzf_decompress на чистом PHP (распаковка строки, сжатой алгоритмом LZF). Писал в 2006-м году для PEAR, но забросил — не дописал функцию сжатия.

Выкладываю в разделе «Храню», может кому-то пригодится.

4 комментария

Powershell и объектный pipe

Я задумался над тем, чтобы показать как могла бы выглядеть обработка логов на PowerShell. Как я уже говорил, pipe в PowerShell объектный, то есть по нему идёт не монолитный текст, а набор объектов. Вот я и попробую на примере показать что это.

Для начала настроим лог Apache так, чтобы его было удобнее парсить. К примеру, можно ввести символы табуляций — в логе они не встречаются и вполне подходят на роль разделителя:

LogFormat "%h\t%l\t%u\t%t\t\"%r\"\t%>s\t%b" common
CustomLog logs/access.log common

В логе у нас есть: хост клиента, его ident, имя пользователя (если была произведена HTTP-авторизация), дата и время запроса, метод-URL-версия-HTTP (одним полем), код ответа и длина отданного клиенту контента:

127.0.0.1   -   -   [03/Jan/2010:16:35:30 +0300]    "GET /favicon.ico HTTP/1.1" 404 1976
127.0.0.1   -   -   [03/Jan/2010:16:35:32 +0300]    "GET /a.html HTTP/1.1"  200 521
127.0.0.1   -   -   [03/Jan/2010:16:35:33 +0300]    "GET /favicon.ico HTTP/1.1" 404 1976

Предположим, наша задача — разобрать лог, отобрать только те запросы, у которых код ответа 200, отсортировать по размеру контента и вывести в табличном виде название метода, URL и размер контента.

cat access.log | %`
{
    $o = "" | Select-Object host, logname, user, date, url, code, len, method
    $o.host, $o.logname, $o.user, $o.date, $o.url, $o.code, $o.len = $_.Split("`t")

    [datetime]$o.date = $o.date -replace '^.([^:]+):(.+).$', '$1 $2'
    
    "logname", "user", "len" | %{ If ($o.$_ -eq '-') { $o.$_ = $false } }

    $o.method, $o.url = $o.url.SubString(1).Split()[0..1]

    $o
} | ?{ $_.code -eq 200 } | Sort-Object -property len | Format-Table method, url, len

Итак, что здесь происходит. Читаем лог, проходимся по каждой его строке (%{ }), внутри цикла странным хаком с Select-Object создаём объект с заданными полями, разбиваем входную строку по символу табуляция, убираем у поля «date» первый и последний символы (там квадратные скобки) и двоеточие между датой и временем (такой формат понимает PowerShell), сразу преобразуем это значение в тип «datetime», у поле «logname», «user», «len» заменяем значение на False, если там «-» («пусто» в терминах лога Apache), поле «url» разделяем пробелу (там три значения — метод, URL и версия протокола), избавляемся от окаймляющих кавычек и записываем в соответствующие поля.

Последней строкой цикла выводим получившийся объект. До цикла по pipe шли объекты попроще — всего лишь наборы строк («System.String»), теперь идут более интересные объекты («System.Management.Automation.PSCustomObject» с заданными нами полями).

Из этих объектов мы вибираем только те, у которых поле «code» содержит значение 200 («?{}» — это короткий алиас «Where-Object»), сортируем по полю длины контента и выводим, форматируя в таблицу, три поля: метод запрос, URL и длину контента. На экране будет что-то подобное:

method                     url                        len
------                     ---                        ---
GET                        /                          4701
GET                        /                          4701
GET                        /                          4701
GET                        /                          4701
GET                        /a.html                    521
GET                        /a.html                    521

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

26 комментариев

Ещё о PowerShell

Всё-таки PowerShell прекрасен. Вот это вот:

cat user-agents.log | sort -u

одинаково работает и под bash и под PowerShell! Конечно, более «чистый» PowerShell выглядит как на листинге ниже:

Get-Content user-agents.log | Sort-Object -unique

Команда «Get-Content» имеет алиас «cat», «Sort-Object» — «sort», а ключ «unique» сокращается до «u».

Или вот, на bash не совсем похоже, но что проиходит догадаться просто:

ls | where {!$_.length} | %{rm $_}

15 комментариев

CSS hack для Firefox 3.5

В комментариях на «Хабре» попросили придумать CSS-хак для FireFox 3.5. Пожалуйста:

<style type="text/css">
x:-moz-any-link:nth-child(0), body { background: red; } /* FF 3.5+ */
</style>

Проверил в Firefox 2.0.0.19, Firefox 3.0.3 и в Firefox 3.5.5.

10 комментариев

CSS hack для Opera 10.50, 10.xx, не 10.50

«Опера» 10.50 стала поддерживать border-radius и много других интересных вещей, в этой связи встал вопрос — как отличить 10.50 от более ранних версий в CSS?

Например, у меня на сайте скруглённые уголки для «Оперы», начиная с версии 9.50 делаются при помощи SVG, 10.50 вполне могла бы нарисовать их без этого «изыска». Помучался-помучался и придумал несколько CSS-хаков, собственного изобретения.

<style type="text/css">
@media (0) {
    body { background: red; } /* Opera 10.xx, но < 10.50 */
}

@media all and (resolution = 0dpi) {
    body { background: red; } /* Opera < 10.50, минимальной версии не знаю, 9.27 работает */
}

@media all, () {
    body { background: red; } /* Opera 10.xx (включая 10.50) */
}

@media all, {
    body { background: red; } /* Opera 10.50 prealpha */
}
</style>

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

Я не знаю минимальной версии при которой срабатывает хак №2, но подозреваю, что будет работать где-то начиная с 7-й версии.

Все хаки я испытывал на «Операх» 10.50 prealpha, 10.10, 10.01, 9.50 и 9.27. Надеюсь, баг 10.50 не исправят и хак будет работать и дальше (pepelsbey, пожалуйста, молчи!:).

Добавлено 25 декабря 2009 10:38: проснувшись утром, я обнаружил, что умудрился ночью запостить этот текст два раза. Решил удалить один из них и удалил тот, что с комментариями. Простите, это утро :(

16 комментариев

XML в MySQL

Почему-то мало кто слышал, что в MySQL с версии 5.1.5 появился «чудесный» способ нарушать 1NF, при этом работая с частями поля таблицы, как со сложной структурой.

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

Речь идёт о двух функциях — ExctractValue и UpdateXML. Если в поле таблицы хранится XML, то первая функция позволит выбрать данные при помощи XPath, а вторая — (при помощи XPath же) изменить какую-то их часть. Ничего неожиданного — функции могут работать как с полями таблицы, так и со строкой, переменной, результатом функции или любой комбинацией вышеперечисленного.

Примерно так:

SELECT ExtractValue('<a>c</a><b/>', '//a');

SELECT UpdateXML('<a><b>ccc</b><d></d></a>', '/a', '<e>fff</e>');

SELECT * FROM users WHERE ExtractValue(info, '//firstname') == 'Иван' AND ExtractValue(info, '//surname') == 'Сагалаев';

В случае, если XPath не дал результата или в поле оказался не XML, функции вернут NULL (версии MySQL до 5.1.12 содержат баг и частично могут работать даже с not-well-formed XML).

6 комментариев

--5

Это прекрасный образец рака мозга, ящитаю:

<?php
function turn($x)
{
     $y = abs($x);
     if ($y == $x)    
         return "-$y";    
     else        
         return "$y";    
}
?>

You can use this code:

<?php
echo turn(-5) + turn(10);
?>

The output is:

-5

;
Because 5 + -10 = -10

Цитата — из пользовательского комментария к функции abs языка PHP. Для тех, кто далёк от программирования, побуду Капитаном Очевидностью.

Функция меняет знак числа (т. е. было «-5», надо сделать «5», было «2», надо сделать «-2»), для этого она сранивает число с его абсолютным значением и, если оно совпадает (значит число положительное), выводит это число с приделанным символом «-», если нет — то возвращает абсолютное значение.

Правильный ответ:

function turn($x) { return -$x }

не стоит того, чтобы оформлять его в функцию.

Что имел ввиду автор, когда писал «Because 5 + -10 = -10» я не знаю, надо Смирнова спросить, он понимает язык идиотов.

14 комментариев

Opera 10.50 pre-alpha

Opera 10.50 pre-alpha вышла! Кратенько: CSS transformation и многое из CSS3 (border-radius!), HTML5 local storage и open database, Carakan (новый движок JS с прекомпиляцией в машинный код), VEGA — библиотека для векторной графики (в будущем будет использовать аппаратное ускорение, но и сейчас ускорение заметно).

Это далеко не всё, лучше прочитать остальное на сайте «Оперы».

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

24 комментария

← 1 50 51 52 53 54 67 →