Programming | Chris Page

Inject jQuery on any website

Feb 20

I spent some time Googling around for javascript injection techniques, and stumbled on a neat little bookmarklet that allows you to inject jQuery into any website, and then use the FireBug console to play around with the page. In addition to how much fun this is, having the smooth jQuery syntax at your fingertips mixed in with FireBug is a great debugging technique for developers.

Many kudos goes to Karl Swedberg for posting his bookmarklet and technique at

Go check it out!

Firefox Inspect Element

May 08

I’d like to write up a bit more on this at a later time, but moving quickly.. a quick way to inspect an element on the DOM is to use Firefox’s Inspect Element tool. It’s very handy for quickly figuring out the CSS selectors and attributes belonging to an element on the page, as well as checking for value changes when working with a dynamic page.

Try it out!

Right click an element and choose Inspect Element

Useful information at a click!

Features, Quality, Speed – Choosing Technology

Apr 24

A few years ago, I put out a series of articles on tech forums describing some of my thoughts on building social networks, and choosing the best technology. I made some comparisons between Rails, Django, and PHP Frameworks, off the shelf CMS like Drupal or WordPress. Not all statements, I would say were accurate at the time ( I may be jaded from bad experiences ), or even today – but the general idea was in the right place.

A few years have gone by ( too fast ), and many of my philosophies have, hopefully matured, changed a little. I tend to slander technologies less, for starters, unless your Drupal, and do more looking at the problem domain and explore what technology can elegantly solve for to get me there, instead of brute forcing my favorite technology and hoping it will keep me there.

Tonight, I received an email from a fellow startup enthusiast, Michael, seeking some further thought on the matter, as he is embarking on a project. After editing my response to him, over and over, I decided, it was worth sharing.

Michael, in his quest to choose the best technology for the job, was stuck between choosing an off the shelf solution, BuddyPress or going completely custom from scratch with CodeIgniter (CI) to build a social network. BuddyPress didn’t quite have all the features he wanted, but did have some, and CI, of course, would be a mostly from scratch endeavor.

Michael stumbled upon one of my notes on the CI forums, and sent me an email asking “How does he choose which will be best?”

My response:

Hi Michael,

Thanks for reaching out to me. I have to say, I’ve received a lot of feedback on my thoughts about this, and I will first admit, I wrote that note on the CI forums several years ago, if I were to write it again, I think I could do you one better. However, I think a lot of the motivation behind it still holds true in my experience, so let me give you some of my thoughts from today, and you will have to task yourself in choosing which specific technology meets your requirement.

Lets spark some thoughts:

  • Are you hiring a team or programming yourself?
  • What types of resources do you have available to achieve a finished product ( either that be your own graphics and programming skill, friends helping, a hired team, skill level, experience ).
  • What type of timeline are you looking at?
  • If you have a hired team, do you have the budget and buffer for when things don’t come out the way you expected? Going custom can have it’s unexpected draw backs and expenditure, while an off the shelf solution might get you to market faster at the cost of not being “quite” what you want in the big picture.

All Code is Throw Away

“All code is throw away” – Peter Meulbroek. A dear friend of mine, mentor, and also former boss, taught me this concept over the course of about 3 years. It’s one of my biggest take aways from working closely with him.

Be ready to try again. To not get it quite right. To give a little, so you can take a little more.

Often, the best thing you can do, is build a beta or prototype. See if it catches. Don’t spend all your resources in one basket and hope it’s the next best thing. If you can get a prototype, you can gauge what to do to sustain, maybe pursue further investment, or decide to throw it out! Going with an off the shelf solution is often a “fast” way to go and provides this sort of testing ground with low expense. Then when the concept is proven, rewrite it on a more customizable platform with all those features you dream of, ramp up infrastructure, resources, budget, etc.

