Way back when CakePHP had a wiki there were a series of articles on “Advanced Validation.” One aspect of these articles was using the Model rules in JavaScript to validate on the client side. The code (I believe this is it) was originally for CakePHP version .10 (iirc). I had been using a heavily modified version of this code even in my 1.2 projects, but it was due for a ground up re-write.

I wrote an article for PHPArch not too long ago with a generic PHP approach for JavaScript validation. Using that JavaScript as a base, I created a helper to convert the model rules into JavaScript.

Here are the links:
Download
Instructions
Demo

This is all very beta, so please let me know if you find an issue. The helper should work with the three formats for defining validation in your model (output from bake, one rule per field, multiple rules per field).

If you are worried about security, there is an option to only include certain rules. See the tips section at the end of the instructions. Thanks to Marc for suggesting this.

Popularity: 96% [?]

Bookmark This Post

del.icio.us Digg FURL Yahoo! My Web 2.0 Reddit

I just stumbled on this smokin’ article on PHP Architect’s new C7Y site. It’s really some of the best PHP writing I’ve ever seen - even non-programmers will probably enjoy it…uh…alright I wrote. So please check it out.

I’m about 75% done rolling this into a CakePHP helper. And since Cake is going re-focus on jQuery as it’s primary JavaScript library there will be no excuse for not using it.

Popularity: 85% [?]

Bookmark This Post

del.icio.us Digg FURL Yahoo! My Web 2.0 Reddit

I almost never post links to other blogs posts, but I thought this was cool.

Leon Chevalier from AcidDrop.com (is this the worst name for a blog designed to showcase one’s professional skills or just in the top 5?) has created a PHP class (latest version) that will automatically package and minify all your CSS and JS.

I was playing around with it to see if there was anything extra Leon was doing that my CakePHP Asset Packer wasn’t. One thing I found interesting is that the actual cached CSS and JS are stored as PHP files. This is done so that PHP can set the expires headers and gzip the contents. Granted this should/could be done with the actual web server, but many shared hosts don’t allow this. Even so I’m not really sure doing this is a great idea, since you’re essentially trading process time for network time.

From the comments it seems like people are having success using this with their WordPress sites. It would make sense to roll the whole thing into a plugin.

Popularity: 80% [?]

Bookmark This Post

del.icio.us Digg FURL Yahoo! My Web 2.0 Reddit

I actually wrote this over two months ago, but never got around to publishing it. It’s an account, written in real time, of my first experience with the Zend Framework.

Preface

Zend recently released the stable version of it’s framework, 1.0.0 (and shortly after that 1.0.1). The company I work for is planning a long term port of their web apps to the framework, with a short term goal of integrating some of the individual components, such as zend_db and zend_cache.

I have five years of PHP experience. Originally doing almost everything procedurally, then moving to a custom framework pieced together from Smarty, Fusebox and my own database model class. Around a year and a half ago I took up CakePHP and have been using it ever since. I’ve done a bunch of Cake sites and although I’m comfortable with it now, I remember struggling with it at first. Part of that was the normal learning curve and part was the early version I was using.

Now that you know a bit about my background here’s my first experience with the Zend Framework. I’m going in cold here. I’ve read a lot about the framework, but nothing really on how to use it.

7:30PM

I’ve got a four pack of Red Bull, the baby is in bed, and my wife is doing homework for her grad course. I have should have a few hours of uninterrupted time, so let’s rock this thing. I can’t wait to create some “Hello Worlds.” Just try and stop me.

7:35

