Blog Death Knoll
I’m a bit overdue on writing up my thoughts on the third annual DC PHP Conference, but I had been considering how to re-purpose this blog to allow me to post more frequently on a more tightly focused set of topics, so actually writing has been on the back burner, metaphorically speaking. The conclusion I’ve ultimately come to is that I don’t have the time or energy to maintain a blog for OEIC at this point. My hands are full with actual development work, and I don’t have the passion to cover the endless stream of new tools and events that coming flooding out of the internet since I’m not particularly interested in huge volumes of noise. Fortunately, there are millions of people handling that for me.
Perhaps if I decide to take the plunge, and grow OEIC as a business, I’ll re-open. Until then, some final shoutouts from the DC PHP conference of a few weeks back.
Mike Lively gave an excellent two part presentation on unit testing with PHPUnit that was quite droll, as well as informative.
Eli White offered an in depth look at the sort of data shuffling you can hope to deal with if you get as popular as Digg.
David Sklar (who it seems also cannot be bothered to update his website) demoed an assortment of PHP scripts to analyze your PHP scripts, and also peeked beneath 14 layers of PHP petticoats with dtrace. It appears Ning has some excellent engineers aboard.
Open Source fun
It’s been a great few weeks for open source projects, as Magento hit 1.0, the Zend Framework hit 1.5, Wordpress hit 2.5, and (not really open source exactly) Apple launched the iPhone SDK. It’s been a lot to keep up with! Combine that with a fair amount of client work, and you see why I haven’t been posting much here. Good problems to have, as they say.
jQuery wins
Cameron Moll mentions today that Javascripting is now a required skill for any front end web designer worth his salt. I’m inclined to agree, as Javascript has made its way from the rainbow-coloring of text in the mid-nineties to a mainstay of the most used websites in the world (I’m thinking of Yahoo and YUI, in particular). While Javascript used to be about the most language I’ve ever developed with, thanks to highly different engine implementations in the various browsers and non-existent or bad tools, it’s come a long way for developers in the past few years, due to the emergence of several cross platform libraries. The big three I’m familiar with are prototype, jQuery and MooTools.
These competing libraries offer equivalent functionality. Prototype is built into Ruby on Rails, and has a big developer base as a result. MooTools is lightweight, and the library can be built to only include the functionality you need. jQuery has proven to be my library of choice, not because it is better than prototype or mootools, but because it’s easy to extend and a many of developers have done just that. There are already hundreds of widgets and plugins listed on the jQuery site. Like pretty much everything in life, someone else has probably already had to solve the same problem you have now. Being a good developer is just as much about knowing when to stand on the shoulders of others as being able to build everything yourself.
On the flipside, there is no such ecosystem in place for Prototype and mooTools. I’ve got to rely on Google to find extensions for the other libraries. While Google is great, it’s a driftnet. In my particular information seeking case, I prefer a targeted, community managed, categorized list. Are there an equal number of great extensions for Prototype? I don’t know, I’m still paging through the Goooooooooogle….
On a somewhat tangential note, this is a compelling argument for the power of information architecture. The jQuery team thought beyond the code to the way it would be used, and designed their site to address the needs of their users. It’s simple concept, but one that is missed by many sites. jQuery did it right, won me over, and I think it will win many more.
Zend Framework 1.5 Preview
The Zend Framework team recently announced the release of the preview for version 1.5 of the framework. I’m excited to play around with several new components, specifically the OpenID and LDAP authentication adapters and the Zend_Form module.
I haven’t really gotten on the OpenID bus yet, but it seems promising, and I can certainly smile at the idea of one day being able to login to the web, rather than individual websites. Imagine not having to remember the password that took six tries to match the byzantine rules for password robustness set by web development team. There’s a very significant security risk involved with the technology at first glance: if you can login everywhere with one set of credentials, if/when they get stolen, the thief has access to EVERYTHING. Security and convenience are often at odds. it will be interesting to see how OpenID addresses these concerns as digital security gets more attention in the coming years.
Zend_Form looks to be the next promising tool in the line of HTML form generating libraries. It may initially stick in the craw of Model-View-Controller hardliners, as the examples provided in the Zend Documentation program the form in a controller action, but when you think about it, forms are more than just presentation. They’re one of the main interactions with any application, and the logic that must be applied to form input can be very sophisticated.
In fact, form validation is an instance where tight coupling is appreciated. While the layout of a form should not be linked with filtering and validation, the composition of a form should be. I will always want to validate every form field - that’s not going to change. Since I don’t have to accommodate that change in process, it’s great that I can be saved some development and maintenance time by binding validators and filters to the presentation of a form element directly. With luck, I’ll get the time to use Zend_Form soon.
Exceeding Expectations
I read a lot of job boards. There are a number of fascinating projects under development right now, and its exciting to have a chance to work with people who see the Web in a different light. Of course, it’s a two way street - these entrepreneurial souls need to find quality talent, and that search can be like finding a needle in a haystack, if that’s how you set up the search. Today I ran across a posting for a designer and UI Engineer which immediately set off my red flag.
This confidential “elite” company is looking for “an equally qualified designer with a discipline in delivering creative work, on time, on budget and beyond expectation”. First off, if you’re an elite company, you don’t hide your brand, you exploit it any time you can. Your brand has power, not your claim of being elite. That’s the whole point of branding, to fill your name with significance, then use your name all the time. If these people think they’re weeding out bad candidates by staying confidential, they’re certainly weeding out the best candidates as well.
Secondly, anytime someone expects work “beyond expectation”, I laugh at the paradox. Don’t use this line. It’s absurd. A better practice is to tell prospective employees and partners who you are and exactly what you are working on. What purpose does the mystery serve? I’d love to know.
Transparency counts
Joel Spolsky writes about the inevitability of some downtime for any online service, as well as the best way to let your customers know about a problem, its resolution and what you’re doing to protect against another occurrence in the future.
Broad and deep
It’s hard to believe it’s already two weeks into 2008. The last 14 days have gone by in a blur as I’ve been frozen in experiment and learn mode. Like most complex systems, there are a large number of different roles that need to be filled in making the Web function as smoothly as it does. You need networking people, system administrators, developers, designers, architects, testers. Each of these positions relies on a very specific set of skills and knowledge that gets deeper by the day. Since the Internet is such a new phenomena, most businesses that use the Web are still learning about what particular division of labor works best in their particular case. In my particular case, I have to know a little bit about all of the above. I’ve been spending 2008 trying to improve my networking and system administration skills from competent to competent with understanding. I’m sure Adam Smith would disapprove, but its still a gratifying challenge to learn how to do something I’ve never done before, especially when it works.
Theo Schlossnagle has put together a great post on keeping networks functional that I’m sure Adam Smith WOULD approve of, by helping to define a trade, and outlining the walk from A to B to C. It sheds a little light on the fact that even though we often want a clear career path to advancement, its hard to avoid doing a bit of everyone’s job along the way.
Enabling mod_rewrite and .htaccess in the LAMP Virtual Appliance
Life is just one damned thing after another.
–Elbert Hubbard
In the past few weeks, there’s been a figurative landslide of tiny problems that have produced (ironically enough!) a pretty unproductive stretch of time here at OEIC Labs, which is how I’ll now be referring to myself. Fortunately, I’ve found that these times teach me how the technologies I use every day actually work, and leave me wiser in the long run. The challenge is keeping a positive mindset, rather than dropping a double axehandle on my monitor. Or so I’ve been told.
Since I’m sure you’re chomping at the bit, frothing at the mouth and generally getting all lathered up in exertion over the prospect of reading exactly what technological hurdles I’ve had to jump over, allow me to present them.
For a new project, I needed to integrate RETS Retriever with cakePHP. RETS Retriever is a PHP application that connects to a Real Estate Transaction Standard (RETS) server, makes formatted requests and displays the returned real estate listings. Since it’s an application, I figured on installing it, running a configuration wizard and that’s about it. If you’ve read my blog before, you’ll know I was wrong.
Installation: check! Configuration: check! Retrieve listings: uh, no dice! I assumed my configuration was incorrect, so I changed the server URL four different ways and was still unable to connect. At this point, as I usually do, I delve into the code to see what’s happening. After tracing through the stack, I find the connection call, plug in a static value of google.com, and am able to open a connection. Hmmm. Why can’t I open a connection to the RETS server then? Because RETS operates on port 6103, of course. And my hosting company has it firewalled. And won’t open it. Lesson 1: Never use shared hosting if you’re a developer. Surprising it took me three shared hosting companies to learn this. Zing!
Ok, I’m going to need a new development server for the project. I’ve been wanting to experiment with VMWare Server and Virtual Appliances for a while, so here is the perfect opportunity. I download the two products, after determining the server I’m going to install them on had a bad NIC that was eating my internet connection. I only wasted one day talking to Verizon about that though. I get the appliance running on the server, and everything works! You can see that I’m unaccustomed to such wild success. I install RETS Retriever on my new VM, and get a connection to the RETS server.
Now we’re cooking! The only problem is that the RETS server isn’t returning any listings. I’m fairly certain there are some properties on the market somewhere in this great nation, so I know I’ve got something to work out. Once again, I do a stack trace through the code, and determine there’s a configuration issue. Lesson 2: It’s usually a configuration issue. Don’t waste time poring through code, if there are config files to play with first. Assume you’re the idiot first, not the other guy.
Luckily, thanks to my code perusal, I find a nice debug feature that I enable in the Retriever code, and I learn I’m passing bad parameters to the server. Lesson 3: Anything that has Standard in its name will be anything but. There are a lot of RETS server implementations out there, and they disagree about what defines a real estate property. Anyway, I get rid of the bad parameters one by one, and finally pull down some listings. A tiny triumph!
After about three days of poking around at something that I thought would take 2 hours, I can finally start working on the meat of the problem, integrating Retriever with cakePHP. I get the latest cake release, unpack it to my VM, open it up in Firefox and discover that mod_rewrite isn’t enabled in Apache. This I did not expect. Uh guys, every major open source application from the last 3 years uses mod_rewrite in some capacity. If you want this VM to be used as a server, mod_rewrite should be enabled. Now I have to hunt down the Apache configuration files, which are always different for the different Linux distros.
Aha, after nine paragraphs of prefacing, we finally arrive at the title subject of this post! Release your clenched jaw and rejoice! Enabling mod_rewrite for the Ubuntu 7.04 LAMP Virtual Appliance is quite simple via the command line:
cd /etc/apache2/mods-enabled ln -sv ../mods-available/rewrite.load rewrite.load apache2ctl -k graceful
Apache restarts and mod_rewrite is enabled, so I pull up my cakePHP install again and see that my CSS can’t be found. This is most curious, so I assume it is because the cake packaged .htaccess file is wrong in some fashion. I replace it with another .htaccess file I know works with cake, but no luck. Is it possible, dare I say it… .htaccess is disabled too?
Indeed, that’s the case. .Htaccess is being ignored by Apache. I’m shocked. Why? For a virtual server advertised as uniquely easy to use, there are quite a few oversights as to what it would actually be used for. Anyway, it’s also quite simple to enable .htaccess:
vim /etc/apache2/sites-enabled/000-defaultOn line 12 of that file, replace
AllowOverride None
with
AllowOverride All
and restart apache with the apache2ctl -k graceful command from above. Now you have a functional LAMP web server! That’s all it takes - now I can get some work done. It makes me wonder what to call what I’ve been doing for the past 4 days. Pre-work? Work-like? Workishness?
Lesson 4: It always take 6 times longer than you think it will.
Zend_Filter_Input and arrays
Here’s a quick tidbit that I discovered a few months back, forgot to document and it bit me in the rear just now. If you’re using Zend_Filter_Input for input validation in your applications, and you’re expecting the incoming data to be a multi-dimensional array, be sure not filter any keys that contain an array, as ZF will transform the array from a data structure to the string “Array”. For instance, let’s say you’re expecting the following data:
$inputData = array( 'parentID' => 1, 'title' => 'My parent data', 'children' => array( 0 => 'Red', 1 => 'Green', 2 => 'Blue' ) )
So you set up a Zend_Input_Filter like so:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | $filters = array(* => array('StringTrim', 'StripTags')); $validators = array( 'parentID' => array( 'NotEmpty', 'Int', 'messages' => array( 0 => 'Please specify a parent ID.' ) ), 'title' => array( 'Alnum', 'messages' => array( 0 => 'Please use only letters and numbers for your title.' ) ), 'children' => array( 'presence' => 'optional', 'allowEmpty' => true ) ); $inputFilter = new Zend_Filter_Input($filters, $validators, $inputData); |
Using the wildcard operator in the $filters declaration will destroy $inputData[’children’]. Rather, you have to individually specify each key to filter, skipping ‘children’.
1 2 3 4 | $filters = array( 'parentID' => array('StringTrim', 'StripTags'), 'title' => array('StringTrim', 'StripTags') ); |
Of course, this isn’t the most secure approach, since no filtering is performed at this point on the contents of the ‘children’ array. There’s a need for filtering and validation classes that can walk through arrays, and validate the values within, but I haven’t yet discovered such classes, so I’ve been using my own custom code in the instances where I need it. Let me know if you’ve developed or run across array compatible ZF filtering and validation classes.
PS - can anyone recommend a plugin or alternative blogging tool to wordpress that will allow me to format code samples properly? I’m sick of fighting Wordpress just to display line breaks and indenting in a <code> tag.
PPS - I’ve found a good code syntax highlighting plugin, and I’ve discovered the WP Visual Editor is the root of all my woes. I turned that off in my user profile, and surprise, surprise, my content stopped getting modified. As usual, good intentions paved the path to (relative) hell. Do less.
Web platforms
As a semi-follow-up to my post on the new Gmail interface a few weeks back, I wanted to link to the thoughts of Marc Andreessen on the present and future of web computing and application development. As usual for me, the post itself is somewhat old news, having been written in October, but I like to let ideas settle, then percolate back to the forefront of my mind before writing about them. Like development itself, the first version is usually wrong in some fundamental way, so I prefer to keep that first mental version to myself. The second iteration is usually wrong too, but within the accepted margin of wrongness known as right. Ruminate on that for a moment!
Back to the chase: Andreessen talks about the levels of platforms on the internet. For him, a platform is something that can be programmed against. His first tier platform is a read platform - data is pulled from the platform via a formal API, but the consumer of the data is completely independent of that platform. This isn’t much different from a screen scraper from 1997, except that the platform is aware that the data is being used programmatically. This is pretty much all of Web 1.0. Undoubtedly useful, and the most flexible for the developer of the data-consuming app because there is no platform mandated standard for app behavior.
Tier two is any platform that allows an external application to display within the end user interface. Essentially, a tier two platform provides defined hooks that a developer can latch onto to provide some extra functionality for the platform users. The application lives elsewhere, but that’s somewhat transparent to the end user. Andreessen cites Facebook, their new FBML, and sees this as an upgrade for developers from a tier one platform, but to me, there are a few drawbacks. Any new application is tied to the fate of the platform. The whole investment of time and capital into the application is completely dependent on the success of the platform company. Unlike operating systems and other local system software, which can live on after the company that created it, if a web platform hits a rough spot financially, the application’s user base and the application itself disappears. There is zero room for legacy systems in a tier two environment. Piggybacking on a tier two platform can be very powerful, but it is also very risky at this point. You know, that whole risk-reward thing. Undoubtedly, we’ll see the emergence of porting tools for tier two platforms, much like we see platform independent (ha!) environments like Java now. Of course, I’m assuming that tier two platforms will all have competition as time goes on.
Tier three is what Andreessen is pushing for… because the most recent company he founded provides a tier three platform. It’s essentially a public installation of Sharepoint server - application code lives in the tier three platform, displays in the platform UI to end users and leverages the platform for most of its functionality. Again, Andreessen sees this as a far superior to tier one and two for developers , but I feel he’s actually writing from the perspective of the platform provider.
If you’ve ever delved into UML, you know that there are several different ideas about what programming is. To some, it’s a whole lot of typing, for others it’s dragging widgets from a toolbox onto a canvas, for the architects, it’s diagramming. Essentially, it all comes down to how much control you want as a developer. There are certain expectations attached to every tool. Hammers are not designed to screw, plane or cut. If you want a tool that does those three things, and you only have a hammer, you’re in for a long day. Platforms are tools for programming, and as a developer, you need to be sure that the tool is right for what you’re trying to accomplish. Sacrificing control for ease is a trade-off to be analyzed, not accepted as the Golden Brick Road.
Afterthought: Joel Spolsky, also as usual, has some words concerning the relative futility of shuffling programming labor from tool to tool.
Categories
- App Design (8)
- Blogs (6)
- Business (4)
- Code Philosophy (2)
- Javascript (1)
- Open Source (5)
- PHP (15)
- Thoughts (2)
- Tools (10)
- Usability (3)
- Wordpress (2)
- Zend Framework (9)