I’ve rewritten entire projects with tens of thousands of lines of code, in different technologies, languages, platforms, you name it, in some cases, 3-4 times in a year. Some of the reasons generally being:

  • the requirements evolved
  • the budget increased or decreased
  • we pulled and added features that we found more or less important
  • users hated it and nobody used it
  • users loved it so much we hit a technical wall or limitation
  • overhead was not worth investment for particular features

Famous Last Words

Think about these items, and then ask yourself what is important to you in this first iteration ( attention to the word “first” ):

  1. Features
  2. Quality
  3. Speed

Take a combination of 2, and choose which framework/platform gets you that. Then, be prepared to change your mind, evolve, and throw away a little code ( or all of it sometimes ) in favor of what gets you to the big picture in the end.

Your fellow startup enthusiast,

Chris Page – Jobs for Programmers

Mar 08
Jobs for Programmers

Jobs for Programmers

Two colleagues out of St Louis, Josh Anyan, and Chris DeGroat, recently created – a website for matching up tech industry jobs with candidates. They gave me a heads up, and I was pretty impressed – as I generally am by these two. I thought I’d give them a call out on my site in hopes to send them what little traffic I can muster. Here is a review: aims to be low friction, my entire experience on the site was just a few minutes, here are some highlights:

  1. The login system is all via the linkedIn API ( how suitable ). This makes it super easy to sign up, and connect with the most relevant professional social network out there – NOT your facebook.
  2. You’re immediately asked a few questions about locale, skillsets, salary ranges that interest you.
  3. Next, your taken to a listing of matching jobs – where you can pick and choose what interests you and go from there.
  4. As new jobs that match your skills come into the system, you are notified. This is a nice way to keep a pulse on opportunities, without throwing your resume on the market. launched a few days ago and is currently in beta. If you’re a recruiter or employer, head on over and toss up a few job postings. It’s free! If you’re a techie, might as well sign up – it’s pretty frictionless, and you never know where you’ll find the next big thing.

For the record: Chris DeGroat and Josh Anyan are rockstar developers, they knocked this product out in just a couple short weeks. Keep tabs on these guys.

Nice work gentlemen.

AdKeeper to Launch

Nov 22

AdKeeper's latest product,

As you many of you already know, I’m a proud member of the AdKeeper team. We’ve been laying a little low for a few months, and here’s part of the reason: We’re launching a new product,!

For an explanation, I’ve decided to simply quote our CEO ( with permission, of course ), as he wrote it best in an email earlier today:

Not a change of course/emphasis – but something new/incremental. We’re very happy with the core biz.

Since we began beta in Feb. we’ve rolled out 10+ Billion buttons across the web. Making this tech easy and seamless was the first order of business – and you may have noticed our deal with Safecount last week that now lets us take a single line of code and drop it into ad tags with partners. This is the beginning of spreading buttons wider and is very exciting. We very much believe Keep buttons will be on “all” ads.

We now not only have the biggest, best group of advertisers for a new media property, ever… we’re certified on every web site in the world and now we make ad tagging/ops way easier. Eric Schmidt’s recent comment about how hard it is to do ad tech resonates with all of us.

And, to top it off – fresh research shows that 23% of users feel better about a brand just seeing the button that let’s them “Keep ad for later”… and we’re getting 50x clicks and 20x view time on Kept ads. That’s the button side of things.

On the destination front (which is where plays), some of our guys fell in love with a tweaked metaphor for deeper engagement with Brands. I told them to have at… our version of Google’s 20% “do what you want program.”

I liked what they’re doing so much that I gave them one of our fun parked URL’s… We’ll be working it for a bit before going wide – but needed to start getting some folks in to kick the tires… thus the proverbial velvet rope. Sign up… maybe we’ll let you in 🙂

— Scott Kurnit, AdKeeper CEO

All of that stated, if you’re interested in checking out the new product the day it launches ( very soon ), sign up at our launch page and… maybe we’ll let you in 🙂

Happy Keeping!

