emacs

Remote Debugging in Emacs

Dylan was helping me out with a nasty Drupal problem when I finally decided to seek out a PHP debugger. He told me about Xdebug. It uses a debugging protocol called DBGp. Because of this you can attach a debugger to a suitably enlightened process, for example a Drupal server. Now I loves me some debugger. I've never been a fan of sprinkling print statements around, scrying through logs, realizing you didn't print the right information and rerunning everything, and finally forgetting to remove those same debugging prints. But I've never been able to attach a debugger to a real live running web process. With this, maybe me and Drupal won't fight like two cats in a back alley.

Unfortunately, Dylan runs the debugger with Eclipse. I resigned myself to my fate and began downloading the ONE HUNDRED MEG Eclipse installer. I'm an Emacs user (in an office full of vi folks). Emacs is pretty damn fat, but it has nothing on Eclipse. (Yo editor so fat, it makes Emacs look thin!) While that oozed onto my computer, I did a little searching around for an Emacs widget for Xdebug. Of course there's one: GEBEN.

GEBEN installs like any other Emacs library. Xdebug like any other PHP extension. Once installed you have to add some bits to your php.ini

zend_extension="/usr/local/lib/php5/modules/xdebug.so"
 
xdebug.remote_enable=On
xdebug.remote_autostart=On

Loads the xdebug extension, turns on the debugging and makes it always look for a server. Without xdebug.remote_autostart on you have to shim XDEBUG_SESSION_START=1 into your GETs and POSTs. With that in place, kick over your web server. You can read up on all the config options.

XDebug works by trying to connect to a debugging server on port 9000. GEBEN provides that server. Fire up Emacs and run M-x geben. GEBEN is now listening. The next PHP you run should show up in Emacs.

   <?php
 
=> print("Hello world\n");
 
   ?>

Congratulations, you are now debugging PHP. What now? Now, type M-x geben-mode-help to get the debugger commands. They're pretty primitive. Step over, step into, step out, continue running, set breakpoints. One of the nice commands is v geben-display-context which will show you all the variables in scope, and it will update as you step through the program. e geben-eval-expression is handy to run random bits of code.

Now you can debug any PHP process, any time, in any environment. You can debug running web sites, no more having to mock up a web environment just to get a debugger. Because it's a debugging protocol it can conceivably be bolted onto anything. Activestate has added it to Perl via Komodo. Don't like Emacs? There's a small truckload of clients. This makes me happy.

(Note, there's NO security on this thing. If you're going to use it outside localhost run it through an ssh tunnel.)

Eclipse? I figured all this out before it was even done downloading.

Tagged as: dbgp, emacs, geben, oh god don't make me use Eclipse, xdebug

Merging two Drupal instances into a single database

I recently had to transfer some tables from a Drupal site that had been developed in it's own database, into an existing Drupal database. In order to do this, the MySQL dump needed to be edited to add table prefixes, lest the existing Drupal install be wiped out.

Editing this by hand was out of the question, but thanks to the emacs replace-regexp command, I was able to change the entire dump file in a matter of minutes.

To initiate the command, one hits ALT-x and types in replace-regexp. First, enter the pattern to find. To add a prefix to all the DROP TABLE commands:

DROP TABLE IF EXISTS `\(.*\)`

The \(.*\) is the regular expression that tells emacs to match everything inside those parenthesis.

After entering the search, one is prompted to enter the replacement pattern. To add a prefix, for example myprefix to the DROP TABLE commands I used this pattern:

DROP TABLE IF EXISTS `myprefix_\1`

The \1 pulls in whatever was matched in the first set of parenthesis in our search pattern.

I repeated a similar search and replace for the other commands that reference a table in a typical Drupal database:

 CREATE TABLE `\(.*\)`
 CREATE TABLE `myprefix_\1`
 
 LOCK TABLES `\(.*\)`
 LOCK TABLES `myprefix_\1`
 
 ALTER TABLE `\(.*\)`
 ALTER TABLE `myprefix_\1`
 
 INSERT INTO `\(.*\)`
 INSERT INTO `myprefix_\1`

After that I was able to import this dump file into the existing Drupal database (without wiping out the other installation) and continue development as a multi-site sharing a single database.

Tagged as: Drupal, emacs

Syndicate content