Травма плеча перестала беспокоить
«Загадочная травма», о которой я писал меньше месяца назад отпустила. Как только боль прошла, в тот же день смог поднять «разогревочные» 68 кг, около 10 раз. Это, конечно, несколько меньше, чем обычно (обычно —
Теперь пока боюсь сорвать, делаю только один подход в день и смотрю на реакцию, надо увеличивать количество подходов, потом — вес.
Пакетное скругление картинок: оболочка

Пока у меня нет свободного вечера, чтобы заняться «скруглятором», но это не значит, что с проектом ничего не происходит. Читатель с ником oldTV изготовил отличную графическую оболочку «MCShell». Выглядит замечательно.
PHP и UTF-8: третий этап (создание прототипов)
Этот сериал хорош тем, что я пишу его в реальном времени. Единственно, первая фаза — когда я собирал первоначальные данные и обдумывал как мне подступиться к этой задаче, заняла куда больше времени, чем может показаться. Итак, в предыдущей части мы выяснили какие модули используются в нашем проекте и узнали, что в нём
В этой части мы подготовимся к тому, чтобы заменить в проекте все упоминания небезопасных (с точки зрения работы
Как я уже сказал, расширение Reflection работает в PHP с багами, именно поэтому я максимально подробно стараюсь обработать ошибочные ситуации. После запуска программы, можно подсчитать, какое количество функций (у меня их 10) не отобразилось правильно, ничего не поделаешь, придётся их править руками. Файл Я удаляюсь править прототипы руками, а в следующей части уже перейдём к непосредственной замене. P.S. В коде есть странное место — «blah» . ’\$var’, увы, у меня Что же дальше?
<?
function U_makeproto($funcname)
{
$func = new ReflectionFunction($funcname);
$out = ' static public function ' . $funcname . '(';
$counter = 0;
$hasRefOptional = $hasOptional = false;
$names = array();
foreach ($func->getParameters() as $param) {
$name = $param->getName();
if ($name !== null && $name != '...') {
$names[] = $name = '$' . $name;
} else {
$names[] = $name = '$param' . $counter++;
}
if ($param->isPassedByReference()) {
$name = '&' . $name;
}
if ($param->isArray()) {
$name = 'array ' . $name;
}
if ($param->isOptional()) {
$name .= '=';
$name .= $param->isDefaultValueAvailable() ? $param->getDefaultValue() : 'null';
if ($param->isPassedByReference()) {
$hasRefOptional = true;
}
$hasOptional = true;
}
$out .= $name . ', ';
}
$out = rtrim($out, ', ') . ') {';
if ($counter || !$names) {
$out .= "\n // FIXME: Invalid proto ( https://www.php.net//$funcname )\n";
}
$out .= "\n if (self::ON) {".
"\n // TODO: UTF version".
"\n }\n";
if (!$hasRefOptional) {
if ($hasOptional || !$counter && !$names) {
$out .= "\n " . '$params = func_get_args();'.
"\n return call_user_func_array('$funcname', \$params);";
} else {
$hereNames = implode(', ', $names);
$out .= "\n return $funcname($hereNames);";
}
} else {
$reqCounter = $func->getNumberOfRequiredParameters();
$out .= "\n switch (func_num_args()) {".
"\n case $reqCounter:".
"\n " . '$params = func_get_args();'.
"\n return call_user_func_array('$funcname', \$params);";
for ($i = $reqCounter+1, $len = $func->getNumberOfParameters(); $i<=$len; $i++) {
$hereNames = implode(', ', array_slice($names, 0, $i));
$out .= "\n case $i:".
"\n return $funcname($hereNames);";
}
$out .= "\n default:".
"\n trigger_error('Wrong parameter count for $funcname()', E_USER_WARNING);".
"\n return null;";
$out .= "\n }";
}
return $out . "\n }";
}
echo "<?php\nclass UTF\n{\n const ON = false;\n\n";
foreach (file('php://stdin', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $funcname) {
echo U_makeproto($funcname), "\n\n";
}
echo "}";bolk@dev:~/daproject$ sed -re 's/\s+\S+\s+//' tool-func.log | php tool-func-proto.php > utf.php
bolk@dev:~/daproject$ grep -c FIXME utf.php
10
PHP и UTF-8: третий этап (давайте уже что-нибудь заменим)
Ну что ж, всё готово для того, чтобы
Запустить её можно, например, так (напоминаю, что у меня PHP находится в файлах с расширениями php, tpl и inc): Программа напечатает имена файлов, где произошла замена. Своеобразная проверка — запустите её ещё раз, на втором проходе никаких имён файлов выведено быть не должно! Обязательно проследите, чтобы запуск не затронул ваш класс Utf! Итак, мы заменили функции на вызовы класса Utf. Всё работает? У меня не заработало. Причины две — я ошибся в имени одной из функций в классе Utf и появились проблемы с preg_replace_callback. О последней проблеме поподробнее. Пока preg_replace_callback была встроенной функцией всё было замечательно, как только она стала статическим методом класса, проблемы появились. Всё дело в указании в качестве callback метода статического класса. Такие вещи придётся править вручную. Если нет возможности провести тестирование, то можно воспользоваться подсказками IDE — во многих случаях она укажет на такие ситуации, но, в любом случае, лучше все такие места просмотреть глазами. Сегодня ночью я улетаю в Екатеринбург, так что, думаю, это последняя часть на этой неделе. Кстати, остаются ещё строковые функции, вызываемые как callback, внутри eval Что же дальше?
<?
if ($_SERVER['argc'] <> 3) die;
if (realpath($_SERVER['argv'][2]) == realpath(__FILE__)) die;
$file = file_get_contents($_SERVER['argv'][2]);
if (strpos($file, '<?') === false) die;
$funcs = file($_SERVER['argv'][1], FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($funcs as &$func) {
list(,$func) = preg_split('/\s+/s', $func, 2, PREG_SPLIT_NO_EMPTY);
}
$skip = false;
$skipIf = array(T_PAAMAYIM_NEKUDOTAYIM, T_DOUBLE_COLON, T_OBJECT_OPERATOR);
$fixed = false;
ob_start();
foreach (token_get_all($file) as $token) {
if (is_scalar($token)) {
echo $token;
} else {
if (!$skip && $token[0] == T_STRING && in_array(strtolower($token[1]), $funcs)) {
$fixed = print 'Utf::' . $token[1];
} else {
echo $token[1];
}
$skip = in_array($token[0], $skipIf);
}
}
file_put_contents($_SERVER['argv'][2], ob_get_clean());
if ($fixed) {
echo $_SERVER['argv'][2], "\n";
}bolk@dev:~/daproject$ find -type f \( -name '*.php' -or -name '*.tpl' -or -name '*.inc' \) | grep -vF '.svn' |
> xargs -n1 php tool4.php tool-func.log
./php/file.php
./php/dir1/file1.php
./php/dir1/file2.php
./php/dir1/dir2/file3.php
…
Ограничение сна: FAIL
Всё, хватит, заканчиваю свой эксперимент по ограничению количества сна. Мне, чтобы выспаться, нужно около 9…10 часов, я ограничивал время сна до 5…8 часов в день. Появились все признаки усталости: сонливость, рассеянность. Правда, сегодня всё будет ещё хуже — у нас вылет в Екатеринбург в половину первого, а в 8:15 уже подъём.
Не знаю, буду ли читать комментарии. Как получится.