AdKeeper Raises $35 million in second round funding!

Jan 03

I joined AdKeeper several months ago – it’s so far been a blast, and has really nailed the startup-junkie sweet spot in me! With a press announcement today, it just got a lot more interesting…

As we pound out our goals and deadlines on the code-front, where I dwell, the rest of the company has been hard at work refining the vision and pushing the marketing. Today we announced our second round funding, a whopping $35 million, led by Oak Investment Partners – bringing the total raised to $43 million.

So, I get this question alot, in fact, my sister just asked me last night: “What are you guys building, Chris?”. Lets save your eyes, and give you a fun video this time:

By the way, my sister’s response via phone was “I save ads all the time, I just usually book mark them and look for them later, but this makes it easier – I really think people will use this”. I feel the same way!

You can also find out more at

You can also watch more videos (Q&As, fun commercials, and more) at our YouTube channel:

PHP Namespace Tutorial

Oct 16
[ad name=”Google Adsense-3″]


Namespaces have been around for years in other languages, but only as of PHP 5.3 have PHP developers been so fortunate. So, what is a namespace in PHP? In short, it’s an abstract container that allows us to re-use same function, class, and constant names but apply different meanings based on what context they are in. That’s a mouthful, huh?

Lets take a look at a small code snippet, and then we’ll break down and expand upon what’s going on in small, chewable increments:


namespace Foo;

function Bar()
    echo __NAMESPACE__;

namespace FooFoo;

function Bar()
    echo "Bar";

echo \Foo\Bar();



There are a few points of interest here:

  • The namespace keyword
  • The __NAMESPACE__ constant
  • Redefinition of the Bar() function
  • The strange new syntax in the echo statement at the end: name resolution

The namespace Keyword

Namespaces are named arbitrarily and have two syntax forms. Note, in either syntax, namespaces cannot be nested; although, sub-namespaces can be defined ( explained later ).

Syntax 1:
namespace Foo

//...code here...
Syntax 2 – Block form:
namespace Foo 
    //...code here...
Secondary Usage

The namespace keyword also has a secondary usage, which is to act as an explicit reference to the current namespace, similar to the self:: keyword used in classes. Example:


namespace Foo;

class Foo
    public function __construct()
        echo __NAMESPACE__;

namespace Bar;

class Foo
    public function __construct()
        echo __NAMESPACE__;

$object = new namespace\Foo();



The __NAMESPACE__ Constant

The __NAMESPACE__ magic constant contains a string that outputs the current namespace. When called from the global context, an empty string is output. You may find it useful for dynamically constructing variable and class names, to error reporting.

Name Resolution

Name resolution refers to how namespaces find your classes, functions, and constants based on a few definitions and rules. Depending on the syntax you use, import rules, and existence in the current namespace, name resolution can change the behavior of your code – so be familiar with the rules.

Some definitions:

Unqualified Names

Unqualified names have no reference to a namespace. Example:


At run time, if within a namespace and a call to an unqualified function occurs, the namespace is first checked, if the function is not found, the global scope is then checked for that function.

For class names, the class is looked for in the current namespace, autoload is then called on that class.

Qualified Names

Qualified names have a namespace separator included, and are translated during compile time based on the current import rules, Example:


Fully Qualified Names

Fully qualified names (FQN) start with a namespace separator, and are explicit references to a namespace that cannot be effected by import rules. FQNs are resolved at compile time. Example:


Sub Namespaces

[coming soon…]

Namespace Aliases

[coming soon…]

Importing Namespaces

[coming soon…]

Autoloading Namespaced Classes

[coming soon…]


Without Namespaces

Previous to namespaces in PHP, the common alternative to control context was through careful conventions in file system structure + long class names, ie:


class Framework_DB


class Framework_DB_MySQL extends Framework_DB


class Application_DB

Rewritten Using Namespaces

