Thursday, June 12, 2008

Proposal accepted for ZendCon08

My proposal "Digging Through the Guts of Enterprise PHP: A Case Study," which looks at PHP usage, techniques, and features as used at my day job at IBM, got accepted for the Zend/PHP Conference and EXPO 2008!

An exploration of the features of PHP used in the Ajax-driven user interface of IBM Rational Build Forge, with a focus on inheritance, interfaces, and Iterators. This talk will demonstrate how we built its user interface on a solid foundation of PHP.

I submitted it shortly after the call for papers opened up and this year, I got in. I've never spoken at a conference before, but it'll at least make for an interesting (and hopefully even successful) experience.

Labels: , , ,

Tuesday, February 12, 2008

Vienna + PHP (source code) + iUI

Source posted! BSD License. From the README:

You'll need to do a few things to get this working:

1. Move the extracted vienna directory to /Library/WebServer/Documents
2. Download iUI (http://code.google.com/p/iui/) and put the main iui directory into the extracted vienna/ directory
3a. Setup a cron job to copy ~/Library/Application Support/Vienna/messages.db to the extracted vienna/ directory
3b. For the adventurous: mv ~/Library/Application Support/Vienna/messages.db to the extracted vienna/ directory and sym-link it back to ~/Library/Application Support/Vienna/
4. Make sure to enable web sharing
5. Go to (your computer's name).local/vienna

Labels: , , , , , , , ,

Sunday, February 10, 2008

Vienna + PHP + iUI

So, sick of not having the ability to feed my XML addiction when away from my machine, I took an hour this morning and hacked together a quick'n'dirty iPhone/iPod Touch UI for my Vienna database using MacOS 10.5's standard PHP (with SQLite PDO), iui, and my Vienna database (stored in sqlite3). I gave it read-only access to the database, partly so I wouldn't have to worry about screwing it up, partly because I didn't feel like bothering just yet. I just need to add a "Mark Read" button to make an Ajax call.

I'll ask the Vienna devs if they'd like a copy of the source to toy with and generally improve, since I blatantly stole reused Joe Hewitt's design and markup for iui-enabled Digg.

Note: though my uploaded demo does pull from a copied Vienna database, it does not pull from a live one, since I wrote the code to run on a desktop MacOS 10.5 machine and not a Linux server. I then just made a bookmark on my iPod Touch to my iMac on the local network.

Labels: , , , , , , , ,

Thursday, November 08, 2007

Announcing Universe Conflict!

Posted to the new project space on SourceForge.net:

An implementation of Space War!, one of the first digital computer games, created in 1961 on the PDP-1 computer, as recreated using the <canvas> HTML5 element and Ajax. It uses the Frozen Toolkit for the client-server communication and currently renders all images and animation using canvas and JavaScript objects.

I had always intended to release this as an open source project, but then realized that I didn't really have the full time to dedicate to it. It also currently exists more as sample code and an interactive demo than anything else, and I figured I should just post it for all to see and hopefully for some to contribute. I initially posted the introduction to it on my blog.

The client-side of this game currently works in Firefox and Opera, though gravity and shooting do not yet exist. The server-side of this currently works insofar as the absolute minimum required to send messages from one browser to the other in order for the two players to fly around each other.

At any rate, check out the code (svn co https://@webspacewar.svn.sourceforge.net/svnroot/webspacewar), play around with it, and feel free to submit patches! :-) I would love to see this completed and fully playable. "Space War!" doesn't have a lot of (base) rules, so it shouldn't take much to get there.

Edit: I've also finally, finally checked in the source code for a link checker I started...oh, I think back in 2002... I created the Cocoa/WebKit branch in order to do two things:

  1. Learn Objective-C and Cocoa
  2. Use the Cocoa/WebKit API in order to take care of the HTTP handling

Labels: , , , , , ,

Tuesday, October 09, 2007

Reviewers and plugging the book

Out in San Francisco for the Zend Conference, and I have two people lined up for reviewing the book. One of the reviews should make it up on Zend's Developer Zone if all goes well!

To anyone attending the conference: I have a bound manuscript with me if you want to flip through to take a look. I'll try to keep it out and noticeable so you'll have an easier time spotting me. I also have put out a few piles of flyers in the lobby giving you a 35% discount on the book (it also has the finalized table of contents on the back).

Labels: , , ,

Friday, September 28, 2007

No properly-bound book for ZendCon, but discounts!

So the binding of the books won't happen in time for me to have one to bring with me to the Zend Conference, but I will have a bound manuscript to show off. I will also have flyers to hand out, which will give you a 35% discount on the book!

It ended up working out better for me to go out there for a few days around the conference (I arrive on the 6th), so if anybody in the Bay area feels up for a Saturday night run to any one of the many restaurants I miss in San Francisco, it would make me very happy! If not, I'll just go without you anyway, as I plan to do most of the nights that week (except, of course, the evening of Happy Hour 2.0).

Labels: , ,

Sunday, May 27, 2007

A PDOIterator class using SPL

While writing about the scalability issues of using function calls like file_get_contents and PDOStatement::fetchAll, I wrote the following PDOIterator class, which I have every intention of using for a while. It makes it very easy to keep queries in the application logic while keeping the retrieval of the results in the output, without using any database driver calls. Because it implements the Iterator interface from SPL, the template can use a foreach loop just like it would if the application had passed the results from PDOStatement::fetchAll.

class PDOIterator implements Iterator {
 /**
  * The PDO connection object
  */
 protected $database;
 protected $statement;
 /**
  * The query to run on the first iteration
  */
 protected $query;
 /**
  * Optional parameters to use for prepared statements
  */
 protected $parameters;
 /**
  * The current record in the results
  */
 protected $current;
 /**
  * The row number of the current record
  */
 protected $key;
 /**
  * A boolean as to whether it has more results
  */
 protected $valid;

 /**
  * Forward-only cursor assumed and enforced
  */
 public function rewind() {
  return false;
 }
 
 public function current() {
  if ($this->key === -1) {
   if (!$this->runQuery()) {
    $this->valid = false;
    return false;
   } else {
    $this->next();
   }
  }
  return $this->current;
 }
 
 public function key() {
  return $this->key;
 }
 
 public function next() {
  $this->current = $this->statement->fetch(PDO::FETCH_ASSOC);
  if ($this->current) {
   $this->key++;
   if (!$this->valid) {
    $this->valid = true;
   }
   return true;
  } else {
   $this->statement = null;
   $this->valid = false;
   return false;
  }
 }
 
 protected function runQuery() {
  $this->statement = $this->database->prepare($this->query);
  $this->statement->execute($this->parameters);
 }
 
 public function valid() {
  return $this->valid;
 }
 
 public function setParameters($params) {
  $this->parameters = $params;
 }
 
 public function __construct($database, $query) {
  $this->database = $database;
  $this->query = $query;
  $this->parameters = null;
  $this->current = null;
  $this->key = -1;
  $this->valid = true;
 }
}

The following two code chunks show how to use this class in the application logic, and then later on when displaying the results of the query, assuming an already open connection in $database, an instance of the MySQL flavor of PDO:

// First, run the query and get the list
$query = 'SELECT `id`, `name` FROM `users` ORDER BY `name`';
$users = new PDOIterator($database, $query);

<!-- Later in the application, output the list -->
<ol>
<?php foreach ($users as $user) { ?>
 <li><a href="?id=<?php echo (int)$user['id']; ?>">
  <?php echo Utilities::escapeXMLEntities($user['name']); ?>
 </a></li>
<?php } ?>
</ol>

The query doesn't actually run until the first iteration, so the database connection does not have any open statement until it starts the iterations. Once complete, it sets the statement to null, freeing up the connection for other queries, without having to clutter any of the application code with PDO-specific calls.

This could easily extend to other database drivers (like the mysqli-specific driver, for example), but since PDO stands to have a large rate of adoption (and since I like it), I used it instead.

Labels: ,

Monday, May 14, 2007

Slight knock on PHP in the section on coding standards

I admittedly held back quite a bit from how much I could easily rant on the topic of PHP's complete lack of consistency when it comes to its function/object library. However, I need to finish the chapter on documentation, not how much PHP's lack of consistency annoys me. As a result, the following excerpt reads much more like a hint of slight frustration than the outburst of obscenities uttered as I hit <ctrl>+<l>, <p>, <tab>, <return> to go back to the PHP manual for the twelfth time that day.

Coding conventions should also include variable, function, method, and object naming practices. When languages support upper-case and lower-case alphanumerics, underscores, and sometimes even the dollar sign character, function libraries and APIs have the potential to include a wide variety of calls available to developers. The following four PHP library functions, while all consistently lower-case, have different parameter ordering and variable naming:

strpos ( string $haystack, mixed $needle [, int $offset] )
str_split ( string $string [, int $split_length] )
explode ( string $delimiter, string $string [, int $limit] )

The strpos and str_split functions in particular should not have differences in their naming, as they reside within in the same categorization of library functions in the PHP Manual, but one has an underscore separating the "str" prefix from the full word of "split" while the other has the "str" prefix unseparated from the abbreviated "pos" instead. Looking at str_split and explode, these two functions have very similar functionality: str_split breaks a string into an array of substrings of a constant length, while explode breaks a string into an array of strings as divided by a passed delimiter. Unfortunately, while str_split takes the string as the first parameter and the split length as the second, explode takes the delimiter as the first parameter and the string as the second, requiring calls to pass an empty string as the first parameter in order to break the string into an array of characters.

No matter what the conventions decided, they should not deviate so far from standard practice that new developers have a difficult time working in the code. By using tabs, consistent naming conventions, and consistent parameter ordering, developers should have the ability to "just know" what a library function or API call looks and acts like, and developers will spend less time researching functions and more time using them.

Labels: , ,

Thursday, April 12, 2007

PHP object oddity

While writing about abstraction, I realized that since $variable->$something works, why shouldn't it work when $something=42? Well, logically, because $variable->42 won't work. It triggers a "Parse error: syntax error, unexpected T_LNUMBER, expecting T_STRING or T_VARIABLE or '{' or '$'" when attempted. However...

$a=1;
$b=new stdClass;
$b->$a='a';
var_dump($b);

...results in:

object(stdClass)#1 (1) {
  ["1"]=>
  string(1) "a"
}

Which, I suppose makes sense that PHP, in its type-cast-happy wisdom, would simply make it a string key. But it does create object variables only accessible through abstracting the variable key with another variable by using $b->$a. It will also cast an array to a key of "Array" without any of the array values, and it also triggers a notice about the Array to String conversion.

Just something I did not expect...

Then again, I also didn't expect the following to work in PHP 5.2.1:

function あ() {
 $い = 'あ';
 echo $い;
}
あ();

Labels: ,