Posts tagged ‘PHP’

Building PHP 5.3.0 with Tidy Support

I dug around a bit, but most resources I came across on Google were about using the tidy extension for PHP rather than doing a custom build of PHP that included the tidy extension. Once I figured the details out, I thought I’d share. They admittedly seemed somewhat obvious after the fact, though also were not communicated as explicitly as I would have liked anywhere that I could see.

You’ll need a system with a CVS client installed to do this. The system I intended to build on didn’t have one, so I used my laptop, did a CVS checkout, made a gzipped tarball out of the CVS checkout directory, used scp to push it up to the remote server, and decompressed and extracted the archive from there.

  1. Download a PHP 5.3.0 tarball and decompress it.
    $ wget -c http://us2.php.net/get/php-5.3.0.tar.gz/from/a/mirror
    $ tar -zxf php-5.3.0.tar.gz
  2. Follow the anonymous checkout instructions to download tidy. Enter the first command shown here, press Enter without entering anything when prompted for a password, then enter the second command shown here.
    $ cvs -d:pserver:anonymous@tidy.cvs.sourceforge.net:/cvsroot/tidy login
    Logging in to :pserver:anonymous@tidy.cvs.sourceforge.net:2401/cvsroot/tidy
    CVS password:
    $ cvs -z3 -d:pserver:anonymous@tidy.cvs.sourceforge.net:/cvsroot/tidy co -P tidy
  3. When configuring the PHP build and specifying the path for tidy, just point to the root CVS checkout directory.
    $ ls tidy
    CVS  CVSROOT  bin  build  console  experimental  htmldoc  include  lib  src  test
    $ cd php-5.3.0
    $ mkdir build/php_build
    $ ./configure --prefix=`pwd`/build/php_build --with-tidy=../tidy
    $ make
    $ make install

I didn’t run into any problems when following this process. php -m shows the tidy module and it appears to run without issue. Hope this helps someone else.

New SPL Features in PHP 5.3 Webcast Slides

Hope you were able to make it to the CodeWorks 2009 webcast at which I presented on New SPL Features in PHP 5.3! I’ve posted the slides and source code. I hope you enjoyed the webcast and that you’ll register for the excellent selection of upcoming webcasts leading up to CodeWorks 2009.

php|tek 2009 Slides

If you made it out to php|tek and saw my uncon session on web scraping, the slides have been posted. If you’d like to discuss the topic further, feel free to contact me. I love chatting about the subject with others.

Building PHP-GTK with Cairo Support on Ubuntu Jaunty

Elizabeth Smith managed to pique my interest and maintain the patience of Job long enough for me to successfully build PHP 5.3.0RC1 with PHP-GTK including Cairo support on Ubuntu Jaunty. The process was a bit arduous, as Ubuntu apparently has a rather “interesting” automake package, so I thought I’d document it here for anyone who might be interested in repeating the process.

I’m assuming here that you want to use as many available Ubuntu packages as is feasible, aside from maybe PHP itself, in order to minimize the amount of manual compilation necessary. To that end, there are a number packages you will need to install before getting started that do not come with a standard Jaunty installation.

sudo apt-get install subversion cvs libcairo2-dev libgtk2.0-dev

If you plan to build PHP from source, you will also need a few more packages.

sudo apt-get install build-essential autoconf libxml2-dev

Once you’ve got all the dependencies installed, the first step will be to grab a copy of PHP. You’ve got a few options in that regard.

Assuming you do a custom build, here’s how I did it.

./configure --with-gettext --disable-cgi --without-pear \
    --prefix=`pwd`/build/php_build
make
make install

Next, use Subversion to check out a copy of Cairo extension. If you did a custom PHP build, you can just place it on the same directory level as that.

svn co svn://whisky.macvicar.net/php-cairo cairo

At the present moment, the easiest way to install the Cairo extension is manually as a PECL extension. So, compile using the phpize utility in your PHP build.

cd cairo
../php-5.3.0RC1/build/php_build/bin/phpize
./configure --prefix=`pwd`/build/php_build \
    --with-php-config=../php-5.3.0RC1/build/php_build/bin/php-config

It’s at this point that Ubuntu’s “interesting” automake package comes into play. The Makefile generated by phpize will be missing a critical flag -DCOMPILE_DL_CAIRO in its CFLAGS setting value. Open the Makefile in any text editor and find the line that looks like this.

CFLAGS = -g -O2

Append the missing flag to the line so it looks like this, then save it.

CFLAGS = -g -O2 -DCOMPILE_DL_CAIRO

At that point, just continue the compilation process for the Cairo extension as normal.

make
make install

Now use CVS to check out a copy of the PHP-GTK extension. Place it on the same directory level as cairo.