While the filesystem structure convention is still a recommended practice for organization, the contents of the files can be defined more concisely using namespaces:


namespace Framework\DB;

class DB


namespace Framework\DB;

class MySQL extends DB


namespace Application;

class DB

I’m anxious to see how the introduction of namespaces in PHP 5.3 changes software everywhere! Happy Coding!

Apache Low Memory Settings + PHP + APC

Apr 03

In addition to moving my servers to save costs, I ran into a two part issue that I lumped into: “I need to tune memory usage a bit”.

Part 1: Apache

Since I moved my Apache servers to lower memory instances, I was running into swap space usage that I could easily avoid, ie:

free -m
                      total       used       free     shared    buffers     cached
Mem:               268        245         22          0         71         53
-/+ buffers/cache:        120        147
Swap:               511         29        482

Some of the reasoning behind this was that, by default, Apache expects a bit more memory to be available than what I provided to it in the move. The fix was to introduce a few settings to lower child processes and limit concurrent connections to something more reasonable to the type of traffic my site really gets – which is near nothing most days.

The settings I dropped into apache were:


    #Low Memory Settings
    StartServers 1
    MinSpareServers 4
    MaxSpareServers 2
    ServerLimit 6
    MaxClients 6
    MaxRequestsPerChild 3000

I made the adjustments, cleared out the swap space with:

swapoff -a
swapon -a

Then restarted apache:

/etc/init.d/apache2 stop
/etc/init.d/apache2 start

And all was well in the world.

free -m
                       total       used       free     shared    buffers     cached
Mem:                268        207         60          0         31         79
-/+ buffers/cache:           97        170
Swap:                 511          0        511

Part 2-1: PHP

A bit simpler, my blog site was running into max memory allocation limits. I had left the default php.ini in place in the upgrade, so I needed to do a once over of configs and change memory_limit from 16M to something more reasonable for my site.


memory_limit = 64M      ; Maximum amount of memory a script may consume (16MB)

Part 2-2: APC

Having Apache settings set for lower memory usage also allowed me more room to increase my APC cache limit a bit higher to keep more pages faster. From 30 MB to 50 MB.


Other obvious solutions in consideration, switch to Rackspace to invert my memory/cpu requirement/cost ratios. Any other tips are welcome 🙂

Mysql: Force Localhost to Use TCP, Not a Unix Socket File

Apr 03

So, recently I decided I was paying too much for my server because I was not maximizing performance across all the various daemons. So I decided to split my larger server into a handful of smaller servers to be able to fine tune each one to dedicated purposes. All went well, but I had some trouble for a few evenings figuring out how I could port forward localhost:3306 to the, now remote, database server. This should have been dirt simple with an iptables rule – but after digging in, I discovered MySQL treats localhost “special” by sending connections through the unix socket file, which is absolutely faster, but only works if the database daemon is on the same host as the connecting application.

After doing some research, I found it is possible to use a tool like socat and autossh to wrap an ssh tunnel to forward connections through the socket file to a remote IP over TCP. This however, was more complex and one off than I cared to explore for my simple problem. I finally resorted to using DNS and to stop using localhost as the host name. However, a few tid bits for the weary traveler:

  • The mysql client library is responsible for selecting the protocol.
  • PHP’s internal mysql libraries, unfortunately, as far as I could discover ( please correct me if I am wrong here ), do not allow you to select the protocol.
  • So if you’re using “localhost” as your host name in a PHP mysql_connect, you’re forced to go through the socket file, however, you can use instead of localhost to force TCP.
  • The linux mysql-client package command line tool offers a –protocol=tcp flag if you want to force TCP. You can also set this as a default inside /etc/mysql/my.cnf under the [client] heading


port            = 3306
socket          = /var/run/mysqld/mysqld.sock
protocol        = TCP

Again, this appears to work fine if you’re not using PHP as your client.

I hope this lesson learned ( use DNS ) comes as a helping hand to others out there. If anybody has some other suggestions, please do leave a comment!