I went to Zend’s site and downloaded the framework (http://framework.zend.com/download). I went with the zip, since I do my development on windows w/ XAMPP. The zip is 4.65MB. Cake’s latest 1.2 alpha is only 634kb. That’s four megs of extra goodness.

7:40

I just read the INSTALL.txt file. I’m going to re-print the entire installation section right here. You ready?

The Zend Framework requires no special installation steps. Simply get a copy of the framework and ensure that the /library directory is in your PHP include_path.

That’s it.
I make a folder called zend in my xampp/htdocs and throw the whole thing in there.
I’m so excited I can’t even figure out which of the 17 php.ini files that comes with XAMPP to edit.

7:50

It’s /apache/bin/php.ini for anyone who cares.
My include now looks like this:

include_path = ".;C:\\Program Files\\xampp\\php\\pear\\;C:\\Program Files\\xampp\\htdocs\\zend\\library"

Booo: Pear. Yeaaah: Zend

8:00

Hmmm…I pointed my browser at the zend folder and I get a dir listing. Where the hell is index.php? There are some demos and they work, but I was expecting the Cake like welcome page.

To the docs!

8:05

The reference guide looks nice and seems pretty thorough, but I’m can’t seem to find the quick start section. Off to Google.

8:10

The first result for “zend framework tutorial” is for a pre-release version. Commentators say not to use it. I guess “Because this tutorial is published online, I’ll update it as the framework evolves, so that it remains relevant as long as possible.” really means “the internet is for static content, when scientists invent a way to to make changes I will update this document”. I shouldn’t knock on Shiflet. He’s a PHP superstar and kind of looks like Doogie Howser (note: The pic changed to look less Doogie like since I originally wrote this), so even if he got into a horrible PHP security related accident and lost all his programming knowledge he would still have that going for him…unless the accident scarred his face.

8:35

I’m on my second Red Bull. Somehow this one spilled into a glass of ice and vodka. Crazy how these things happen.

The comments from the Shiflet article lead me to this and this.
I’m a bit scared off by the 9 part IBM article, even though they produce some good stuff. Plus it’s all dated 2006, so I’m not sure if it’ll apply to the 1.0.1 release. If only there was a way to update the content of something once it was put online…if only…

The other thing that bothers me about IBM’s stuff is they categorize some parts as “Articles” and others as “Tutorial”. Seriously, parts 1,4,6,7,9 are articles. Parts 2,3,5,8 are tutorials. What’s going on over there? I remember this causing me headaches when I was trying to find all five parts of their Cakephp artorial…or is it tuticle?

9:00

Turns out its up to you to create your own index.php, called the bootstrap file in Zend lingo. You also have to manually create the dirs for your app. Akrabat’s PDF has a dir layout, but I can’t tell if it’s Zend required layout, Zend recommend layout or Akrabat’s “this is my layout - don’t question it” layout.
Either way, I’m not crazy about it. It has the everything in the webroot, then adds htaccess files to deny access. Plus the RewriteRule redirects everything to index.php, then requires another .htaccess to turn off rewrite for images/js/css.

9:30

Eh…The luster is wearing off. I’m two hours in and I haven’t done any code.

9:35

I understand now why some people are calling this the Zend Component Library.

9:45

One of the things I like about Cake is that it promotes best practices. I’ve seen some complain that it is rigid and you have to do things the Cake way. But I don’t mind because a) the Cake way is well thought out and b) it makes easy to pick up someone else’s work.

9:55

I’m convinced someone could make a living buying and selling Red Bull. The price fluctuates more than the price of gold. Somedays it’ll be $2 a can, $7 for a 4 pack. Other days it’s $3.75 a can and $12 plus 10% of all future earnings for the four pack. Don’t even get me started on the new 12oz monster cans they have now.

10:05

I can’t get my brain around not putting a closing PHP tag (?>) at the end of a file. I know it doesn’t “matter” and it prevents you from accidentally leaving whitespace at the end of a file and prematurely sending output to the browser.

Zend’s coding guidelines even expressly prohibit the end tag:

“For files that contain only PHP code, the closing tag (”?>”) is never permitted. It is not required by PHP. Not including it prevents trailing whitespace from being accidentally injected into the output.”

When did this become such a problem? I think it happened to me once and I fixed it in about 3 seconds. This is the programming equivalent to peanut allergies. Who ever heard of such a thing 20 years ago (3 years in PHP’s case) and now all of sudden it’s more widespread than…resisting Paris Hilton joke…screw it…it’s more widespread then Paris Hilton at a night vision camera convention. See I’m not above making three year old pop culture references. I should remove the link from my site to this blog before I never get another freelance job again.

10:15

If don’t you think all this rambling isn’t a pathetic cover while I feverishly read AK’s tutorial then go ahead and keep believing that.

10:25

Ok the tutorial is nice and all, but in the end it’s really just a generic CRUD app that I could generate with Cake’s bake script in about 10 minutes.

Here’s my favorite part:
“It shouldn’t have escaped your notice that addAction() and editAction() are very similar and
that the add and edit templates are identical. Some refactoring is in order! I’ve left it as an exercise for you, dear reader…”

So basically he’s saying: “This is one way to do it, but it’s not a very good way. There’s a much better way and I know it. I could tell it to you and make this tutorial really kick ass, but instead I’m going to leave it to you to figure out.” Thanks.

