1. PHP Community Conference

    I was once told that "the only reason you're successful is that you were at the right place at the right time." Other than the word "only" in that declaration, the accuser was mostly right. The reason I'm [moderately] successful is that I was at the right place at the right time. The subtlety in the second statement is in the reason I was at the right place at the magical time.

    I firmly believe that my technical skills are only part of my value, career-wise. Looking back on my career so far, I can definitely see opportunities that arose because of being at the right place. What wasn't considered in the flippant statement was why I was there, when I was.

    To me, it's clear: I've taken measures to put myself in the right place, when it was beneficial to do so. I've been doing this for years, and it's paid off.

    Want to know how I became the Editor-in-Chief of php|architect magazine, a Web Architect at OmniTI, and was put into contact with my co-founder for Gimme Bar? Sure, my abilities to build web stuff played into all of those roles, but the way I found myself in all of those positions was by asking. Yes, asking.

    Was I in the right place at the right time when I noticed Marco commenting about having to edit the current issue of php|architect, and I chimed in "hey, I kind of actually like that sort of thing," half a decade ago? Definitely, but it's more complicated than "luck."

    Similarly, when I approached Chris Shiflett about working with OmniTI, his immediate reaction was "Of course there's room on my team for you; we'll just need to work out the details." Am I that good, when it comes to coding, architecting large deployments, and managing a team? Definitely not—even less so back then.

    The real question is why was I hanging out on IRC when Marco was venting, or how was it so easy for me to have Chris's ear? The answer is simple: I'd established myself as part of the PHP community, and had a standing with those guys, even without having ever worked with them, directly (I had written for php|architect before, but it wasn't under Marco's direct supervision).

    I assume that many of you readers are already members of the community in some way. That could be as simple as participating on mailing lists or forums, helping reproduce bugs, or fixing grammatical errors in the manual. One of the best ways I've found to connect with the community, though, is in person.

    Nearly everyone I know and have had a long-term relationship with, in the PHP community, I met at a conference. Sure, I'd often "known" someone from their online persona, but it's hard to really "know" someone until you've spent some face time with them, preferably with a beer or two between you.

    This is one of the main reasons that I think that the PHP Community Conference in Nashville, in just about a month, is important, and why I think you should go. I have no personal stake in this (in fact, since it's run by the community, the only stake to be had is a potential loss by the organizers; there is no profit to be had), I just think it's going to be a great event, and a wonderful opportunity for attendees—and not just from a career perspective, but I expect everyone who attends will become more valuable to their current employers, too, based simply on knowledge gained and connections made. (There's a huge amount of value in being able to fire off a friendly email to the author of (e.g.) the memcached extension, when you get stuck, and to already be on a first-name basis.)

    I'm also speaking, there, on Gimme Bar. It won't be a pitch. It will be more of a show-and-tell session on which technologies we use, how we've built what we have so far, what I think we've done right, and a frank discussion on the mistakes we've made (so far (-: ).

    If you can, you should make it to the PHP Community Conference, and be in the right place at the right time, whether it's Nashville on April 21 and 22, or sometime in your future.

  2. Ideas of March

    Around two weeks ago, Chris wrote a blog post that I responded to, and I was reminded of some of the great conversations that helped build our community. Many of these took place on the blogs of the aughts.

    Like Chris, I think we've lost a bit of that. I've seen what feels like hundreds of conversations fly by on Twitter, 140 characters at a time: incomplete thoughts crammed into a package that's simply too small for detailed and deep expression. Don't get me wrong—a stream like Twitter (or maybe not Twitter itself) is valuable for quick thoughts and light conversation, but we often need more than that.

    Thus, like others, I am pledging to do more blogging this year than last, starting now.

    I recently spoke at ConFoo, and I intend to turn my Fifty Things talk into a series of short blog posts. I've also been mulling over a post on how and why we ported Gimme Bar from CouchDB to MongoDB. Those will hopefully pave the way and form a habit and personal culture of blogging. Please feel free to hold me to this intent, and if you have a blog, I hope you'll join this effort of creating a blogging revival (and if you don't yet have a blog, check out Habari).

    See you soon.

  3. Gimme Bar: One Year Old

    Exactly one year ago, today, Gimme Bar was born.

    Gimme Bar has been the focus of my work for that entire time, and I haven't blogged about it (much).

    Ironically (sort of), I've been far too busy working on Gimme Bar to do much writing about Gimme Bar, but I thought it fitting to take a couple minutes to write a few words about it today.

    The elevator pitch for the project goes something like this: Gimme Bar is a personal utility to help you capture and collect interesting things you find in your day-to-day use of the Web.

    I'm admittedly not very good at the pitch, but my colleague (and Gimme Bar's backer) Cameron is, and we released this demo video, yesterday:

    We're in the middle of some huge changes on the technical side that I intend to blog about, and once those are released, I hope to add a lot more active users. If the video makes it sound like something you might be interested in, be sure to sign up for an invitation. We've got some really great stuff coming in the pipeline, too, for existing users.

    I'll post more, soon, I hope.

  4. Post-Advent 2010

    As I write this on Christmas Eve, Chris is putting the finishing touches on PHP Advent 2010.

    A brief search of my site indicates that I haven't actually blogged about PHP Advent since 2007, when I was lucky enough to write the first article. That first year, Chris put the advent articles up on his blog (and we do intend to copy them over to phpadvent.org, eventually). Sensing that Chris had entirely too much work to do, curating, and since we were working together by the time the season came around in 2008, I offered to help with editing and curation—I did, after all know the pain/joy of putting together a magazine.

    Chris took me up on my offer, and he enlisted Jon and Jon to design and build a proper site. We commissioned authors a little too late, but they came through and PHP Advent 2008 was a success.

    By the time 2009 came around, Chris was already deep into preparing to launch Analog, and I'd already announced (internally) that I was moving on to other things. As a result, 2009's Advent was hard. Really hard. We commissioned authors too late, didn't set solid deadlines (as much as we hate deadlines, this sort of date-sensitive project requires them), neglected to dedicate enough time to author herding and editing, and to top it all off, I was headed to Costa Rica for a much-needed vacation, leaving Chris holding the bag for the last five days of 2009's season. Things were so bad at one point, last year, that I took it upon myself to write an article just so that we didn't miss a day. Luckily, we made it through (and by we, I mean Chris, because by the time my flight to San Jose on Dec. 19th came around, I'd had quite enough of Advent for the year).

    If we learned anything from PHP Advent 2009, it was sadly not from the great articles, but instead from our own failures. If we were going to do this again in 2010, we needed to get on it early, and we needed to attack with full-force. I set my calendar to start bugging me in August, but even though I was hassled by its weekly reminders, we found ourselves at the start of November, wrecked from just having organized a conference, and in the middle of two product launches. Despite feeling like we didn't want to have the trouble of Advent again in 2010, neither of us dared say it to the other…at least not in so many words.

    Due only to the abilities and professionalism of our most excellent authors, PHP Advent 2010 was—at least in my opinion—the best year, yet. They wrote wonderful, substantial, punchy articles that informed our readers, and generated significantly more traffic than we've seen in previous years: over 70,000 views, from more than 25,000 unique visitors, so far, and data from past years tells us that these numbers drop slightly starting on the 25th as we cease to post new content, but remain strong into January, with constant, lower traffic and occasional blips throughout the year. The most popular article this year had more than 10,000 views!

    As we post the last article of 2010, I'm encouraged but all of this, and—contrary to how I felt in 2009—am actually looking forward to making PHP Advent even better in 2011.

    Thank you Chris, and thank you authors. Have a wonderful new year.

  5. Remote pbcopy

    I use the command line a lot. I'm sure many of you do, too.

    I find myself often piping things between processes:

    $ cat seancoates.com-access_log \
    > | awk {'print $1'} \
    > | sort \
    > | uniq \
    > | wc -l
    627
    $ # unique IPs

    One particularly useful tool on my Mac is the pbcopy utility, which takes standard input and puts it on the pasteboard (this is known as the "clipboard" on some other systems). Its sister application, pbpaste is also useful (it outputs your pasteboard to standard output when your pasteboard contains data that can be represented in some sort of text form—if you have image data copied, for example, pbpaste yields no output).

    $ cat seancoates.com-access_log \
    > | awk {'print $1'} \
    > | sort \
    > | uniq \
    > | pbcopy
    $ # the list of unique IPs is now on my pasteboard

    I find this particularly useful for getting information from the command line into a GUI application.

    Wouldn't it be even more useful if we could pbcopy from a remote SSH session? Indeed it is useful. Here's how.

    The first thing you need is a listener on your local machine. Luckily, Apple has provided us with launchd and its administration utility, launchctl. This is basically [x]inetd for your Mac (plus a bunch of other potentially great stuff that I simply don't understand). Put the following in ~/Library/LaunchAgents/pbcopy.plist:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
         <key>Label</key>
         <string>localhost.pbcopy</string>
         <key>ProgramArguments</key>
         <array>
             <string>/usr/bin/pbcopy</string>
         </array>
         <key>inetdCompatibility</key>
         <dict>
              <key>Wait</key>
              <false/>
         </dict>
         <key>Sockets</key>
         <dict>
              <key>Listeners</key>
                   <dict>
                        <key>SockServiceName</key>
                        <string>2224</string>
                        <key>SockNodeName</key>
                        <string>127.0.0.1</string>
                   </dict>
         </dict>
    </dict>
    </plist>

    …then, run: launchctl load ~/Library/LaunchAgents/pbcopy.plist

    This sets up a listener on localhost (127.0.0.1) port 2224, and sends any data received on this socket to /usr/bin/pbcopy. You can try it with telnet:

    $ telnet 127.0.0.1 2224
    Trying 127.0.0.1...
    Connected to localhost.
    Escape character is '^]'.
    hello
    ^]
    telnet> ^D
    Connection closed.

    …then try pasting. You should have hello (followed by a newline) on your pasteboard.

    The next step is tying this into SSH. Add RemoteForward 2224 127.0.0.1:2224 to ~/.ssh/config. This will tell your SSH connections to automatically forward the remote machine's local port 2224 to your local machine, on the same port, over your encrypted SSH tunnel. It's essentially the same thing as adding -R2224:localhost:2224 to your SSH connection command.

    Now you have a listener on your local machine, and a secure tunnel from remote servers to this listener. We need one more piece to tie everything together. Put the following in a file (preferably in your path) on the remote machine(s) where you'd like a pipe-friendly pasteboard:

    cat | nc -q1 localhost 2224

    …I like to put this in ~/bin/pbcopy or /usr/local/bin/pbcopy on servers where I have root. You'll also need to chmod +x this file to make it executable. You'll need the nc executable, which is often available in a package called netcat. This invocation of nc takes standard input and pushes it to localhost on port 2224.

    Now you should have a useful pbcopy on your remote server(s). Be aware, though, that there is no additional security on this port connection. If someone on the remote machine can connect to localhost:2224, they can inject something into your pasteboard. This is usually safe, but you should definitely keep it in mind. Also, if you have multiple users using this technique on the same server, you'll probably want to change the port numbers for each user.

    I use this technique all the time. Now you can too. Hope it's helpful.

    (Note: I'm tagging this PHP and Web because it's likely to overlap with those groups.)