Simple Performance Testing with Apache Benchmark

Jan 03
[ad name=”Google Adsense-3″]

I’ve been knee deep in performance and scalability for some time now, and have used and learned of many useful tools and techniques to help out. One of my favorite command line tools for seeing how well a single Apache server is churning out pages in development comes stock on Ubuntu, and Mac OS X: Apache Benchmark.

A simple performance test against the homepage of one of my client site’s using AB at the command line:

ab -t5 -n100

The results:

This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd,
Licensed to The Apache Software Foundation,

Benchmarking (be patient)
Finished 664 requests

Server Software:        Apache/2.2.8
Server Hostname:
Server Port:            80

Document Path:          /
Document Length:        306 bytes

Concurrency Level:      100
Time taken for tests:   5.054 seconds
Complete requests:      664
Failed requests:        0
Write errors:           0
Total transferred:      465003 bytes
HTML transferred:       205326 bytes
Requests per second:    131.38 [#/sec] (mean)
Time per request:       761.143 [ms] (mean)
Time per request:       7.611 [ms] (mean, across all concurrent requests)
Transfer rate:          89.85 [Kbytes/sec] received

Connection Times (ms)
min  mean[+/-sd] median   max
Connect:       38   78  48.7     64     994
Processing:   114  540 226.2    493    1690
Waiting:      114  531 205.6    493    1485
Total:        191  618 236.0    558    1808

Percentage of the requests served within a certain time (ms)
50%    558
66%    587
75%    598
80%    617
90%    845
95%   1163
98%   1402
99%   1746
100%   1808 (longest request)

There is quite a bit of useful information here that can help you tune your code and server. It’s important to note however, that when working on a larger site, that expects quite a bit more traffic, you might want to investigate some more thorough solutions outside of just a single machine and ab. It is, however, a nice starting point into useful information.

[ad name=”Google Adsense-2″]

One rather funny pitfall you can run into however, is if the host you are sending requests to is smartly secured – these types of tests become a bit useless, as they may have security settings to limit or delay requests – providing you with timeouts and/or inaccurate information. Best to run these types of things in a semi-developmental mode with those types of security settings turned down, and rely on bigger guns or fleets of boxes and scripts to hit a production secure site.

In addition to hitting just a landing page, you can use AB to send COOKIE or POST data too! This is very useful if you want to see how pages perform but need credentials to get in first. This is a little trickier to do using the -c, -T, -p, and -v flags. I noticed there are under-useful resources online to figuring it out with AB, so it would seem worthwhile to write it – as it took me some trickery to figuring it out as well:

Sending POST data to a login form:

First we create a file that contains our URL encoded post data. Note, AB expects the values to be URL encoded, but not the equal (=) or ampersands (&).


Capturing a cookie:

Here, we use the verbosity (-v) flag so we can see the response headers that come back — many sites will send back a cookie once authenticated, we’ll want to capture that cookie here. Though, some sites will not require it, I demonstrate it for the sake of example:

ab -v4 -n1 -T 'application/x-www-form-urlencoded' -p post_data.txt

The returned response header will fly by quick, you’re looking for something like the following:

Set-cookie somesession=somerandomsessiondata...;

The session data may come back encrypted, unencrypted, a serialization, or just a number. That varies by site. The point here is you have a key/value pair for the cookie. All you need is the part up to the semi-colon ( not including the semi-colon ). Copy that “key=val” string, and use it when hitting other pages on the site you are testing, ie:

Using a cookie to test a page that requires a cookie:

ab -t10 -n100 -c 'somessession=somerandomsessiondata'

This can become a lot of fun once you get the hang of it. Now you have the know how, go enjoy creating an arsenal of these scripts and start performance tuning your sites – or script hacking your favorite social network ( or obnoxious Blizzard clan website hahaha… drum roll for D3 – 2010? Please???! ).