10:30

For some reason Zend has a bunch of web service classes - not that I’m against this, but it seems odd that they would be part of the core framework. Plus I’d rather have a really nice index.php/htaccess that would work on 99% of the apps. Hell I don’t even know what half these services are. Lucene, Reflection, Strikeiron? These have to be sponsored right? That has to be how Zend is making money off this thing.

10:33

I’ve decided against doing a really boring CRUD app as my first Zend project. If they’re going to include all these random web services I mine as well use one.

10:35

Lucene is “a general purpose text search engine written entirely in PHP 5″. Kind of cool. RSStalker is the closest thing I have to a content heavy site, but I’m not sure Lucene would do much there. NEXT!

10:38

I have to cut back on these Red Bulls - I’m not seeing straight. Apparently Lucene and Reflection aren’t services. I read “Zend_Search_Lucene” and “Zend_Server_Reflection” as “Zend_Service_…”

10:40

I was thinking of doing something with Akismet. Like a text area where people can put in anything then run it through Akismet to see how spammy it is. Kind of like a challenge to see who can produce the spammiest text. In the end I think that would be abusing a cool free service, plus it looks like they only return true/false and not a score.

10:43

Hey Zend manual team. Add a “overflow: auto;” to your pre.programming style. Otherwise your code samples look a mess if I shrink my browser.

10:46

Audioscrobbler is kind of cool. They provide a ton of interfaces to their music info. I remember like 5 years ago I wanted to do a site called onesong.com. The premise was if someone told you about a band and you wanted to find their best song to give them a try you could go to this site and find the top rated (by the users) song. Audioscrobble has a artistGetTopTracks call. I’m sure this has been done a million times by now. Still I consider this a candidate.

10:51

StrikeIron is intesesting. I’m surprised I’ve never heard of them. They “offer hundreds of commercial data services (”Data as a Service”) such as Online Sales Tax, Currency Rates, Red Bull Open Market Prices, Stock Quotes, Geocodes, Global Address Verification, Yellow/White Pages, MapQuest Driving Directions, Dun & Bradstreet Business Credit Checks, and much, much more.”

Come on. There is no way they didn’t pay to be included. The “and much, much more.” is such generic marketing speak. Can’t you just imagine a cheesy over excited guy in a question mark suit reading that last paragraph on a late night infomerical. Anyway, StrikeIron offer some interesting choices and the first 10k requests/month are free.

10:54

I’m going with AudioScrobbler, but not the onesong thing.

A couple of weekends ago I was down in Baltimore with some friends from high school and college. We we’re chatting about music at the O’s/Sox game and one of my friends mentioned there was a new The Receiving End of Sirens CD. I didn’t even know it was going to be released. I’m sure there are a bunch of sites that provide RSS feeds of new album releases, but you still have to scan through the list to find the bands you want. You could use Yahoo! Pipes to filter the list, but I’d rather just be able to get feeds from the bands I want.

Be back…Going to Google for 2 minutes and see if this exists.

10:57

Back. Nothing I could find. I’m going to do this RSStalker style, meaning each band gets its own feed, so if you want to track a 10 bands you’ll need 10 feeds. I could have the user make an account and pick the bands they like, then generate one feed. But then I have to deal with the whole user account thing. I like this way better because someone can just unsubscribe from their aggregator and not have to remember their login to remove a band.

11:00

Hmm…it appears AudioScrobble doesn’t even require an account, so I may actually be able to get his online tonight.

This is a bit worriesome: “Do not exceed one request per second to ws.audioscrobbler.com without prior
arrangement, it will result in your IP being banned.”

This means I’ll have to do a backend script to handle the updates, rather than just updating at the time the feed is requested. Even if I cached the feed, Bloglines requests a bunch of updates at once, so if more than one cache needs to be refreshed I could violate that policy.

Also if someone else is using the service on my shared server it could cause problems. No real way to tell this though, so I’ll just hope I’m the only one (and that my shared IP isn’t already banned).

11:25

Looks like the Zend docs are already out of date. “setArtist” function doesn’t exist. Unless it’s overloaded somewhere, but I’m getting a “Fatal error: Call to undefined method Zend_Service_Audioscrobbler::setArtist()”. I guess it was replaced with the genereic “set” method. Out of curiosity I’m going to check version 1.0.0.

11:28

Nope, not there either.

