Alexey Zakhlestin's Blog

Programming for Mac and Web

Pake: PHP Project Build System

Permalink

Sometimes, there are pieces of software, which are unfairly forgotten. Let’s talk about one these.

Often, while working on software projects, one finds, that there are repetitive tasks, which would be much easier to deal with, if automated. In the C/Unix world, this task is often solved by Make), Java programmers prefer Apache Ant), Ruby programmers use Rake). The fact, which is not commonly known, is, that PHP also has such instrument, and it is called Pake. It was originally created by authors of Symfony framework. Unfortunately, they never wrote any documentation, which killed adoption rates.

To start automating something, you need to create Pakefile.php in the root-directory of your project, define some tasks inside and run them with “pake taskname” from command-line. The good news is, that tasks are defined in PHP language and syntax is quite simple:

<?php

pake_desc(‘FOO task’);
pake_task(‘foo’, ‘bar’);

pake_desc(‘BAR task’);
pake_task(‘bar’, ‘baz’);

pake_desc(‘BAZ task’);
pake_task(‘baz’);

pake_alias(‘default’, ‘foo’); // marking foo as default task

function run_foo($task, $args)
{
echo “foo\n”;
}

function run_bar($task, $args)
{
echo “bar\n”;
}

function run_baz($task, $args)
{
echo “baz\n”;
}

I defined 3 rules, gave them descriptions and specified dependencies. Additionally, I specifed default rule. Now, we can play with this a bit. Create file with this contents, save it somewhere, and point your terminal to the same directory.

`

pake baz bar foo `

What happened? Pake looks for “default” task in the pakefile. We defined “foo” as default. Pake found out, that foo depends on bar, and bar depends on baz. So, Pake runs “baz”, then “bar” and then, finally, “foo”. That is as simple as it can be.

Pake has builtin support for basic file-operations (pake_mkdirs(), pake_copy(), pake_rename(), pake_remove()), which are the powered-up versions of php’s filesystem-functions, templating (pake_replace_tokens()), directory-mirroring (pake_mirror()) and runners for creating PEAR-packages, Phing-commands and Simpletest.

Pake project wasn’t maintained for a while, so I decided to give it a spin (as there is a good chance, that I will be able to use it for my current projects). I imported it’s version history to GitHub. You can find latest version here: http://github.com/indeyets/pake

My plan is to add some generally usable helpers to current branch, write some documentation and then to start work on Pake2 which would use all new features of PHP-5.3 (namespaces, closures, rich SPL).

Git-project is a source for creating pear-package. To build one use the following command:

`

php bin/pake.php release 1.1.0a1 `

it will create “pake-1.1.0a1.tgz” file in the same directory. You can install it with the following command:

`

pear install -f pake-1.1.0a1.tgz `

If you want to grab a prebuild pear-package of pake, you can do it here

Work With TwitterData in PHP

Permalink

I recently created a small library for working with twitterdata in PHP. Sources are available from GitHub: php-twitterdata

Here’s the description from Twitter Data site:

Twitter Data is a simple, open, semi-structured format for embedding machine-readable, yet human-friendly, data in Twitter messages. This data can then be transmitted, received, and interpreted in real time by powerful new kinds of applications built on the Twitter platform. Here is an example Twitter Data message:

I love the #twitterdata proposal! $vote +1

The part with the dollar sign, $vote +1, is a piece of data embedded using the Twitter Data format.

To use php-twitterdata library, download it into the sub-direcory in your project’s directory (or any other place you like) and init the autoloader:

<?php
require ‘php-twitterdata/autoload.php’;
?>

PHP API provided by php-twitterdata has 2 layers. On lower level, there are 3 classes: TwitterData_Message, TwitterData_Frame and TwitterData_Tuple which correspond to parts of data-enabled twitter-message. Message can consist of several Frames, Frame can consist of several Tuples and a “subject”. Objects of each of these classes can be created programmatically and combined in hierarchy. Each of them has “magic” __toString() method, so, to export them as a valid twitter-message, you just need to put objects in string context. Something like this:

<?php
$tuple = new TwitterData_Tuple(‘foo’, ‘bar’);
$frame = new TwitterData_Frame(‘Hello, world!’, array($tuple));
echo $frame;
?>

and the result will be: Hello, world! $foo bar

If you need to parse Twitter Data messages you should use TwitterData_Parser class. It is a SAX-style parser, with DOM-style export. If all you need is a hierarchy of objects, use it like this:

<?php
$parser = new TwitterData_Parser($text_from_twitter);
$message = $parser->export(); // $message is object of TwitterData_Message class
?>

Otherwise, you can specify another handler-class as a second parameter of constructor. Such class has to implement TwitterData_Parser_CallbackInterface.

