djsipe.com | Web Development

Over the years I’ve used a number of different PHP IDEs.  Some were great some were “meh”.  One of the things I look for in an IDE is if it really does make my life easier.  When I have things to do, I can’t afford to spend days getting my IDE to work as advertised it just needs to work.

Zend Studio

I’ve used Zend Studio from versions 5 to 8 and with the exception of 5, they all…well…kinda sucked.  Ever since Zend decided to adopt Eclipse, it’s been slow a nightmare.  There’s the potential to be great, but as with all things Eclipse, you have to spend a lot of time upfront configuring the IDE to do whatever it is you want it to do—and it’s ridiculously slow.  I can remember spending no less than an hour fumbling around with plugin dependencies before ultimately giving up and swearing off Zend Studio (until the next version came out with all the promise of a new dawn).  Cost: $299

Komodo

Admittedly, I haven’t used Komodo for years but I remember it was also a solid IDE.  I do remember the interface being a little clunky and hard to navigate around, but the folks at ActiveState may have addressed that in later versions.  Cost: $382

Eclipse PDT

Eclipse PDT is the core IDE for PHP from the open source Eclipse project.  It’s pretty much the same as Zend Studio these days except that it’s free and doesn’t tie in with Zend’s proprietary products.  Being free, it’s hard to speak too ill of it, so in some ways I like it better than Zend Studio.  But when it comes down to it it’s even less pre-configured for out of the box development than Zend Studio.  This means it took even longer to get it into a condition where I could use it.  I ultimately uninstalled it and never looked back.  But if you have the patience and expertise to stick with it, PDT can do great things for you.  Cost: Free!

Aptana

Aptana is a really good IDE.  It has great PHP and JavaScript support.  Also based on Eclipse, but somehow not as slow as PDT or Zend Studio.  Aptana also has great out-of-the-box usability to it.  It’s a great choice if you want a free IDE that handles both PHP and JavaScript reasonably well.  One down side it that it comes with a lot of obnoxious “ads” (links to) for their integrated hosting services.  Cost: Free! 

PHP Storm

In my opinion, PHP Storm is the absolute best PHP IDE.  It is extremely well thought out and makes programming a pleasure with its code assist auto-completions.  I don’t know how they did it, but it seems like it always knows what I am about to type.  As with most other IDEs it has support for Git, SVN, and everything else you’d need.  There’s also Phing, Xdebug, PHPUnit, and more.  I do remember it didn’t come with out-of-the-box support for MySQL and I had to fumble around with an ODBC driver and buggy Java modules to get MySQL working in it.  Cost: $99

PHPDesigner

PHPDesigner is good workhorse IDE.  It doesn’t have a lot of the slickness of some others, but it is fast and it just works.   It also supports true remote projects where your code is saved on a remote server.  Being able to work on remote files directly without having to download them is a godsend in situations where your codebase can’t be easily configured to run on your local computer.  But, understandably, when working on remote files the support for code assist options is limited to only those files you have opened.  PHPDesigner also has some annoying quirks with the way it handles the auto-pairing of opening quotes, parentheses, and HTML tags—but again the support for remote projects outweighs all of these minor problems.  Cost: $37

If I’ve missed any others, and I’m sure I have, just let me know which ones and what you think about them.

Siri

Siri

Like a lot of people, I rushed out to get the new iPhone 4S when it came out.  (Well I rushed to my computer to pre-order it technically.)  At first I really liked the Siri integration in the phone.  It was cool to see all the nifty things it could do.  But it still struggled to understand some seemingly simple commands.  Commands like “Do I have any new email messages?” got me “I do not see ‘new email messages’ in your playlists.”  Hugh?

It didn’t take long for me to start using Siri less and less.  It seemed that with every befuddled response I got from her, the less likely I was to even try using the service again in the future.  Any time I strayed outside of the short list of commands demoed in the Apple keynote, I was almost always left repeating myself to her over and over, and then ultimately forced handle the problem myself.  Every time Siri fails to understand me is one more time I become frustrated at having my time wasted.  The end result is I almost never use Siri except in those handful of instances where I know it works.

It was my pleasure to speak at this month’s first-ever meeting of Web Dev Connect.  This month’s topic was an introduction to jQuery.  Next month we’ll be talking about the new jQuery Mobile framework.  Hope to see you there!

Below are my slides.

This took me a while to figure out so I thought I would post it here just in case it may help someone else.

One of the challenges of using any of those nifty widgets that ship with our favorite JavaScript frameworks is getting around CSS style conflicts.  A lot of times, widgets created by framework developers will rely on custom style sheets to style their UI elements.  Since I’m old fashioned and like to code my own style sheets, it can be very frustrating when a framework’s style sheet overrides some of my own styles elsewhere on the page.

