[]RSS

About Archives Artwork Comic Contact Philosophy Projects Tags

Php++, and why Rails isn’t for me

Comments Off

April 1st, 2007 in Php

Here’s an idea that I haven’t had a chance to hack at yet: Php++. Take the base language, clean it up using a simple pre-processor, and spit out regular Php. Think of it like Rails, but inverted. Instead of creating a few mini-languages to replace HTML/CSS/Javascript/SQL generation, find a way to string these languages together in a cleaner way. An exoskeleton versus an endoskeleton.

I don’t have anything against Ruby (it’s a cleaner, crisper Perl), and it’s not like I don’t appreciate what Rails tries to do. What gets in my way is that Rails introduces new domain-specific-languages that aren’t as good as what they replace.

What Rail’s DSLs intend to do is great: automating database migrations, schema/code synchronization, managing project skeletons, Javascript integration, and more. The problem is that these DSLs are specific to Rails, and represent non-portable knowledge. You have to relearn how to do JOINs, UNIONs, and POSTS. Not that the Rails way isn’t clever, but it’s a layer between a set of languages that are already really good. My question is, what’s wrong with writing SQL, HTML, and JS? I think the answer is that their intersection is messy, and you duplicate your application’s domain knowledge between each of the specific languages.

So Rails helps to enforce the One Definition Rule, but it does so by inventing new mini-languages. Rails does it well, which is forgivable, but I’m thinking that the same end is possible while still embracing SQL, HTML, and Javascript. Anything you know about these languages should still apply, so anything you learn using the tool would be useful elsewhere.

Enter Php++

Add a small number of keywords similar to the QT C++ extensions that make it easy to generate sensible code from your SQL/HTML/JS. For example:

class student {
    public get address() = "SELECT * FROM Students WHERE id = '$sid'";
    public set address($street, $number, $etc) = "INSERT ...";

    // The display portions rely on get/set
    public edit show_edit_form() default(); 
    public edit show_inline_edit() default(ajax);
    public view display_full_address() default(); 

}

The extensions would also take care of the mess around escaping SQL, and could switch between various SQL backends without much trouble (mysql_*, Pear::DB, etc.). And the Php++ processor would do the right thing, and would generate real, readable Php.

Now my only problem is finding the time to hack at it.

Php database interfaces

[Comment]

October 29th, 2006 in Php. Weblog

bambooLet’s face it, the default Php MySQL interfaces are pretty weak. A few of the shortcomings:

  • No prepared statements
  • In lacking prepared statements, requires the use of escaping functions for any SQL containing POST/GET variables
  • Read functions overwrite duplicate column names in returned data when reading rows from joined tables
  • Has a very verbose API, with many long parameter lists
  • Is not class based, so everyone bakes their own abstraction

Compared to the Perl DBI, for example, Php’s mysql_ functions are absolutely horrid. Luckily there are many great alternatives, as I discovered this weekend with a bit of research.

The PDO

Php’s PDO functions are similar to Perl’s DBI, sporting a reasonable API and supporting a number of databases.

Php’s improved MySQL functions

Php has an improved set of MySQL functions (the mysqli_ functions) that add both a simple class wrapper and a parallel, improved API. The new API supports prepared statements, and has a cleaner interface layout. The new APIs still munge the fetch_assoc functions (they still overwrite), but are otherwise a great improvement.

The improved MySQL functions are only available in Php 5, and I’ve read warnings that it’s a pain to run both the msql_ and mysqli_ functions from one Php installation.

Pear’s MDB2

The MDB2 package from the Pear repository replaces their previous DB package, and provides a similar interface to Perl’s DBI. I find the interface a bit bigger than my needs present, but it is a very complete and mature abstraction.

In the real world

All of these libraries are available on most platforms and from most reasonable webhosts (like Dreamhost).

My first choice so far is the improved mysqli_ class/functions, then the built-in PDO library. I’ll spend a few weeks with them and then post a follow-up.

Php, foot, mouth

[Comment]

September 27th, 2006 in Php. Weblog

I found an interesting behaviour tonight. The language allows you to call a member function as if it were a static function, something you can accidentally hide when calling callback functions:

// Oops, this calls a non-static member statically as sm::blocks
preg_replace_callback(
       "/(?<=\n\n|\r\n\r\n|\r\r|\A)(.*?)(?:\n\n|\r\n\r\n|\r\r|\Z)/sm",
       array("sm", "blocks"),
       $text);
}

What I really meant was:

array($this, "blocks")

When you call a static function in a Php class, it has the side-effect of wiping out the class context. Without the class context, you can’t make other calls to class members. In my case above, Php allowed me to break the class context (calling a non-static as static) without warning, which caused a perfectly legitimate class member function fail:

function text($m) {
    $this->inlines($m);
}

Which fails with: Using $this when not in object context.

Instead, Php should warn: Calling a non-static member as static. This might not be what you meant to do.