Does it all sound too complex? No problem!

php-twitterdata library also includes high-level interface, which consists of 2 simple functions: TwitterData::array_to_TwitterData() and TwitterData::TwitterData_to_array(). First one converts associative array into the string, which can be inserted into twitter-message, and second one takes message-string received from twitter and returns associative array parsed out of tuples from the first frame of message (If you need to get all possible data from message, you will still need to use low-level API).

Example of high-level API:

<?php
TwitterData::TwitterData_to_array(‘Hello, world! $foo bar’);
// array(‘foo’ => ‘bar’);

$message = ‘Hello, world! ‘.TwitterData::array_to_TwitterData(array(‘foo’ => ‘bar’));
// Hello, world! $foo bar
?>

Library has unit-tests, which cover all examples provided on Twitter Data site both on Introduction page and on Examples page and is licensed under MIT-style license.

Chronograph at MacZOT. $12.95 Only!

Permalink

Chronograph

Just wanted to let you know, that our time-tracking app Chronograph is available for $12.95 from MacZOT today. That’s 50% of our usual price. Please note, that it is a time-limited offer: you can buy Chronograph at this price only on June 30, 2009. Additionally, MacZOT will be giving several free licenses to their subscribers — take your chance.

By the way, we recently released Chronograph 1.3 which has one of the most requested features: iCal integration. Just click one button in preferences and watch how all your tracked time-data appears in iCal-calendar. Add a simple AppleScript and you can integrate Chronograph data into your workflow. With each release Chronograph becomes more mature, but, still, is an extremely easy to use piece of software.

If you were waiting for some special occasion to buy Chronograph license — this is exactly such occasion. Don’t miss it. It is HERE.

relevant links:

[Milk Farm Software, ltd.](http://www.milkfarmsoft.com/)
[Chronograph's home-page](http://www.milkfarmsoft.com/chronograph.php)
[Download Chronograph 1.3](http://s3.amazonaws.com/milkfarmsoft/Chronograph%201.3.0.dmg)

PHP-FPM Is BSD-licensed Now

Permalink

Some seriously good news here. It took several years of waiting, but, it finally happened. PHP-FPM project is officially BSD-licensed now, which means, that it has good chances to become a part of official PHP distribution.

PHP-FPM is “deciphered” as “PHP FastCGI Process Manager” and is a patch for php to greatly improve FastCGI SAPI usage in production. It adds a bunch of additional features to php’s fastcgi such as: easy php-process daemonization (with ability to specify uid/gid/chroot/log-file), safe php-processes restart (without losing requests), custom error-handling and accelerated file-upload support (requires additional support from web-server).

There’s not much documentation in english, currently, but, again, there is a good chance that it will be added really soon.

Chronograph

Permalink

It’s been a while since I posted anything here. Life was keeping me busy :)

Today, I am glad to announce the release of my new product: Chronograph. Chronograph is one of those tools, that I wrote for myself, because everything else out there felt like nonsense. Either too complicated, or too ugly. Anyway, Chronograph — is a time tracking application. Basically, there are Projects, which consist of Tasks. You can select task and start the timer. Then you do the job, stop the timer and move on to the next task. Chronograph keeps stats on the time spent and you can create reports (basic, for now) based on them.

I am trying to make application, which would feel “right”, and looks like the direction is correct.

Chronograph screenshot

If you have any comments, ideas regarding Chronograph let me know in comments, or using email: info@milkfarmsoft.com

Thanks :)

C, Headers

Permalink

The concept of headers in C was necessary at its time, but these days it just makes compilation of complex program in complex environment several times more complex. Whenever you have several package-roots (I have /usr, /usr/local, /sw, /opt/local, /opt/some_pkg1, /opt/some_pkg2 at the same time), which have different versions of the same libraries, you need to separately check resolution order of libraries and header-files.

Sometimes it feels completely counter-intuitive and you just end up manually hiding some files.

Common end-user solution is just sticking to the package-root provided by distribution (usually “/usr”), but that is not an option for developer, who needs to test different combinations of bleeding-edge apps.

How do you manage this stuff?

Example. I need to build php6 (installation prefix /opt/php6) with:

  • iconv from /sw (whle there is other iconv in /usr)

  • libxml from /usr (while there is other libxml in /sw)

  • icu from /sw/local (while there are pieces of other icu’s in /sw and /usr)

In reality, there are more libs involved, and complexity arises, when these different libs are needed by the same components of php. I start thinking, that I should create some special package-root and just symlink every needed library in it. And just give it as the only package-root to php. Seems like a complex task, while considering all dependencies.

In my ideal world, there would be no name-resolution at all, compiler would just require exact position of library (which would be represented by the single file)