I recently gave a presentation on Continuous Integration at the AmsterdamPHP meetup. At my current work we also use the PHP Template. You can find the slides here.
Contains some background, our experiences and some tips. Most important tip is to get fast hardware.

Chef - System Integration. Handles conforming all of my servers to a specific version/environment and also deploys "release" tagged builds that pass testing to live servers

Currently the stack is set up to:

Issues and project goals managed in Jira, with API making them available to developers to easily browse in PHPStorm

Developer commits and pushes changes to their branch to the build server

Build server monitors git and automatically starts processing a build whenever a new push is detected.

Clean pull, codeception then processes the projects Unit tests, followed by functional, then connects to Selenium Server and runs through all the acceptance testing.

Builds automatically appear with related issues in the rest of the Atlassian suite (i.e jira), and the commiting developer is immediately notified on build success/failure over google talk.

On failure of acceptance tests, selenium is set to automatically screenshot the failing tests and include them as assets for the developer to review.

Chef automatically converges all of the production servers every 6 hours. Once a build has been reviewed and tagged as release Chef automatically picks up the build and deploys it to the production servers. Custom scripts + Doctrine handle migration on each server from that point on.

It depends on the project. For smaller open-source projects I've been using Travis and their GitHub hook. They say they have private plans on the way as well.

For larger projects which actually have complex artifacts and continuous deployment requirements, Jenkins is a great platform. I've tried Cruise Control with PHPUnderControl as well, but at the time they were difficult to get running and I didn't care for the work flow. These tools might have improved since then, though.

In fact, you can record/write tests in Selenium IDE and if you use the "Convert to" or whatever menu item it is in IDE, you can pick PHP*, and it will generate (kludgy, but functional) PHPUnit_Selenium code for the same test.

*(You used to be able to do this out of the box; but since the PHP API for Selenium was not made by Selenium, they took it out a while back. You can get the functionality back with a plugin if you look for it.)

edit: FTR, the PHP API for Selenium -- like all other APIs for Selenium -- are actually Selenium RC (aka Selenium Grid) based. So, you need to have a Selenium RC server running or instantiated for the resulting code to work. Previously I ran a modest VM farm of Selenium servers for this purpose.

also, for the daring, the actual language APIs are all just wrappers for the under-the-hood Selenium RC HTTP-based protocol, for which there is hard-to-find documentation.

I could see using it still. Depends on how rigorous your process is. Odds are good though as a single developer you are pretty fast and loose. I.E you check in bad code just so you don't lose the days' work, etc., in which case you'd constantly be getting "YOU BROKE THE BUILD" emails and cursing the stupid CI server. :)

I was always curious about this. Short of automating testing when you push a change.. what else can CI do in PHP? I understand in compiled languages you can actually... well.. build it, but what is the point in PHP?

Yep, we all develop locally. Our system is a post-commit hook, so the code actually gets into the Github repo before the tests get run (whether the tests pass or not). We have a Jenkins bot in our IRC channel that immediately reports the status of all builds to us. So if the build breaks we all know right away.

One reason it's not a "your push is delayed until tests pass" system is so that it can be deployed to the test server and have the tests run. The build and the tests can take 5-15 minutes, depending on the project, so having the push being "conditional" seems like it would be really tricky.

The build step is fetching all the third-party code the project uses from external sources - in our case, Drupal, contributed Drupal modules, JavaScript libraries (fetched by Drush Make), and for the test suite, a bunch of Symfony2 components and Behat dependencies (fetched by Composer).