To get around this in ExtJS, you have to use the “scoped” stylesheet that ships with ExtJS and do a little footwork with the JavaScript:

<head>
    <link rel="stylesheet" href="js/libs/ext/4.0.2a/resources/css/ext-all-scoped.css">
    ...

This style sheet will only apply ExtJS’s styling to elements that are inside an element with the class x-reset.  That’s great but what isn’t clear is that once you load ext-all.js, it will automatically apply that x-reset class to the html element. To get around this you’ll need to tell the Ext object not to apply this class by actually defining the Ext object before it’s created by the ExtJS code itself:

    ...
    <script>
        // Here we define Ext for the first time
        Ext = {
            buildSettings:{
                "scopeResetCSS": true  // Thanks, but I'll do my own scoping please
            }
        };
    </script>
    <script src="js/libs/ext/4.0.2a/ext-all-debug.js"></script>
</body>

When Ext loads, it actually looks to see if an Ext object has already been defined and if so, treats its values like a config object.  So by setting the buildSettings value before Ext loads you are telling the future Ext object that you’re going to handle scoping the CSS yourself and it can just chill out—go have a Coke or something.

From time to time at work, I feel like the only person in the world who doesn’t have a big soft spot in their heart for ExtJS.  Each time it’s vaunted as the Swiss Army Knife of UI development I can’t help but object.  I will say that ExtJS is a top-notch library with tons of amazing features, but what I take issue with is when it’s implemented as a replacement for traditional UI design and markup.

When you are writing your UI entirely in JavaScript, something is wrong.  Not only are you pushing the browser to generate a daunting amount of HTML through code, you’re also completely depending on JavaScript for anything to work on your site.  It’s Progressive Enhancement cryptonite.

To be fair, there are some reasons why you might use ExtJS for your UI:  You can get projects up and running much faster and in some groups where there isn’t a strong designer you can actually improve the consistency and look and feel of your applications.  Outside of these scenarios, I much prefer libraries like jQuery that focus on building upon the existing markup of the page rather than writing the markup for the page.

In PHP, there are two broad ways you can solve most complex problems.  The first is to “hack” away at the code until you’ve finally crafted a gigantic mass of mangled loops and if statements that ultimately produce the results you’re looking for.  The second, is to hack together code in smaller, self-contained units.  These units may be functions, they may be classes, or they may be programming frameworks.  Obviously, my preference is the latter. Yet in my time I’ve been guilty of more than one mangled briar patch of bemusing control structures.

Now, I know the concept of using functions and classes isn’t ground-breaking to anyone but what I’m talking about is a little more than just using them—it’s using them correctly, or at least more correctly. To put this another way: it is always better to solve a problem by combining many simple solutions, than employing any one catch-all solution no matter how clever it may be. This is true of code and, I would argue, of most problems in general.

They key to this approach is being able to develop an effective strategy for whittling a problem down into manageable chunks.  You could write functions until your blue in the face and still not be any closer to an efficient solution.  To be more precise, here are a couple strategies you might employ to streamline your code into a simpler form:

  1. Never copy and paste blocks of code
    If you find yourself doing this, stop.  You’ll probably need this code again later on too right?  Try moving it to a function.
  2. Beware of loops
    If you find yourself using a loop structure, especially one that spans more than 10 lines, you might consider moving your loop to a separate function.  A loop is a tell-tale sign that you have a tricky problem you are trying to work your way through.
  3. Database queries
    9 times out of 10, if you have a database query rubbing elbows with the rest of your business logic, that sucker should get booted out to a function.  Abstracting any and all database queries inside simple functions gives you the ability to completely change the way you’re generating that particular subset of data in the future.  Freeing you up to employ whatever clever caching mechanism you’d like down the line.

What tips do you have for simplifying your code?

A common problem in complex database systems is an over-abundance of tables, columns, procedures, functions, and the databases that hold them.  Trying to figure out the right columns to use in that reporting query your boss wants by the end of the day can get just a little overwhelming.  Thankfully, there is an easy way to drill down into the structure of your database so you can find just what you’re looking for.

Behold, your information_schema database… The information_schema database is a special database that MySQL uses to keep track of its own internal plumbling.  It holds meta information on every field, column, table, and database on your MySQL server.  For this reason you must treat this database like royalty.  No inserting, updating, or deleting anything unless you want to have to rebuild all your tables.  That said, running selects is harmless enough and if you keep it to that you should be just fine.

Searching For a Column

Here’s a quick way to search for columns in any database by column name:

-- Search for column name containing "bar"
SELECT *
FROM information_schema.COLUMNS
WHERE
COLUMN_NAME LIKE '%bar%';

Searching For a Table

Need to narrow it down? Search by column name and table name.

