php

PHP: библиотека SPL

На сайте Blue Parabola появилась очень хорошая статья, объясняющая чем хороша библиотека SPL (Standard PHP Library). Даже если вы не читаете на английском, всё равно взгляните — там есть примеры кода.

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

«Обычное PHP-приложение»

Читаю Django Book (книга о Python-фреймворке Django):

In contrast, other Web development platforms couple the URL to the program. In typical PHP (https://www.php.net//) applications, for example, the URL of your application is designated by where you place the code on your filesystem.

Может мне кто-то расскажет что такое «обычное PHP-приложение», в котором «URL вашего приложения определён местом,где размещён код в вашей файловой системы»? Даже веб-мастера блогами забытых сайтов знают о существовании mod_rewrite (если говорить про Apache), а интернет уже много лет содержит тысячи (если не сотни тысяч) рецептов по работе с ним, а так же альтернативные способы.

В итоге «обычные» (т. е. «встречающееся чаще других») «PHP-приложение» это, напротив, то, что отвечает принципам ЧПУ (это в России так REST называется, впрочем REST придуман по другому поводу).

P.S. ещё лингвисизм по отношению к PHP из той же книги:

If you’re experienced in another Web development platform, such as PHP or Java, you may be thinking, “Hey, let’s use a query string parameter!”, something like /time/plus?hours=3, in which the hours would be designated by the hours parameter in the URL’s query string (the part after the ?).

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

PHP для Windows Mobile

Немного посмотрел HPH, диалект PHP для Windows Mobile. Я о нём писал пару лет назад, а вот теперь посмотрел, коль скоро у меня устройство с WM6.1.

Что сказать? Это не PHP. Это какой-то язык отдалённо напоминающий PHP. Всюда натыкаешься на странное с точки зрения программиста PHP поведение: то HPH не нравится, что в конце нет «?>», то конструктор класса должен называться в том же регистре, что и сам класс и так далее. Кстати, о классах — ООП от PHP4, что удручает. На сайте сказано, что объекты передаются по ссылке, за это спасибо, массивы почему-то — тоже (в PHP не так).

Если не называть это PHP, то вполне сносный язык, для… для… для чего же? Не знаю, может быть поднять персональные сервисы на нём, ту же Wiki, как пример. Не такая уж плохая идея, жаль только, что ничего готового под него не пойдёт: поддержки MySQL нет (но есть SQLite3!), список функций неполный. Но авторы всё равно молодцы и делают интерпретатор, кажется, для собственного удовольствия.

По сути, список поддерживаемых функций давно таков, что новые можно писать уже на самом HPH и включать как библиотеку, тем более, что реализации некоторых, самых важных, есть в PEAR модуле PHP_Compat.

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

PHP: мануалы читать необходимо

Я изучаю новый язык следующим образом: сначала всегда полностью читаю руководство (вот с «Пайтоном» мне не повезло — в руководстве, которое я выбрал, об itertools было упомянуто вскользь), потом уже пробую что-то писать, изредка показывая куски кода для критики.

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

В свежей статье на «Хабре» — один из подобных велосипедов:

function uptime() {
    $fp=@popen('uptime','r');
    $s=@fgets($fp);
    @fclose($fp);

    @preg_match('#load average: ([0-9\.]+)#', $s, $m);
    return $m[1];
};

Во-первых, в PHP есть функция sys_getloadavg, во-вторых, (если версия PHP ниже 5.1.3) эту информацию можно добыть значительно проще: «(float) substr(strstr(`uptime`, „load average:“), 13)», в третих, можно (на Линуксах) читать /proc/loadavg.

В этой статье вообще масса забавного: в разделе «временные припарки», где index.php заменили для снятия нагрузки, для чего-то использовался print, вместо того, чтобы выдать сообщение голым html, memcached используется как база данных и так далее.

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

PHP: compliler_halt_offset

Малоизвестная возможность PHP, появившаяся с версии 5.1 — аналог секции DOC из Perl. Позволяет создать специальную текстовую секцию в конце файла скрипта, откуда можно будет читать данные, например, туда можно поместить страницу помощи к программе или какие-то метаданные.

Секция начинается вызовом специальной конструкции __halt_compiler(), всё, что дальше этой строки интерпретатор не считывает и не выполняет. Смещение, по которому начинаются данные за конструкцией, доступно через константу __COMPILER_HALT_OFFSET__. Почему нельзя было сделать константу, указывающую на файловый ресурс (по аналогии с STDERR) для меня загадка.

Использовать можно, например, так:

echo file_get_contents(__FILE__, null, null, __COMPILER_HALT_OFFSET__);

// the end of the script execution
__halt_compiler();Hello, world!

На печать программа выведет строку «Hello, world!».

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

Closures в PHP: подробности

Внимательно прочитав документ по замыканиям в PHP, я вынес для себя следующее. Патч работает очень просто и довольно изящно. Замыкания — это не какой-то новый базовый тип, а экземпляр класса Closure. Причём, для того, чтобы объект вёл себя как функция, вводится новый «магический» метод __invoke:

class Example {
  public function __invoke () {
    echo "Hello World!\n";
  }
}
$foo = new Example;
$foo ();

Слово «use», которое появилось в полной версии создания функции — это, конечно, уже полностью новый синтаксис, а не просто косметические изменения. Для тех, кто не прочитал документ, поясняю, что анонимная функция может быть создана, например, так:

function getAdder($x) {
   return function ($y) use ($x) {
     // or: lexical $x;
     return $x + $y;
   }
 }

«Use» вытекает из идеологии PHP, где глобальные переменные не видны сразу внутри функции, а определяются программистом (тоже хаком, кстати). «Use» именно «доставляет» переменную. Причём не из глобального уровня, а с родительского уровня. Что (ура) реализует мою давнюю мечту об изоляции переменных.

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

Замыкания в PHP 5.3.0

В PHP 5.3.0 будут замыкания. Бог ты мой! Не прошло и 15 лет! Надеюсь, это будут действительно анонимные функции, хотя возможность замыкания сама по себе тоже значительное событие.

Напомню как сейчас обстоит дело в PHP с «анонимными» функциями. Сделаны они хаком, поэтому я их взял в кавычки. Каждый раз, когда вы вызываете create_function PHP создаёт функцию (в глобальной зоне видимости, других нет) «\0lambda_N», где N — номер по внутреннему счётчику PHP, а «\0» — символ с кодом ноль, чтобы пользователь не смог самостоятельно создать «анонимную» функцию с произвольным номером, иначе пришлось бы просматривать все фукции с определённым префиксом и искать в нём «дыры» в номерах.

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

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

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

Habr, WTF?

Хабр не устаёт меня удивлять всё снижающимся качеством статей и кода. Ну вот что это:

if(strpos($name, 'fetchRowBy') === 0) {
      array_unshift($arguments, substr($name, 10));
      return call_user_func_array(array($this, 'fetchRowBy'), $arguments);
    }

Ещё бы регулярное выражение использовал, ей-богу!

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

WDDX в PHP и русские символы

У меня ощущение, что никто никогда не пробовал гонять национальные символы через WDDX из PHP в другие языки и обратно. Задача: получить от демона Perl сериализованные данные и десериализовать их. Был выбран формат WDDX, вроде как хорошо описанный стандарт и всё такое. JSON сначала не подошёл, модуль в Perl что-то там дурил, теперь мы это победили. Тем временем в WDDX…

Всё было хорошо, пока в utf8-потоке от Perl не появились символы, которые не влезают в нижнюю половину ASCII. Я перебрал автоматом все кодировки, которые знает iconv, чтобы посмотреть в какой кодировке PHP WDDX умеет есть русские буквы. Ничего ему не понравилось. Потом я догадался сериализовать utf-8 символ через функцию из PHP. Получилось что-то странное. Залез в исходники.

В общем, оказалось, что какое-то время назад кто-то постил баг по этому поводу — UTF-8 в WDDX не передавались вообще. Решили проблему очень просто — взяли кодировку как однобайтовую ISO-8859-1, закодировали в utf-8 и в таком виде выпустили в свет. При получении делается обратное преобразование:

if (!strcmp(atts[i], EL_NAME) && atts[++i] && atts[i][0]) {
    char *decoded;
    int decoded_len;
    decoded = xml_utf8_decode(atts[i], strlen(atts[i]), &decoded_len, "ISO-8859-1");
    stack->varname = decoded;
    break;
}

Соответственно, когда PHP получает из Perl нормальный UTF-8, он его пытается рассмотреть как UTF-8, который надо превратить в ISO-8859-1, на выходе мы получаем вопросы. Чтобы этого не происходило перед wddx_deserialize надо сделать iconv(’iso-8859-1’, ’utf-8’, $string), что решает проблему.

В итоге, мы перешли на JSON. Всем хорошего дня.

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

Кодирование национальных символов в Cyrus IMAP

На днях пришлось столкнуться с кодированием русских символов в папках сервера Cyrus IMAP. Выглядит это примерно так:

folder.BC8EPQQ0BDUEOgRBBDAALQRBBDUEOgRABDUEQg-

Мне повезло, я догадался, что это модифицированная UTF-7, после раскодировки оказалось, что раскодированный текст находится в кодироке UCS-2 big endian. Получилась вот такая функция для перевода всего этого безобразия в UTF-8:

// Cyrus IMAP modified UTF-7 decode
function decodeCyrus($str)
{
    return preg_replace_callback('!&([a-z0-9+/=,]*)-!is', 'decodeCyrusHelper', $str);
}
 
function decodeCyrusHelper($m)
{
   if ($m[1] == '') return '&';
    return iconv('ucs-2be', 'utf-8', str_replace(',', '/', base64_decode($m[1])));
}

Способ использования:

<?php
$decoded = decodeCyrus('folder.BC8EPQQ0BDUEOgRBBDAALQRBBDUEOgRABDUEQg-');

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

PHP cURL и проблема HTTP/HTTPS запросов в nginx и lighttpd

У cURL есть неприятная, в некоторых случаях, особенность: при установке поля CURLOPT_POSTFIELDS, cURL устанавливает в заголовке «Expect: 100-continue». Это поле вызывает проблемы в современных версиях nginx и в некоторых старых (не знаю как сейчас ситуация обстоит) версиях lighttd.

Lighttpd выдаёт код ответа 417, а nginx (по крайней мере на HTTPS запросах) даёт паузу примерно в две секунды. Решение простое: убрать «Expect» из заголовков. В PHP это делается вот так:

curl_set_opt($connection, CURLOPT_HTTPHEADER, array('Expect:'));

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

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

PHP SOAP

Что-то одно PHP SOAP или Perl SOAP::Lite — делала ключница. Простая задача: общаются две программы, клиент на PHP, используется модуль SOAP и сервер на Perl, используется SOAP::Lite.

В режиме XML-RPC Perl отвечает «Неверная версия» (SOAP::Lite поддерживает только 1.1), попытки установить версию со стороны PHP (есть специальные константы SOAP_1_1 и SOAP_1_2) ни к чему не приводят, в режиме document ещё хуже — PHP начинает плеваться совершенно невразумительными сообщениями об ошибках из разряда «моя нога кефир валяться», т. е. все слова знакомые, но что бы это значило… Мануал ничего не проясняет, интернет молчит, примеры из руководства не работают. Шаманскими плясками (например, я нашёл в исходниках параметр soap_action) удалось заставить PHP замолчать, но тут уже возмущается Perl — говорит, что доступ к методу запрещён.

Есть ещё nuSOAP (написанный на чистом PHP), но этот монстр занимает более полуметра. В общем, выкинул всё, взял cURL и SimpleXML. Сам запрос — 40 строк, ещё примерно столько же — разбор ответа через SimpleXML, меньше сотни строк. Так и живём.

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

SPL в PHP 5.3

В PHP 5.3 появился новый функционал в SPL: куча, стек, очередь и связанный список. Официальной документации по ним пока нет, но есть запись в блоге Lorenzo Alberton, на примерах показывающая что это такое и как этим пользоваться.

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

PHP 5.3.0 jumps to Basic

В PHP 5.3.0 ввели оператор «jump»: «Added „jump label“ operator (limited „goto“). (Dmitry, Sara)»

Полюбуйтесь:

$n = 1;

L1:
if ($n > 3) jump L2;
echo "$n: okn";
$n++;

jump L1;

L2:

Здравствуй, непонятный запутанный код! Ребят, сделайте «my» как в Perl, а? Куда ведь более полезный функционал.

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

PHP: простой способ определения кодировки UTF-8

Придумал простой способ определения кодировки UTF-8 в PHP, работает без модулей iconv и multibyte string (mb-функции):

if (preg_match('//u', $string)) { /* у вас UTF-8 */ }

Работать должно, думаю, с версии PHP 4.3.5, в документации сказано: «UTF-8 validity of the pattern is checked since PHP 4.3.5».

21 комментарий

NOWDOC в PHP 5.3.0

В PHP 5.3.0 появилась новая синтаксическая конструкция: «NOWDOC». Сильно похожа на «heredoc», но с тем различием, что в «nowdoc» нет интерполяции переменных:

Следующий пример выведет в точности тот текст, который находится внутри nowdoc:

echo <<<'EOT'
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should not print a capital 'A': x41
EOT;

Второе отличие от heredoc, что nowdoc можно использовать в любом статическом контексте, например так:

class foo {
    public $bar = <<<'EOT'
bar
EOT;
}

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

Чем быстрее всего отрезать строку в кодировке UTF-8

Решил протестировать — чем быстрее всего можно отрезать строку в кодировке UTF-8. В PHP для этой цели (помимо использования извращений, типа SQL-запроса) можно использовать: mb_substr из модуля «Multibyte string function», iconv_substr из модуля iconv, preg_replace в режиме UTF-8 из Perl-Compatible regular expression function и собственную реализацию прохода по UTF-8 строке.

Я взял строку в 700 UTF-8-символов и отрезал от неё 500 разными функциями. Вот что получилось (PHP 5.2.4 без акселераторов):

  • хуже всех справилась реализация на чистом PHP — 0.34 сек
  • получше — iconv_substr. 0.063 сек
  • ещё лучше — mb_substr. 0.0175 сек
  • лучше всех — preg_replace. 0.005 сек
    Если кому интересно, вот моя функция по проходу по строке в кодировке UTF-8:
$len = strlen($text);
    for ($pos = $cutted = 0; $cutted < $cut && $pos < $len; ++$cutted)
    {
            $ch = ord($text[$pos]);

            // multibyte char
            if (0x80 & $ch)
            {
                    for (; $ch & 0x80; ++$pos, $ch <<= 1);
            }
            else
            {
                    $pos++;
            }
    }

Итак, лучший способ отрезать первые $N символов UTF-8 таков:

preg_replace('/^(.{'.$N.'}).*$/uSs', '$1', $text)

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

Программисты на PHP — новые чукчи?

Мне кажется, про программистов на PHP скоро будут складывать анекдоты, как про чукчей. Посмотрите какой чудесный перл из конференции ru_php в ЖЖ:

Пытаюсь сконвертировать .doc файл в .txt , но php не понимает команды без точного объяснения:

$wf=fopen(«myfile.txt»,«w»); $i=0; $f=file(«laplap.doc»); while($i<10) { fwrite($wf,$f[$i]); $i++; } fclose($wf);

может есть другой способ? спасибо

Я очень боюсь поверить, что человек это пишет всерьёз.

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

PHP 5.3.0: Прощай .htaccess

Я уже достаточно давно работаю в конфигурации nginx + FastCGI PHP (без Apache в качестве backend). Это более эффективно — экономит память и система, в целом, более устойчива, производительна, легче в управлении (приходится конфигурировать один сервер, а не два). Единственное, чего нехватало — настройки PHP для определённого хоста (так называемые «Local Value» в phpinfo).

Так вот, в PHP 5.3.0 ситуация изменится:

— Improved php.ini handling: (Jani)
. Added «.htaccess» style user-defined php.ini files support for CGI/FastCGI
. Added support for special [PATH=/opt/httpd/www.example.com/] and [HOST=www.example.com] sections. Directives set in these sections can not be overridden by user-defined ini-files or during runtime.

Этого мне нехватало куда больше, чем пространств имён и «?:», который там тоже появятся. По правде говоря, там есть ещё более значительное для меня изменение — Late Static Binding вкупе с __callstatic и $foo:myFunc(). Или даже «Improved PHP runtime speed and memory usage: Added garbage collector».

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

← 1 7 8 9 10 11 12 →