11:30

Putting together the request and getting back data was pretty easy, except the list of albums is missing TREOS latest release. I guess I’m only getting “Top” albums, not all, but “The Earth Sings Mi Fa Mi” is listed as a top album on the website. A search for Metallica returns 50 hits, but the TREOS only 4, missing the latest album. Seems like the web service data isn’t as complete as the website.

I plow ahead anyway.

11:35

I’m not crazy about using the term “incubator” for trial/in development projects. I feel like they’re waiting to burst out the belly of their host and reek havoc on a ship full of PHP developers. And my wife said the mechanized loader suit was a waste of money. HA!

11:45

I just did a quick AppTable that extends Zend_Db_Table that catches inserts and automatically adds the created and modified dates, like Cake.

I’m not crazy about the fetch syntax:

$row = $band->fetchRow('name = "$key_name"');

Feels like I’m still writing SQL. I prefer Cake’s array approach.

11:48

I also miss being able to set DEBUG to 2 and having all the SQL dumped at the bottom of the page. Zend’s fetch row ($band->fetchRow(’name = “$key_name”‘);) is returning null. It would be nice to see the query that is being run.

11:50

Yes I’m a moron. I was using ‘ instead of “, which means $key_name wasn’t getting replaced with the actual value. I’ll still argue if I could have seen the query I would have known the problem right away.

11:55

Having separate insert/update db calls is kind of annoying too. A generic save, which figures out the right syntax would be nice. AppTable to the rescue!

12:05

I’m sorry, but Zend’s documentation sucks. I know Cake gets crapped on all the time for it’s poor docs, but they are way better then Zend’s in my opinion. Zend’s docs are all style. They look nice, but once you start looking for how to do something even the simplest of things it’s not there. Take http://framework.zend.com/manual/en/zend.db.table.html#zend.db.table.insert.key-auto for example. How do I get the id of the newly inserted row? We’re talking about one line of code, but in multiple paragraphs about auto-incrementing keys, sequences and natural keys they don’t answer that simple question.

While I’m on the topic the API sucks too. I practically live in Cake’s API. That’s my home on the corner of Cache and Auth streets. The blue one with the white shutters.

Cakes API smokes Zends API - no argument. Where is the search? Where is the link bringing you right to the code? You can argue that Zend API is using phpDocumenter, so it’s limited to that functionality? I think that’s a poor excuse and makes me wonder how phpDocumenter skated by for so long.

Despite my grievances, this app is coming together quickly.

12:30

By the way the answer to my above rant about how to get the auto id: the return value. It’s the return value.

12:40

Somewhat often the AudioScrobler service fails to respond causing an error to be thrown. Which works well until the catch block tries to do a getStatus on a non object and a fatal error occurs. Oh well I guess that’s the risk you take using beta software. Whats that? Zend is production ready you say?

12:44

There’s actually a band called “asdf” with a self-titled album.

SimpleXMLElement Object
(
    [name] => asdf
    [mbid] => SimpleXMLElement Object
        (
        )

    [reach] => 4
    [url] => http://www.last.fm/music/ASDF/asdf
    [image] => SimpleXMLElement Object
        (
            [large] => http://cdbaby.name/g/i/girldown.jpg
            [medium] => http://cdbaby.name/g/i/girldown.jpg
            [small] => http://cdbaby.name/g/i/girldown.jpg
        )

)

I just spent 15 minutes trying to debug why this, since I was expecting the search to not return anything.

12:50

I spent a few minutes trying to figure out how to relate tables and decided to move on. Even if I figured it out all the examples were still using two queries rather than one query with a join

1:25AM

Once I got rolling this thing actually came together pretty quickly. It probably has a bunch of bugs and I never got around to doing an update script. Because of this I’m not really comfortable putting it online. I’ll probably just zip it and include the code with this post.

1:40AM

I’m officially exhausted and declaring this done. Here’s the zip of the code. There is no documentation, it is thoroughly buggy and it was written in a five hour binge by someone trying to learn a framework and probably includes code that would make a seasoned Zend professional give up PHP forever and take up Java or ASP.

Epilogue - Two Months Later

Re-reading this it’s clear I soured on Zend by the end. To be honest, if it was the only thing out there I would probably stick with it and eventually depend on it. I remember when I was first forcing myself to learn CSS. I hated it. I kept thinking how easy it would be to switch back to table-based layouts. But I knew it was better so I stuck with it and now can’t image going back.

