php
PHP и UTF-8
Все уже
Увы,
Немного праздника в этот однобайтный склеп привносит тот замечательный факт, что
Печальнее всего с двумя вещами.
Вторая проблема заковыристее. В PHP испокон веков аж три модуля для работы с регулярными выражениями — PCRE, Regular Expression (POSIX Extended) и уже знакомый нам Multibyte String. Первый работает
PCRE в таких помощниках не нуждается, потому что сам умеет работать
if (preg_match('/(\w)/iu', 'ПриветN', $m)) {
var_dump($m);
}Выдаст нам… букву «N». Почему? Находить в строке
Matching characters by Unicode property is not fast, because PCRE has to search a structure that contains data for over fifteen thousand characters. That is why the traditional escape sequences such as \d and \w do not use Unicode properties in PCRE
То есть «\d» (цифры), «\w» (буквы) и, кстати, «\b» (граница слова) и «\s» (пробельные символы) работают только с однобайтовыми кодировками. Ужасно? Не то слово! Всё потеряно? К счастью, нет.
Если внимательно читать документацию по PCRE, то найдётся много интересного, в том числе решение и этой проблемы. В одной из версий этой библиотеки появилась экспериментальная конструкция, называемая «глаголом» (VERB), «глаголы» умеют очень многое, но нас интересует специфический «глагол» «UCP», который (ура) занимается тем, что переключает «\w», «\s», «\d» и «\b» в полностью юникодный режим.
То есть такой код даст нам ожидаемый результат:
if (preg_match('/(*UCP)(\w)/iu', 'ПриветN', $m)) {
var_dump($m);
}Победа? Ничего подобного. Этот глагол работает начиная с PCRE 8.10, в самой последней стабильной версии PHP (5.3.3) содержится PCRE 8.02, там этот глагол ещё не поддерживается, я проверял.
Нужная нам версия 8.10 войдёт в PHP 5.3.4. Но,
Но не стоит опускать руки,
Подведём итоги. Для перевода (большого) проекта
Ну а так же не забыть про внешние источники данных — перевести базу
Некоторые программисты стыдятся знания PHP
Просто наблюдение. Заметил, что на собеседовании программисты оправдываются, что знают PHP. «Не знаю как так получилось».
Epic War 4