-- Search only in tables beginning with "foo" for columns with "bar" in it
SELECT *
FROM information_schema.COLUMNS
WHERE
COLUMN_NAME LIKE '%bar%' AND
TABLE_NAME LIKE 'foo%';

Find Columns Used in Stored Procedures or Triggers

Being able to quickly track down all the places a given column can be updated in your database is extremely useful when it comes time to hunt down an illusive bug. Here’s how you can quickly narrow your search to only the stored procedures, functions, and triggers that actually mention your column somewhere in their code:


-- Search all stored procedures and functions for "foobar_column"
SELECT *
FROM information_schema.ROUTINES
WHERE
ROUTINE_DEFINITION LIKE '%foobar_column%';

-- Search all triggers for "foobar_column"
SELECT *
FROM information_schema.TRIGGERS
WHERE
ACTION_STATEMENT LIKE '%foobar_column%';

There’s a whole bunch of other tables to play with in the information_schema table, so dig in… but remember look, don’t touch.

We’ve all seen them, links that look like they go somewhere but when you roll your mouse over them you see something like “javascript:popupWindow();” in the status bar instead of a URL. Putting JavaScript into the href of links is just a horrible idea as it severely degrades the accessibility of your site (and ticks off people like me who want to see where they’re about to be taken before they click). But rather than just complain about it, I thought I’d put together some code to help us all avoid this situation all together.

The ideal solution is one that will work for the greatest number of users. Given that, we need a solution that will use unobtrusive JavaScript to enhance a standard HTML page with customizable popup windows—rather than rely solely on JavaScript. Since straight-up HTML supports opening links in new windows by adding a target attribute to the link, we start off with a link that looks like this:

<a href="/popup.html" target="popupWindow" class="popup">Open new window</a>

Using this as a starting point, the next step is to create a simple popup window function that wraps the standard DOM method: window.open().  I use this function to do a few things:

  1. Enforce default parameters rather than depend on the browser’s defaults
  2. Provide defaults that favor greater accessibility, ie: scrollbars and resize
  3. Allow a JavaScript object literal to be used instead of the standard configuration string

Here’s the function:

// Create a namespace for our utilities
var UTIL = UTIL || {};
UTIL.popup = UTIL.popup || {};

/**
 * Open popup window
 *
 * Opens a popup window using as little as a URL. An optional params object can
 * be passed.
 *
 * @param {String} href
 * @param {Object} params
 * @return {WindowObjectReference}
 */
UTIL.popup.open = function (href, params) {
	// Defaults (don't leave it to the browser)
	var defaultParams = {
		"width":       "800",   // Window width
		"height":      "600",   // Window height
		"top":         "0",     // Y offset (in pixels) from top of screen
		"left":        "0",     // X offset (in pixels) from left side of screen
		"directories": "no",    // Show directories/Links bar?
		"location":    "no",    // Show location/address bar?
		"resizeable":  "yes",   // Make the window resizable?
		"menubar":     "no",    // Show the menu bar?
		"toolbar":     "no",    // Show the tool (Back button etc.) bar?
		"scrollbars":  "yes",   // Show scrollbars?
		"status":      "no"     // Show the status bar?
	};

	var windowName = params["windowName"] || "new_window";

	var i, useParams = "";

	// Override defaults with custom values while we construct the params string
	for (i in defaultParams) {
		useParams += (useParams === "") ? "" : ",";
		useParams += i + "=";
		useParams += params[i] || defaultParams[i];
	}

	return window.open(href, windowName, useParams);
};

Admittedly, this part isn’t rocket science and could probably be done in a more elegant way, but it’s needed to really open things up for the next part.  Now we get to the fun stuff.  Using jQuery, we search the document for all links that have a CSS class of “popup”.  For each one we find, we add an onClick handlerthat disables the browser’s default onClick behavior for links and then opens up a popup window using the links href attribute.  Here’s the code:

$(function(){ // Run this code when the document's done loading

    // Apply this code to each link with class="popup"
    $("a.popup").each(function (i){

        // Add an onClick behavior to this link
        $(this).click(function(event) {

            // Prevent the browser's default onClick handler
            event.preventDefault();

            // Grab parameters using jQuery's data() method
            var params = $(this).data("popup") || {};

            // Use the target attribute as the window name
            if ($(this).attr("target")) {
               params.windowName = $(this).attr("target");
            }

            // Pop up the window
            var windowObject = UTIL.popup.open(this.href, params);

            // Save the window object for other code to use
            $(this).data("windowObject", windowObject);
        });
    });
});