With Zend I’m not convinced it is better then the alternatives, namely CakePHP. It’s really just a matter of preference and if Zend had gotten to me first, maybe that would be my #1. In the end it doesn’t really matter. Zend, Cake, Symfony, CodeIgnitor…they’re all a trabillion times better then slopped together procedural code.

Popularity: 61% [?]

Bookmark This Post

del.icio.us Digg FURL Yahoo! My Web 2.0 Reddit

cakebaker posted about a new series on the IBM Developers network covering the top three PHP frameworks. The series will focus on CakePHP, Zend and symfony. You can’t really argue with this group as being the big three of PHP Frameworks…unless you exclude Zend since it’s more of a library then a full-stack framework.

A couple things about the article.

- I wish there was a planned part 6 that would run a series of benchmark on the app that is created, both with and without caching. It looks like they plan to release the code, so in theory I could do it…in theory…

- Under the “Installing CakePHP” section there is a part:

You should wind up with four directories (app, cake, doc, and vendors), as well two files (.htaccess and index.php). You will be moving some of these files around later, but for now this is OK.

I’m interested to see where they’re going with this since I’ve ton a bunch of Cake apps and haven’t moved any of this. I assume they’re moving the cake folder to a shared location so it can be shared by various applications. I see this a lot and frankly I hate the idea, but that’s a whole other post.

- The part about how Cake automagically updating timestamps in the DB doesn’t mention there are other magic timestamp fields such as created. I guess they can’t mention every feature, although I would think they would at least mention the benefit of Cake automatically handling these fields, which is database independence (I think).

- I like that they’re pushing Cake 1.2 even though it’s “Alpha”. I started a pretty big project a few months ago and went with 1.1 and am kicking myself now. Well not really. 1.1 is still pretty nice.

Popularity: 52% [?]

Bookmark This Post

del.icio.us Digg FURL Yahoo! My Web 2.0 Reddit

VerticalResponse LogoAlthough this may seem obvious to most developers, if you’re using a template system, such as Smarty, there is no reason for the templates to live off of webroot. If for some reason you do need to keep your templates there, remember to add the template extension to apache, so that it treats the files as PHP. Otherwise you risk sending your PHP code directly to the browser.

This is all painfully obvious, right? We’ll not to the folks at VerticalResponse. The other day I was attempting to setup an email newsletter, but couldn’t get past the login. I was getting (split onto two lines):
VerticalResponse Error Message

So for kicks I tried the url, less everything before htdocs. To my surprise it worked, PHP code displayed exactly as it was typed in.

Curious, I tried some other templates names. I was just making guesses based off the one name I knew.

Granted these are just templates and there really isn’t anything too damaging exposed. Although I only spent five minutes doing this.

This concludes “Obvious Tips, That Aren’t So Obvious To Some - Part 1″. Part 2 begins right about…now: Turn off display_errors on your production system. Yes, I’m still talking to you VerticalResponse.

Popularity: 48% [?]

Bookmark This Post

del.icio.us Digg FURL Yahoo! My Web 2.0 Reddit

One of my goals with this blog is to post more code snippets. It is something I did occasionally on my old blog. It’s one of those things that should be simple, but ends up being a bit of a pain. I’ve used a Wordpress plugin in the past, but I was never fully satisfied with it. Lately I’ve seen some other programming blogs I read using a client side Javascript solution. After some digging the two “ready for prime time” packages I found were Chili and SyntaxHighlighter.

This is a comparison of those two. If you feel I missed another package let me know in the comments.

Chili

License: MIT
Includes: jQuery(21KB), core (7KB), PHP CSS(1KB), PHP JS (37KB)

One of the things I initially liked about this package was that it used jQuery, which is my new favorite Javascript library, although then I realized, as much as I use jQuery on my web apps, I don’t really have a need for it on this blog. So having to include it was just additional baggage.

I’m not crazy about the overall size. The PHP “recipe” is 37KB alone. Much bigger than any of the others. Another drawback is the weak documentation. The Chili page is long, dominated by the change log - which is good information, but placed poorly. A simple “how to use Chili” section with code samples - USING THE FREAKING PACKAGE would be nice [Update July 24, 2007 - Chili has a new quickstart page. I'll leave me rant here for entertainment purposes].

You know, something like:

1) Include jQuery and the Chili Javascript files. Your paths may be different.