Подсел
Но медленно наращивать мощность очень уж скучно, сделал патч, который увеличивает количество денег до двух миллионов, применив его
Для того, чтобы применить патч, найдите
Программа написана сразу на трёх языках — PowerShell (для Windows) и PHP с Python (для всех), запускайте любым из этих трёх интерпретаторов:
#!/usr/bin/env python
########################################################
# Written by Evgeny Stepanischev (//bolknote.ru) #
# Epic War 4 money patch (for PowerShell, Python, PHP) #
#<?/*
"""*/
echo str_repeat('#', 55), chr(10);
if ($_SERVER['argc'] > 1) {
$fp = @fopen($_SERVER['argv'][1], 'r+b');
if ($fp) {
$content = fread($fp, 655350);
$content = preg_replace('/(?<=stat_money).{5}/s', pack('H*', '0480C584B4'), $content);
rewind($fp);
fwrite($fp, $content);
echo 'Done.';
} else {
echo 'Invalid file.';
}
fclose($fp);
} else {
echo 'Usage: ', $_SERVER['argv'][0], '<filename>';
}
__halt_compiler();
""" + """ " | out-null
If ($args) {
[char[]] $binary = Get-Content -encoding byte $args[0]
$binary = [string]::join('', $binary) -replace`
'stat_money.{5}', `
"stat_money$([char]0x4)$([char]0x80)$([char]0xC5)$([char]0x84)$([char]0xB4)"
Set-Content $args[0] ([byte[]][char[]] $binary) -encoding byte
"Done."
} Else {
"Usage: " + $MyInvocation.MyCommand.Name +" <filename>"
}
"""
from sys import argv
from os.path import basename
if len(argv) > 1:
name = 'stat_money'
f = open(argv[1], 'r+b')
binary = bytearray(f.read())
try:
index = binary.index(name) + 1 + len(name)
binary[index:index+4] = '\x80\xc5\x84\xb4'
f.seek(0)
f.write(binary)
f.close()
print('Done.')
except:
print('Invalid file.')
else:
print('Usage: %s <filename>' % basename(argv[0]))
# " | out-nullpython patch.ps1 DEF4_SAVE.sol или powershell -Command .\patch.ps1 DEF4_SAVE.sol или php patch.ps1 DEF4_SAVE.sol
Жаль расцветить три языка в одном файле можно только вручную.
PHP для «Андроида»
Появился проект «PHP для „Андроида“», поддержка PHP 5.3 интегрируется в т. н. «Android Scripting Environment».
На PHP для «Андроида» можно писать утилиты командной строки, фоновые процессы
В данной версии PHP поддерживается всё API платформы — есть возможность управлять вибрацией, BT, камерой,
PHP 5.3: что нового?
На сайте «SlideShare» появились (на русском языке) слайды с конференции «PHPconf» «Что нового с PHP 5.3» (на случай, если
Scalar type hinting в PHP 5.4.X или 6.X
Ну и раз уж я решил перед сном пописáть о PHP, то продолжу. Ещё новость из мира PHP — в PHP будет scalar type hinting. Илья Альшанетский добился включения своего патча в код.
Сейчас type hinting в PHP есть, я могу указать явно, что параметр будет объектом определённого класса или массивом:
function test1(MyClass $var) {}
function test2(array $var) {}Скоро можно будет указать, что передаваемый аргумент должен быть скаляром. Жаль только, что появилась только возможность указать определённый тип. Если «object» указать можно, то «scalar», к сожалению, нет. Это странно. Придётся указывать явно:
function test3(string $var) {}Что поможет снизить количество ошибок в отдельных случаях, но как быть, если мне такая жёсткость ни к чему, если я хочу оставить возможность преобразования типов, там где это сделано хорошо (преобразование типа «array» в «string» в PHP сделано бессмысленно, посмотрите на Perl, там это имеет смысл)? Да и как мне указать, что мне всё равно — придёт int или float? Видимо, только явным приведением типа при вызове, а про возврат значения по ссылке, в этом случае, придётся забыть.
В отдельных случаях, хотелось бы, чтобы передав объект в такой типизированный параметр, у объекта дёрнулся метод __toString, а то и __toNumber, если указано, что должен быть передан числовой скаляр.
Надеюсь, не одному мне этого хочется и Илья продолжит работу над патчем.
Добавлено через несколько минут: прочитал комментарии, оказывается идут дискуссии о добавлении ключевых слов «scalar» и «numeric». Кроме того, Илья рассуждает и о преобразованиях типов в рамках type hinting. Ура.
PHP-FPM будет входить в состав PHP 5.3.x
Отличная новость
Если вы не знакомы с этим патчем, то перечислю основные отличиями
А так же возможность задавать заговолок ответа при фатальных ошибках PHP, поддержка возможности nginx 0.5.9+ передавать большие
В общем, исключительно полезный патч. Жаль, что в ветку PHP 5.2.X его
На ветку 5.3.X вряд ли пока переходит много народу. Я попробовал мигрировать пару проектов, неудачно. Один завис
DevelStudio

Это PHP DevelStudio, среда для разработки графических утилит на PHP, сделанная действительно под влиянием Delphi. Визуальное программирование — натаскиваем компонентов, расставляем кнопки, диалоги, окошки, пишем обработчики кликов, нажатий и прочего, компилируем, готов
Пару дней поковырялся, забавно. Никакой мистики, старый как мир принцип — интерпретатор, библиотеки и прочее складывается в один файл. Отсюда и основной недостаток — даже сжатый UPX’ом (среда сама умеет им сжимать) запускаемый файл примера, который
Тем не менее, авторы сделали гигантскую работу (кстати, DevelStudio написана на PHP) и программировать действительно удобно и просто.
На сайте программы есть справка и видеоуроки (кстати, рекомендую посмотреть видеоуроки, основы воспринимаются очень быстро).
Добавлено на следующий день. Тут в комментариях вспомнили Delphi for PHP
Как узнать в каком месте зависла программа на PHP?
PHP 5.3.1
Способ проще некуда: ставим модуль PHP xdebug, прописываем его в php.ini (не забываем, что в PHP 5.3 всегда используется «zend_extension»), а в исследуемой программе указываем:
xdebug_start_trace('/какой/то/путь/имя-лога', XDEBUG_TRACE_APPEND);После зависания идём в указанную папку и смотрим в лог, последняя строка в нём и есть источник зависания.
PHP 5.2.12 → PHP 5.3.1
Поставил новый «Денвер» с PHP 5.3.1 (до этого версия была 5.2.12), сразу же поймал баг — одна из программулин, которую я тихонечко пишу в свободное время стала подвисать вместе с интерпретатором при определённых условиях.
Прокрутив код в голове, я понял, что есть одно место в коде, которое вызывает у меня сомнение — блокировка (flock) файла, убрал обе блокировки, код заработал. Развернул по памяти всю объектную структура проекта, понял, что основной объект, который является точкой доступа к файлам создаётся два раза, у меня забрезжило смутное подозрение. Переделал основную точку входа в обработку файлов на синглетоны. Заработало как часы.
Я не уверен, потому что вполне могу
В общем, не ждите, что миграция при смене версии на 5.3 гарантированно произойдёт без проблем.
Добавлено 15 февраля 04:21: а ещё у меня 5.3 (под Windows) зависает при использовании функции crypt (алгоритм Blowfish, другие не проверял), не всегда зависает, но если входные данные разнообразны, то рано или поздно это происходит.
Как сделать 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 работают неглупые ребята, новое и свежее интересное.
По правде сказать, XHP чуть больше, чем упрощённый HEREDOC, он умеет самостоятельно экранировать HTML из суперглобалов или делать это по просьбе программиста, валидировать XML по структуре, описанной прямо на PHP и удалять лишние пробелы.
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 и так далее), возможно — вызов метода через переменную
Но даже в таком варианте это неплохо.
Кстати, ничего не ново под луной, семь лет назад
Pure PHP class LZF decompression (lzf_decompress)
Разбирая архивы на старом компьютере в Казани, наткнулся на свою реализацию
Выкладываю в разделе «Храню», может
--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. Для тех, кто далёк от программирования, побуду Капитаном Очевидностью.
Функция меняет знак числа (т. е. было
Правильный ответ:
function turn($x) { return -$x }не стоит того, чтобы оформлять его в функцию.
Что имел ввиду автор, когда писал «Because 5 + -10 = -10» я не знаю, надо Смирнова спросить, он понимает язык идиотов.
Input multiple-2
По мотивам предыдущего поста. Чтобы Opera 9+ (а так же 3.5—6.05), Firefox 3.6+, Chrome 3.0.191.0+ и Safari 4.0.1+ позволили выбрать несколько файлов в диалоге загрузки файлов, нужно написать вот такой код:
<form enctype="multipart/form-data" method="post">
<input type="file" min="1" max="9999" name="file[]" multiple="true" />
<input type="submit" name="submit" />
</form>Я указал «file[]» для того, чтобы PHP сразу разложил полученные файлы по массиву $_FILES. К сожалению, запрос от «Оперы» PHP понимает неверно, так как «Опера» шлёт такой запрос в формате multipart/mixed. К счастью, PHP в этом случае положит содержимое файлов одним
Я попробовал, это несложно. Для того, чтобы разобрать
if (isset($_POST['file'], $_POST['file'][0])) {
if ($idx = strpos($_POST['file'][0], "\n")) {
$bound = substr($_POST['file'][0], 2, $idx-2);
$body = "MIME-Version: 1.0\nContent-type: multipart/form-data; boundary={$bound}\n\n".
$_POST['file'][0];
unset($_POST['file'][0]);
$f = &$_FILES['file'];
$f['name'] = $f['type'] = $f['tmp_name'] = $f['error'] = $f['size'];
$msg = mailparse_msg_create();
if (mailparse_msg_parse($msg, $body)) {
$i = 0;
foreach(mailparse_msg_get_structure($msg) as $st) {
$section = mailparse_msg_get_part($msg, $st);
$data = mailparse_msg_get_part_data($section);
if ($data['content-type'] == 'multipart/form-data') {
continue;
}
ob_start();
if (mailparse_msg_extract_part($section, $body)) {
$tmp = tempnam(sys_get_temp_dir(), 'php');
file_put_contents($tmp, ob_get_clean());
$f['name'][$i] = $data['disposition-filename'];
$f['type'][$i] = $data['content-type'];
$f['tmp_name'][$i] = $tmp;
$f['error'][$i] = 0;
$f['size'][$i] = filesize($tmp);
$i++;
} else {
ob_end_clean();
}
}
}
unset($f);
mailparse_msg_free($msg);
}
}
var_dump($_FILES); // результат помещатся в $_FILES, не забудьте удалить временные файлы после обработки!У меня ожидается, что содержимое файлов будет передано как параметр «file[]» (в $_POST это будет $_POST[’file’][0]), но пример несложно переделать на любое другое имя или сделать это имя параметром.
Недокументированный PHP
Решил собрать все недокументированные конструкции и возможности языка PHP, которые я знаю, в одном месте.
Переменные с числовым именем
$var = '123';
$$var = 'test';
var_dump(get_defined_vars());Команда list для строк (работает не во всех версиях PHP)
list($a, $b) = 'HI';
echo $a, $b;Доступ к приватным свойствам через массив
class smth
{
private $prop = 'test';
}
$obj = new smth();
$arr = (array) $obj;
echo $arr["\0smth\0prop"];arr[] в аргументах функции
function add(&$var)
{
$var = 'element';
}
$arr = array();
add($arr[]);
var_dump($arr);Может вы
POSIX-регулярки в PCRE
Для меня это просто открытие
bolk.dev ~ $ php <<PHP
> <?var_dump(preg_match('/[[:alnum:]]\d+/', 'a9'));
> PHP
int(1)В документации упоминания есть, но я никогда внимания на них не обращал.
PHP 5.3: что нового
На «Хабре» хорошая обзорная статья рассказывающая о том, что нового в PHP 5.3.
P.S. почему к любой статье по PHP обязательно появится коментарий с полной пургой, а?
Модуль XScript для PHP
Писал для PHP биндинг в XScript. Си++ я не знаю (и знать не хочу), поэтому писал на Си. Огромое спасибо Antony Dovgal за помощь, без него я бы ещё долго разбирался как писать модули для PHP на Си внутри вражеского Си++, с его же помощью причесал
Что я хочу сказать. Опыт, конечно, полезный, но грустно, что сейчас, как и несколько лет назад (когда я писал первый модуль), практически нет документации о том как писать модули, не говоря уже о хороших, обзорных статьях, где все шаги были бы расписаны и рассказано было бы что и зачем делается.
Чистого времени я потратил половину дня (вместе с хождением по «Яндексу», перепиской, установкой пакетов XScript и прочее — ещё 1,5 дня), но это только потому, что Тони согласился помочь (и у него был опыт написания Си++ модулей на Си на примере биндинга к архиватору RAR, который мы и разбирали).
Думаю, этим и объясняется небольшое количество бинарных модулей на PHP, а так же их низкое качество. Жаль.
«Книга постоянств» Императора Пхп
Около года не читаю жежешный ru_php, а он всё не меняется, оказывается:
Вырисовалась проблема — при var_dump ($класс), var_dump, как последний предатель, выдает все private переменные класса… — так должно быть или это глюк? Не хотелось бы при гипотетической краже скрипта, обработанного Zend Encode что бы отвардампили все пароли и ключи оплат.
Я подумываю о том, чтобы добавить это сообщество в свой