Disabling “Back” Behavior of Backspace in Browser

February 3, 2009 by mcrusch

Here’s a quick little one…
If you, like me, find it annoying that the backspace button takes you back one page in history in your web browser (like clicking the Back button), then you might be glad to know you can disable it (in Firefox–sorry, haven’t looked into other browsers)

I found out how to do this here:

http://ubuntu.wordpress.com/2006/12/21/fix-firefox-backspace-to-take-you-to-the-previous-page/

Where the author is actually doing the opposite, enabling the feature.

To disable:

  1. Go to about:config
  2. Filter for backspace
  3. Change the value for browser.backspace_action to 1 to disable back button behavior

Generate PHP5 Interfaces from Excel file

January 1, 2009 by mcrusch

After doing initial design work on some piece of code, I often find that the first task is to write a set of interfaces that I’ve designed by writing things out on paper. When there are a lot of interfaces with a lot of methods, I find it tedious to type them all in, taking into account formatting and phpdoc-style documentation. Although a good text editor helps, I wanted to go one step further.

So, I designed an Excel spreadsheet that would allow me to type in the interface information in a tabular form and would then generate the PHP code for me. This does not use any script, but you have to do two text replaces afterwards that can be a little difficult depending on your text editor (UltraEdit, not free, makes it a snap).

Caveats

I’ll admit up-front that this is quite a hack job and probably not useful in most circumstances, but if you have a lot of interfaces (and trivial classes) to create at once, this could save you some time. And, it’s an example of fun with formulas in Excel. I didn’t use any script–all formulas.

In particular, it doesn’t handle descriptions for return values (only types) or visibility modifiers for methods (that’s one reason why it works best for interfaces). These could be added without too much work with some more formula hacking.

How It Works

I’ve uploaded a sample here. This is a simple set of interfaces for graphs and directed graphs. There’s also a class. You’ll want to start with this file. When you’re ready to do your own, you can delete rows 3-43, and clear A2:E2 to begin your work (you want to preserve the formulas in row 2 starting at column F).

You start each interface or class with a “Type” line, specifying “class” or “interface”, the name, the one-line description, and the class/interface that it extends, if any. Then, if you have further description of the class/interface, you can include Comment lines. The Description column uses a fixed-width font and is sized to indicate the amount of room you have for these comments. If you go too long (assumes an 80-character line limit), the field turns red.

Next, specify your methods. For each method, start with a “Method” line, specifying the return type (omit for void), method name, and one-line description. Then, you may include Comment lines. Finally, add Parameter lines for each parameter, specifying the type, name, description, and default value. The Description line will turn red if you go too long, and it adjusts for indentation and the like.

Make sure your file ends with a footer line that simply has the word Type in the first column. Then, fill all columns after the first thick vertical border (the column “Final” and those to the right) down from row 2 to the row just above the footer row. Copy and paste the contents of the Final column to a text editor, and you are almost there.

In the text editor:

  1. Remove all blank lines
  2. Replace all instances of “\n” followed by an end-of-line with just the end-of-line (using the end-of-line of your choice)
  3. Replace all instances of “\n” with the end-of-line of your choice

If you are using Excel in Windows and UltraEdit and want Unix end-of-lines, you would replace:

  1. ^p^p with ^p until there are no more
  2. \n^p with ^n
  3. \n with ^n

Possible Improvements

One might be able to cut out the text editor step by replacing instances of \n in the formulas with the proper Excel formula to actual put the newline character in. I think the formula is CHR?

One could add a separate “Return” line type that would allow for a return description. Then, you could use the “Type” column for the method to be the visiblity modifier instead of the return type.

The Infamous 3221225477 and Autoloading

November 25, 2008 by mcrusch

Parent: child process exited with status 3221225477 — Restarting.

It wasn’t until I ran into it myself that I realized the fear that this error message strikes in the hearts of many.  It shows up in the apache error logs and is accompanied by an apache process dying.  The user sees a blank screen or an error message, and the developer is left scratching is head and wading through page after page of google hits with no solutions…

It sounds like there may be a number of causes, but I found one: using call_user_func_array() to call static methods of not-yet-loaded classes in PHP.  In my case, the code looked something like this:

/**
 * Delegates all function calls to static methods of $this->class.
 *
 * @param string $name static method name
 * @param array $arguments all arguments
 * @return mixed
 */
public function __call($name, $arguments)
{
    return call_user_func_array(array($this->class, $name), $arguments);
}

