2010-05-24

Дружим XAMPP с ImageMagick

Необходимо мне вдруг стало отлаживать мой хобби-проект http://spaceismine.org/ на Windows-машине, который в production-версии работает на Fedora. А на linux-системах нет проблем с установкой расширений, подобных imagick. Для Fedora, к примеру, достаточно установить расширение через yum и перезапустить apache:
yum install php-pecl-imagick
service httpd restart
В Windows же не все так просто. Менеджер пакетов PECL под окнами очень капризен и сразу работать не хочет. Для него нужны танцы с бубном, описанные в мануалах. Я решил пойти слегка другим путем: установить imagick, вручную прикрутив его к php.
В целом, ImageMagick - открытое бесплатное программное обеспечение, которое служит для обработки графической информации. А imagick - это php-wrapper (обвязка) для библиотек ImageMagick. Файлы, которые мне понадобились:

http://www.imagemagick.org/download/binaries/ImageMagick-6.6.2-0-Q16-windows-dll.exe
http://valokuva.org/builds/ext/vc9/ts/imagick/2010-05-24_1007/php_imagick_ts.dll

Был выбран wrapper thread-safe, так как версия php, которая была установлена в XAMPP была так же thread-safe. В итоге, я установил ImageMagick и скопировал скачанный php_imagick_ts.dll в место:
C:\xampp\php\ext\php_imagick_ts.dll
И тут мне попался огромный подводный камень. Проблемы возникли с тем, что php в XAMPP был скомпилирован с помощью Visual Studio 6.0, а модуль php_imagick_ts.dll - в Visual Studio 9.0 и из-за разных подписей они вместе напрочь отказались работать. А модуль imagick, скомпилированный в VC6 найти так и не удалось.
Я взглянул на версию php, она была 5.3.1, а на production'е у меня 5.3.2. Не очень страшно, но захотелось все же обновить и php. Итак моя, казалось бы безобидная идея, превращается в эпопею. :)
Что ж, я люблю все новое и решил выкачать thread-safe php, собранный в VC9, чтобы он был совместим с imagick. Долго искать не пришлось.

http://windows.php.net/downloads/releases/php-5.3.2-Win32-VC9-x86.zip

Итак, переименовав на случай отката C:\xampp\php в C:\xampp\php5vc6, я распаковал содержимое свежего php в чистую папку C:\xampp\php. Затем скопировал модуль imagick в C:\xampp\php\ext\php_imagick_ts.dll
Понадобилось скопировать C:\xampp\php\php.ini-development в C:\xampp\php\php.ini, так как последнего не было на месте. Также пришлось немного подкорректировать этот дефолтный php.ini, патч (unified diff) примерно такой:
--- C:\xampp\php\php.ini Mon May 24 16:09:59 2010 UTC
+++ C:\xampp\php\php.ini-development Wed Mar 3 13:40:56 2010 UTC
@@ -784,7 +784,7 @@
 ;include_path = ".:/php/includes"
 ;
 ; Windows: "\path1;\path2"
-include_path = ".;C:\xampp\php\PEAR"
+;include_path = ".;c:\php\includes"
 ;
 ; PHP's default setting for include_path is ".;/path/to/php/pear"
 ; http://php.net/include-path
@@ -806,7 +806,7 @@
 ; http://php.net/extension-dir
 ; extension_dir = "./"
 ; On windows:
-extension_dir = "ext"
+; extension_dir = "ext"
 
 ; Whether or not to enable the dl() function.  The dl() function does NOT work
 ; properly in multithreaded servers, such as IIS or Zeus, and is automatically
@@ -876,7 +876,7 @@
 
 ; Maximum allowed size for uploaded files.
 ; http://php.net/upload-max-filesize
-upload_max_filesize = 10M
+upload_max_filesize = 2M
 
 ; Maximum number of files that can be uploaded via a single request
 max_file_uploads = 20
@@ -948,7 +948,7 @@
 ;extension=php_curl.dll
 ;extension=php_dba.dll
 ;extension=php_exif.dll
-extension=php_fileinfo.dll
+;extension=php_fileinfo.dll
 ;extension=php_gd2.dll
 ;extension=php_gettext.dll
 ;extension=php_gmp.dll
@@ -956,17 +956,17 @@
 ;extension=php_imap.dll
 ;extension=php_interbase.dll
 ;extension=php_ldap.dll
-extension=php_mbstring.dll
+;extension=php_mbstring.dll
 ;extension=php_ming.dll
 ;extension=php_mssql.dll
-extension=php_mysql.dll
+;extension=php_mysql.dll
 ;extension=php_mysqli.dll
 ;extension=php_oci8.dll      ; Use with Oracle 10gR2 Instant Client
 ;extension=php_oci8_11g.dll  ; Use with Oracle 11g Instant Client
 ;extension=php_openssl.dll
 ;extension=php_pdo_firebird.dll
 ;extension=php_pdo_mssql.dll
-extension=php_pdo_mysql.dll
+;extension=php_pdo_mysql.dll
 ;extension=php_pdo_oci.dll
 ;extension=php_pdo_odbc.dll
 ;extension=php_pdo_pgsql.dll
@@ -985,7 +985,6 @@
 ;extension=php_xmlrpc.dll
 ;extension=php_xsl.dll
 ;extension=php_zip.dll
-extension=php_imagick_ts.dll
 
 ;;;;;;;;;;;;;;;;;;;
 ; Module Settings ;

Таким образом мне удалось подружить XAMPP и imagick, и обновить PHP в XAMPP до версии 5.3.2. Надеюсь, я смог спасти хотя бы кого-нибудь от граблей. :)

2010-05-23

Autocomplete в Zend Studio

Не всегда Zend Studio может определить тип переменной из контекста. Например, когда тип переменной становится ясен только во время интерпретации кода. Случается очень часто, на самом деле, например, когда мы пытаемся пробежаться по rowset'у в цикле foreach.
$usersRowset = $usersTable->fetchAll();
foreach ($usersRowset as $userRow) {
    $user->... // автокомплит в этом случае не сработает
}
И в таких случаях такая очень важная штука как автокомплит не работает. Класс может содержать огромное количество методов, названия которых вы вряд ли помните все наизусть.
Zend Studio большинство своих автокомплитов распарсивает из комментариев PHPDoc. Поэтому, чтобы заработал автокомплит, необходимо добавить комментарий PHPDoc
$usersRowset = $usersTable->fetchAll();
/* @var $userRow Zend_Db_Table_Row */
foreach ($usersRowset as $userRow) {
    $user->... // автокомплит работает :)
}