<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/JavaScript" src="/js/chili-1.8b.pack.js"></script>

2) Chili can automatically find the recipes it needs - simply tell it where to look.

<script id="setup" type="text/javascript">
    ChiliBook.automatic = true;
    ChiliBook.recipeFolder     = "chili/js/";
    ChiliBook.stylesheetFolder = "chili/css/";
</script>

3) Wrap your code and tell Chili which recipe to use. Remember to replace & with &amp; < with &lt; and > with &gt;

<pre><code class="php">
<?php
    class family_friendly() {
        function censor($word) {
            return '*' . gettext($word) . '*';
        }
    }

    function get_license() {
        return 'Creative Commons';
    }

    printf('This guide is released under the %s license.<br />', get_license());
    printf('Seriously, Chili author, if you are reading this, move 95% of the %s onto secondary pages and include this simple tutorial.<br />', family_friendly::censor("crap"));
?>
</code></pre>

That’s all you need. Thats all the information 99% of your users need. I shouldn’t have to figure out which of the five example pages I need to view source on to get this working. Especially when they have such confusing names as: examples-all-combinations.html (which appears to be a joke, that I don’t get), examples-dynamic-automatic-adhoc.html, examples-dynamic-automatic-adhoc-metaobjects.html, examples-static-automatic-adhoc.html. Huh?

I’m done with my rant. I’ll say some nice things about Chili now. One of the features that is really cool is that it’s completely automated. You simply wrap your code with the correct tag and Chili does the rest. Also since it is a plugin for jQuery it degrades nicely, leaving the code less pretty, but still completely readable.

Now that I said something nice I can go back to ranting. The samples provided with the download have Google Ads in them. I can understand having them on the actual site, but in the downloaded samples it seems a bit tacky to me. Even worse the ads are all food related, that is when they’re actually in English. I assume the author simply took the pages directly from the site and rolled them into the download, but I still find it annoying.

Also the author makes the claim “You just put the code you want highlighted in a code tag AS IS”. Then not even 300px later he states “Always escape the content of the code element for HTML: at least substitute any & by &amp; and any < by &lt; in this order. If you want to highlight HTML you also need to escape any > with &gt;.” So it isn’t exactly “AS IS”.

SyntaxHighlighter

License: GNU
Includes:CSS(4KB), core(11KB), PHP (5KB)

SyntaxHighlighter is obviously a much lighter solution. It too has separate includes for each language, called brushes here. The instruction page is also well done. In addition to highlighting and formatting the code SyntaxHighlighter adds buttons that allow the user to view plain, copy to clipboard and print. On the downside it isn’t automated like Chili, although you could certainly use jQuery, or some custom javascript to execute HighlightAll on a page load. Like Chile you need to encode the < character (but not > or &).

1) Include the core files and the brushes for any language you want. Your paths may be different.

    <script type="text/javascript" src="/syntaxhighlighter/js/shCore.js"></script>
    <script type="text/javascript" src="/syntaxhighlighter/js/shBrushPhp.js"></script>
    <script type="text/javascript" src="/syntaxhighlighter/js/shBrushJScript.js"></script>
    <script type="text/javascript" src="/syntaxhighlighter/js/shBrushXml.js"></script>

2) Put this at the end of your file. If you put it before the code you want highlighted it won’t work.

<script class="javascript">
dp.SyntaxHighlighter.ClipboardSwf = "syntaxhighlighter/js/clipboard.swf";
dp.SyntaxHighlighter.HighlightAll("code");
</script>

3) Wrap your code and tell SyntaxHighlighter which brush to use. Remember to replace < with &lt;

<pre name="code"  class="php">
<?php
    class Highlighters() {
        function result($highlighter) {
            switch ($highlighter) {
               case "chili":
               default:
                  return "FTL";
               case "syntaxhighlighter":
                  return "FTW";
            }
        }
    }

    $highlighters = new Highlighters();
    printf("Chili is a nice effort, but just not for me.  Chili %s", $highlighters->result("chili"));
    printf("I am going to give SyntaxHighlighter a shot.  SyntaxHighlighter %s", $highlighters->result("syntaxhighlighter"));
?>
</pre>

Wrap Up

If you’re already using jQuery and want to highlight non-PHP then Chili is worth checking out. For this blog I’m going to give SyntaxHighlighter a shot. I think end result of SyntaxHighlighter is nicer looking and the additional buttons are useful features.