In my case, $this->class held the string “DatasetPeer” which was the name of a class.  The class was typically loaded using autoloading, and at the point in the code where this failed it had not yet been referenced, and so had not been loaded.  Apparently (at least in my version of php) call_user_func_array() called in this manner does not autoload the class, but rather crashes the apache process. I would assume that call_user_func() works similarly.

The solution was to load the class, and the easist way I could think of to do that without having to actually invoke a method on the class was to use reflection:

/**
 * Delegates all function calls to static methods of $this->class.
 *
 * @param string $name static method name
 * @param array $arguments all arguments
 * @return mixed
 */
public function __call($name, $arguments)
{
    // Force auto-loading of the class.  If is has not loaded yet, then
    // call_user_func_array will cause a nasty crash
    $rc = new ReflectionClass($this->class);

    return call_user_func_array(array($this->class, $name), $arguments);
}

I will probably now use the ReflectionClass object $rc to invoke the method, foregoing call_user_func_array() completely, but I note that this one change was sufficient to solve the problem.

DAG Ontologies in Relational Databases

July 29, 2008 by mcrusch

I am designing a piece of software that will make extensive use of ontologies.  For my purpose, an ontology is a list of “terms”, each with a name and description, where the terms can be related to each other in a number of ways and the relations form a directed acyclic graph (DAG).

BTW, I suggest that before you go on, you read this article.  The author is trying to do something very similar to what I’m doing, and his article is excellent, with code examples and diagrams and everything.  I have devised a solution that differs in some ways.

Example

See the article.

Problem

The problem is that we often want to be able to quickly pull out all terms that are related, directly or indirectly, to another term.  This requires quickly finding all terms that have a path to a particular term.

Furthermore, we want the database design to be DBMS-independent, so it cannot use special features particular to certain DBMSes.  In particular, I’m trying to avoid stored procedures.

Inspiration

Not wanting to re-invent the wheel, I investigated various database packages that use ontologies, including GO and BioSQL

I also did some reading and came across this very helpful article (already mentioned multiple times)

Solution

I decided that each ontology would be a completely self-contained unit.  Hence, a term in one ontology could not be related to a term in another ontology.

First of all, the schema:

Schema

Four tables: ontology, term, term_rel, and term_path.

  • ontology: contains a name and description of the ontology
  • term: contains a name and description of the term, a foreign key to the ontology, and flags indicating that the term is the root term or is obsolete
  • term_rel: defines direct relationships between terms (edges on the DAG):
    • id: unique id
    • subj_term_id: foreign key to the subject term (a.k.a. the descendant, on the non-arrow side of the edge)
    • obj_term_id: foreign key to the object term (a.k.a. the ancestor, on the arrow side of the edge)
    • pred_term_id: a term from the “predicate” ontology indicating how the terms are related (e.g. “is a”, “has a”)
    • ontology_id: redundant foreign key to the ontology to which subj and obj belong; makes queries easier
  • term_path: defines all paths
    • (contains all the same fields as term_rel), plus
    • term_path_id: nullable reference to another term_path (explained below)
    • term_rel_id: reference to a term_rel (explained below)
    • distance: number of edges on the DAG in this path

Logic

Term path has to be maintained when term_rels are added and deleted.  This logic was inspired by the aforementioned very helpful article, though I have made significant changes (that make it simpler and less DB-dependant, though it does require outside logic).

Each term_path is identified by an integer primary key.  However, it is also defined by another term_path (call it the subpath) and a term_rel.  The subpath is that path which contains all edges of the main path, except for the last one.  So, if the path is A -> B -> C -> D, then the subpath is A -> B -> C.  The term_rel is the last edge, in this case, C -> D.  Paths that contain only a single edge will have no subpath (term_path_id is null).  All paths have a term_rel.

When adding a new relationship from A -> B, do the following:

  1. Add a path from A -> B with distance 1.  It will have no term_path_id, and term_rel_id will reference the term_rel just added.
  2. For every existing path, P, to A (with subj_term_id = A’s id), add a new path P* from P’s subject to B.
  3. Take all paths added in #1 and #2 and put them in a stack
  4. If the stack is empty, then you are done.
  5. Pop the top path (Pt) off the stack
  6. Find all edges (term_rels) that can extend Pt.  These would have term_rel.subj_term_id = term_path (Pt).obj_term_id.  If there are none, go back to step 4.
  7. For each of those edges, create a new path, extending Pt, just as you did for P in step #2, and push the new edge onto the stack.
  8. Go to step 4.