One of the great features of jQuery that we utilize here is the data method.  This allows us to attach data to DOM elements without corrupting the HTML with non-standard attributes or tags.  Using jQuery’s ability to locate DOM elements using CSS selectors, we can bind the custom configuration object (used in our new popup function) to the links themselves.  Then, when a link is clicked, it can read it’s popup configuration and pass it to the popup window function.  In this way, we can keep our HTML standards compliant and completely separate from our JavaScript code.

Putting it all together, we can create an HTML page like this:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
		<title>Popup Window Test</title>
		<script type="text/javascript" src="jquery-1.2.6.pack.js"></script>
		<script type="text/javascript" src="utils.js"></script>
	</head>
	<body>
		<ul>
			<li>
				This link uses defaults:
				<a href="http://google.com" target="google" class="popup">Google.com</a>
			</li>
			<li>
				This link uses custom parameters:
				<a id="custom-popup" href="http://yahoo.com" target="yahoo" class="popup">Yahoo.com</a>
			</li>
		</ul>
		<script type="text/javascript">

			// Add custom pop-up properties to the second link
			$("a#custom-popup").data("popup", {width:400,height:400, top:200, left:200});

		</script>
	</body>
</html>

If you would like to download this example, you can get it here.

Most internet services are valuable to us because they can add value to our personal information. Google can deliver more relevant search results by monitoring which search results we click on and then tailoring future results to our preferences. FaceBook asks us for some personal information like geographic location and our immediate network of friends, in return they let us connect with new friends and contacts that we wouldn’t have found otherwise. In both cases, these companies are using our personal information to provide a service we find beneficial.

What concerns most people is what else companies do with our information when we’re not using it. Do they use it to spam our friends? Do they monitor our internet behavior and share it with other companies? In truth, most people don’t mind companies keeping track of our data for us—but when they try to monetize that data we begin to feel uncomfortable.

Whenever companies distribute software, as the owner of software, they can place strict legal limitations on what can be done with it. They can say who can use it, in what way, and for how long. Why can’t we, the consumer, place the same limitations on our own information that we let companies use? We should be setting the terms upon which they use our data.

It’s a bit of a role reversal that might take some getting used to but, when it comes to social media, the consumer’s data is the real currency companies value. Why should we have to read a 50-page TOS that tells us how the company is going to use our data? It’s ours.

I would love to see an organization like Creative Commons come out with a personal profile license that companies have to adhere to. There could be a couple flavors, letting us pick the types of activities we’re comfortable with. Maybe we don’t mind our consumer behavior being tracked. (You could get better ads that way.) Maybe we’re cool with email blasts. (Coupons in your inbox?) Or maybe we’re like Steve Gibson and would just assume the company not even be able to decrypt our data on their own servers.

I’m sure this would be a huge pain for companies to keep track of—especially if the number of profile licenses in the wild got above 4 or 5. But companies could tell us to take a hike if they don’t like the type of profile license we’ve chosen. That’s fine with me. There are other fish in the sea. At least this way everything’s up front and both parties know what they’re getting into.

It’s our data. They want to make money off of it. It’s about time we set some terms of use.

Update: With the release of Zend_Layout, the need to this sort of workaround has diminished.

It’s no secret that I’m a big fan of the Zend Framework. After fumbling around with a primitive MVC application at work, I was instantly won over by the clean, and intuitive way they implement MVC. Round about version 0.9, the ViewRenderer was introduced. ViewRenderer is, I’d say, 90% useful. It makes certain assumptions about the way you’re using the framework. If you color between the lines it’s a great help.

One thing I almost always have to do is override the way it selects and automatically renders templates based on controller and action names. I typically roll with a single template and load elements into that template. Of course, I could just disable ViewRenderer altogether, but it does do a lot of other things that I find helpful, like initializing the View.

My solution: extend the default Zend_Controller_Action class. There’s only a few things to do:

  1. Disable the auto-render functionality of ViewRenderer
  2. Add a new $_template property to hold the template to render
  3. Render a single template in the postDispatch method

Here’s the code:

require_once "Zend/Controller/Action.php";

class Blink_Controller_Action extends Zend_Controller_Action
{
    protected $_template = "defaultTemplate.phtml";

    public function init()
    {
        $this->_helper->viewRenderer->setNoRender(true);
        parent::init();
    }

    public function postDispatch()
    {
        echo $this->view->render($this->_template);
    }
}

With our new controller action, we can then largely forget about rendering the View. All we have to do is assign values to the View:

require_once "Blink/Controller/Action.php";

class MyController extends Blink_Controller_Action
{
    public function IndexAction ()
    {
        $this->view->myValue = "some value";
        // Assign more values...
        // Do business logic...

        // Optionally, select a new template to render
        $this->_template = "differentTemplate.phtml";
    }
}
Posted in php | 3 Comments »

© 2012 Donald J. Sipe III | Powered by WordPress | RSS Feed