export CVSROOT=:pserver:cvsread@cvs.php.net:/repository
cvs -q checkout -P php-gtk

If the phpize utility is not in your PATH, you’ll have to assign it to an environmental variable as those are the only two ways that the buildconf utility you’re about to use will pick it up.

export PHPIZE=../php-5.3.0RC1/build/php_build/bin/phpize

Execute the buildconf utility to generate the configure script, then execute it.

./buildconf
./configure --prefix=`pwd`/build/php_build \
    --with-php-config=../php-5.3.0RC1/build/php_build/bin/php-config

To have the PHP-GTK extension take advantage of the presence of the Cairo extension, you’ll need to add a flag to the CFLAGS setting in its Makefile. Open that, find the line that looks exactly like the original one modified in the Cairo Makefile, and append the flag -DHAVE_CAIRO to it so it looks like this.

CFLAGS = -g -O2 -DHAVE_CAIRO

At that point, continue the compilation process normally just as with the Cairo extension. Once that’s done, since the extensions were compiled as PECL extensions, you’ll need to enable them in your php.ini file.

If you did a custom build of PHP, just copy the php.ini-development file in the root of the extracted tarball directory to lib/php.ini within your build directory as this is where PHP will look for it by default. If you’re using PHP 5.3.0RC1, there is a syntax error around line 581 of that file. A URL should be commented out using a semicolon but isn’t. Note that the extension_dir setting needs to be set and, if you use a relative path, it must be relative to the current working directory from which PHP is invoked (the root PHP build directory in my case).

extension_dir = "lib/php/extensions/no-debug-non-zts-20090115"
extension=cairo.so
extension=php_gtk2.so

At this point, if you execute your php binary with the -m switch, you should get a list of extensions loaded. cairo and php-gtk should be among them and you shouldn’t see any errors before the extension listing. To take this for a test spin, there’s a particular demo file for PHP-GTK with Cairo support in the php-gtk checkout.

cd php-5.3.0RC1/build/php_build
bin/php php-gtk/demos/examples/cairo_support.php

If this works as expected, you should see a nifty little PHP-powered clock widget on your desktop.

Many thanks to Elizabeth for her help in putting this tutorial together and for all the very cool people working on the PHP-GTK project. You can find them in the #php-gtk channel on the Freenode IRC network. At the present time, some of them are in the process of revamping the PHP-GTK docs. In the meantime, you can check out the GTK docs for more current information.

CDC Update

While using cdc recently after having written about it, I ran into an odd issue. While doing a lint check on a code block, a parse error was occurring on a line that contained a comment in the original source file.

The original code block to do this lint check had the line below to do the heavy lifting.

$response = shell_exec('echo ' . escapeshellarg($code) . ' | php -l');

A var_dump() on $code revealed this, where the comment line was the line on which the parse error was occurring.

string(474) "<?php
...
// Matches any of the standard escape sequences \r, \n, or \t
$matches = (preg_match('/\\r|\\n|\\t/', $string) == 1);
...
?>"

Presumably what was happening was, even though the var_dump() call showed that actual newlines were being interpreted correctly, the \r was also being interpreted rather than taken literally. This caused the comma following it to generate the error I was receiving, namely "Parse error: syntax error, unexpected ‘,’." (If you know why this is, I’m very curious to find out.)

Luckily I was able to tag Derick and he pointed me in the direction of an alternative: proc_open, which even has an example for executing a PHP file that works just as well when modified to perform a lint check on a PHP file. You can see the code changes in the related git commit.

Zend_Form and Zend_Loader_PluginLoader SNAFU

I’ve spoken on this blog before about scaling Zend_Form for larger forms by having it use a central set of plugin loaders for all elements contained within a form, rather than allowing each element to implicitly create its own instances. Another way to accomplish the same goal is to have form elements use the same loaders that the form has already created for itself.

<php

class FastloadingForm extends Zend_Form
{
    public function addElement($element, $name = null, $options = null)
    {
        if (!is_array($options)) {
            $options = array();
        }

        // A plugin loader is implicitly created if default decorators are loaded
        $options['disableLoadDefaultDecorators'] = true;

        // Add the element to the form
        parent::addElement($element, $name, $options);

        // Configure the element to use the form's plugin loaders
        $element = $this->getElement($name);
        foreach ($this->_loaders as $type => $loader) {
            if ($type != 'ELEMENT') {
                $element->setPluginLoader($loader, $type);
            }
        }

        // Now load default decorators for the element
        $element->loadDefaultDecorators();

        return $this;
    }
}

However, this approach can cause an issue if subforms are being used because of a bug in Zend_Loader_PluginLoader.