That’s additions.  Now for deletions.  Deletions are trivially easy if your DBMS supports cascading deletes.  Simply set the term_path.term_path_id and term_path.term_rel_id foreign keys to cascade deletes.  Now, when a term_rel is deleted, all paths that include it wil be as well.

If your DBMS does not suppor this, then you have two options:

  1. Use a database abstraction layer that will emulate it.
  2. Implement the logic yourself

I leave #2 as an exercise to the reader :)

Implementation

This actually works, by the way.  I’m using it.

I am doing this in a Symfony project, using the Propel for ORM.  So, I am able to use cascading deletes, as Propel will do the work for me if the underlying DBMS will not.

The code is available upon request.  I will be happy to provide it for you.  Since it’s all done within the Propel framework, it may be hard to follow for those not familiar with Propel.  Your best bet is to hit me up via my work web page.

PHP Debugging in Eclipse (with Symfony, too)

June 10, 2008 by mcrusch

Much has been written about debugging PHP in eclipse, yet for all the blogs and tutorials I have had no end of problems. My setup was complicated by the fact that I was trying to debug command-line scripts using the symfony framework. Only the last part was really symfony-dependent, however. Here is what finally worked for me.

My setup:

  • Windows XP
  • PHP 5.2.6
  • Eclipse 3.3
  • Symfony 1.0.11

Debugger Choice: Zend

First I needed to decide on a debugger. In the end I found that Xdebug caused nasty PHP crashes at the end of some runs. I’m not sure why I had this problem, but I wound up using Zend.

Eclipse, servers, and clients

Eclipse 3.3 comes with debug clients for Xdebug and Zend debugger built-in. If you look in Window -> Preferences, PHP -> Debug -> Installed Debuggers, you should see them there. This does not mean, however, that you have everything you need ready to go.

PHP must also be configured (in php.ini) with debugging support. This involves loading an extension for Zend debugger or Xdebug. Eclipse comes with a version PHP configured with Zend debugger. On my system it was here:

C:\Program Files\eclipse\plugins\org.zend.php.debug.debugger.win32.x86_5.2.10.v20070905\resources\php5\php.exe

The key to this is that in that same directory is a php.ini that loads ZendDebugger.dll (also in the same directory).

Furthermore, Eclipse seems to require that your PHP have debugging support built in, even when you Run (not Debug).

Other considerations

The Zend debugger slows down PHP significantly. I didn’t want to have it enabled by default. So, I created a separate ini file that includes the Zend debugger and told Eclipse to use it.

My code used MySQL, so I needed at least that extension loaded in PHP.

The Steps

  1. Install everything (Apache, PHP, Eclipse, Symfony, etc.)
  2. Find ZendDebugger.dll in your eclipse plugins dir (see path above for a hint)
  3. Copy it to your PHP extensions dir (a subdir of your main PHP dir)
  4. Create a copy of php.ini called php-debug.ini
  5. In php-debug.ini add the following (substituting in the proper path to PHP):
  6. zend_extension_ts=”C:/Program Files/PHP/ext/ZendDebugger.dll”

  7. In Eclipse, go to Window -> Preferences, PHP -> PHP Executables
  8. Click Add
  9. Specify a name that you will recognize
  10. In Executable path, find your standard php.exe (not part of Eclipse)
  11. In config path, specify php-debug.ini
  12. Choose Zend Debugger
  13. Add
  14. Now, to run or debug you will need to choose the PHP Executable that you created.

Symfony

To make it work with symfony, create the following file, named bootstrap.php, in your project root dir:

<?php
// From symfony.bat
ini_set(’html_errors’, ‘0′);
ini_set(’open_basedir’, ”);
// ‘Calls’ the php script symfony
require(’./symfony’);
?>

Then, to run a symfony command, for example symfony test-unit Foo, you would do the following:

  1. Go to Run -> Open Run Dialog (or Open Debug Dialog)
  2. Make sure PHP Debugger and PHP Executable are set correctly.
  3. Specify bootstrap.php as the php file to run
  4. In the php script arguments, put the symfony parameters (e.g. test-unit Foo)

For regular symfony commands you would still do it straight from the command-line, or using Symfoclipse. This is useful for unit tests and the like where it would invoke your code.

Problems

Sometimes, PHP executables that are created are not made available in the Run or Debug dialogs. I don’t know why, but creating new PHP executables (without removing the old ones first) seems to work around the problem.