If you have any experience with either feel free to write about it in the comments.

Popularity: 75% [?]

Bookmark This Post

del.icio.us Digg FURL Yahoo! My Web 2.0 Reddit

golfshake.com logogolfshake is a niche social networking site, targeted at golfers. In addition to the standard social features, golfshake adds many tools specific to the golf community.

Darren Ramowski originally submitted his site a couple months ago when it was golfscoretracker.co.uk. Since then he has done a complete overhaul and recently re-launched as golfshake.com. The new name and site are both big upgrades. As Darren explains in his blog, the main drive behind the switch was to promote the site to international (non-uk in the case) users. In addition the site has grown beyond a simple score tracking system to a full fledged community. The new name fits both these goals.

golfshake.comThe original site was built seven years ago as a side project to help Darren’s golf game, as well as a way to refine his PHP/MySQL skills. The site has really taken off in the last 18 months as the user base has jumped from 1500 to over 16K. Darren attributes most of this growth to the additional community features which have encourages word of mouth advertising.

From Darren:

Within the last 2 years the site has seen some major updates to the code base and the introduction of lots of new features. Users can now get in touch with each other to arrange golf games, see how their golf compares with buddies, organize public events which other users can join and run golf societies online. It’s a bit of a cliche but it’s almost MySpace for golfers.

I’m a big fan of this sort of stat tracking/competition angle. It’s something that will keep users coming back and active on the site. The way Darren has incorporated the usual social networking features with features targeted directly at golfers is impressive. It is this integration of stat tracking and community that really set golfshake apart.

If you’re a golfer, golfshake is definitely worth checking out.

Popularity: 54% [?]

Bookmark This Post

del.icio.us Digg FURL Yahoo! My Web 2.0 Reddit

I wrote my first guest post the other day. It was an intro to Xdebug for PHPDeveloper.org. I didn’t like the end result as much as my post on how to use Xdebug to speed up your code.

Popularity: 76% [?]

Bookmark This Post

del.icio.us Digg FURL Yahoo! My Web 2.0 Reddit

adGridWork adGridWork is a re-imaging of the old (Web 1.0-1.5) ad exchange sites. I can’t remember any specific sites, but the basic premise was for every 3 (or whatever) ads you show on your site, your add gets shown on 2 sites. The extra ad was sold, allowing the site to make money. The big difference with the adGridWork project is that everything is free. It is a basically a way for the web community to help support each others sites with nothing being taken away.

adGridWork ScreenshotThe site was created by Kyle Johnson and Nick Mazza, both college students majoring in Computer Science. Kyle and Nick are true practitioners of rapid development - they conceived the site in November and had it launched on December 1st. It’s been less than two months since the launch, but they have over 800 registered sites thus far.

One of the most impressive features on the service is it’s ability to filter ads so that only relevant ones are shown. This benefits the site displaying the ads as well as having your ad shown on appropriate sites in the network.

When registering a site with our network, you can select from dozens of specific categories your site falls under, as well as specify any number of keywords to associate with your site. Our ad engine will then display your ad on other sites with similar categories/keywords. In turn, similar ads are displayed on your site, with the exception of any competitor’s ads (you can list your competitors when registering a site).

I signed up for the service a couple weeks ago so I could give it a trial run before writing this. adGridWork provides stats for both the ads your site has served up as well as your ad on other sites. The stats for PseudoCoder are a bit disappointing, but that isn’t adGridWorks fault. This blog isn’t highly visited (yet) - I’ve only shown 178 ads on this site and 0 (as in zero, none) have been clicked. Stats are updated in real time - I just clicked an ad to check.

The PseudoCoder text ad as it appears on the adGridWork networkRight now I’m clearly a leacher. Although I’ve only shown 178 ads, my ad has been shown 5991 times. And clicked on 5 times for a .08% conversion rate. To be honest I have no idea if that rate is good or bad, but I suspect it’s bad, horribly bad. Although this could mean my ad isn’t being show on the right types of sites, I’m guessing it probably because the ad itself isn’t very compelling.

Even though the service isn’t working on great for me at this point I’m going to leave it on this site for a bit. It’s the least I could do since I’ve my ad has appeared about 30 times more than I’ve shown other peoples. If anyone has any suggestions for improving the text in my ad I would definitely give it a shot.

Popularity: 24% [?]

Bookmark This Post

del.icio.us Digg FURL Yahoo! My Web 2.0 Reddit