The bug entails Zend_Loader_PluginLoader allowing multiple instances of the same path to be added per prefix. This becomes an issue because of how Zend_Form handles adding subforms: it automatically calls addPrefixPath() on the subform for each path contained in each of the form’s own plugin loaders. If both the form and subform are using the same plugin loaders, the bug causes the same paths to be added multiple times. When plugins are subsequently loaded, the duplicate paths are all searched individually, creating a bottleneck as more subforms are added.

The issue in the JIRA bug tracker for ZF has patches for both the issue itself and the unit test suite for the Zend_Loader_PluginLoader component. Please view the bug report and vote to ensure that the issue receives attention and is fixed in a release in the near future.

DomQuery Update

I think it’s mostly flown under the radar, but one of my smaller projects is a class called DomQuery that is built on top of DOM and the SPL ArrayObject. The functionality is provides is somewhat similar to jQuery, but it’s different in that it does so programmatically through the API rather than using an expression parser.

This post is mainly to inform anyone who might be interested that I’ve moved the project from its old home at Assembla to a new repository on github. I’ve been enjoying my use of git for version control of other projects and it seems an appropriate place to house DomQuery to allow other people to play with it. I haven’t had time recently to make many updates, but hope that will change in the short term. If you haven’t used DomQuery, why not try it today?

Updating PHP Syntax Highlighting for vim on Ubuntu

This is just a quick post, mostly a "note to self" so I don’t forget how to do this. If you were curious, it was the result of indirect inspiration from these Become a Bash Ninja slides.

If you’re running Ubuntu 8.10 as your desktop OS, have vim installed, and use it for PHP development, you may not be aware that the PHP syntax file that comes bundled with vim is a bit outdated. There’s a fairly simple way to update it, though. In fact, it’s doable with two simple commands from Terminal.

cd /usr/share/vim71;
wget -O - http://www.vim.org/scripts/download_script.php?src_id=8651 | sudo tar -zxv

Webcast Slides

Hard to believe it’s been that long, but two months ago I mentioned the free webcast series sponsored by Adobe and leading up to php|tek 2009.

I’ve posted the slides from my webcast on February 27. If you weren’t able to make it, I gave an introduction to what web scraping is, basic details of the HTTP protocol, available resources for developing web scraping applications, and best practices. I know there are plans to make the audio from the webcast and I will update this post with a link once it becomes available.

If the slides and audio aren’t enough for you, I will in all likelihood be giving an extended version of the presentation that includes both retrieval and analysis as part of the Unconference event at php|tek. Look forward to seeing you there!

Stop Asking, Start Helping

Full disclosure: I’m not on the internals team. The topic of this blog post just happens to push my buttons and I want to be able to point people to a URL rather than answer the question over and over again.

A question that seems to be popping up more and more these days is, "When will PHP 6 be released?" It’s especially annoying because the people that enjoy an exercise in futility ask this question are the same people that simply refuse to take WIR for an answer. Or maybe they just read into the hype generated by trigger-happy publishers who want to preempt a stable release, I don’t really know.

There’s been no alpha or beta release of 6; it hasn’t moved anywhere outside of the CVS repository yet. I would think that would provide some indication that 6 is still a ways off. The feature freeze for 5.3 was originally set for 7/24/08. The first beta release only came out this week. This is all public knowledge and I think a pretty good indicator of the speed at which the landscape is changing.

Given what was originally planned for 6 and how much of it ended up in 5.3, the 6 envisioned today could be worlds away from what actually ends up being released. Take a look at those TODO lists; the amount of work left to be done is anything but trivial. The internals team is not a corporate entity and its members are not compensated for their work in any way. They are volunteers and most work on PHP when they’re off the clock from their day jobs. This limits how quickly progress can be made and how accurate estimated release dates can be. So respect them and their time and stop asking when it’s going to be ready, because they don’t really know much better than you do.

Another thing: PHP is server-side software. It’s not a new web browser coming out where the user may or may not upgrade when you have had time to adapt your application to work with both the old and new versions. No one is forcing you to upgrade the installation you use internally. If you have customers that maintain their own PHP installations, don’t feel pressured to be on the bleeding edge just because they want to be.

Be sensible: don’t lag more than two or so minor point versions behind the current stable offering, don’t immediately upgrade to a brand new stable version, and have automated tests that can be run against release candidates so it’s easier to discern issues that might arise when a stable release does come out and you want to upgrade.

If you really want to be prepared, there are several things you can do. Keep tabs on the accepted and implemented RFCs to see what features are being added and what effect, if any, they have on BC. Search the bug tracker for issues reported and fixed in the branch relevant to you. Don’t limit yourself to testing new versions with your own test suites, but help to write tests for PHP itself to ensure that new versions are as stable as possible. These will make your time much better spent than asking a question that has no definitive answer. And it will keep the rest of our blood pressures all the lower for it.