<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
  <channel>
    <title>Blog entries tagged perl :: mwop.net</title>
    <description>Blog entries tagged perl :: mwop.net</description>
    <pubDate>Sun, 24 Jun 2012 21:50:00 -0500</pubDate>
    <generator>Laminas_Feed_Writer 2 (https://getlaminas.org)</generator>
    <link>https://mwop.net/blog/tag/perl</link>
    <atom:link rel="self" type="application/rss+xml" href="https://mwop.net/blog/tag/perl/rss.xml"/>
    <item>
      <title>Automatic deployment with git and gitolite</title>
      <pubDate>Sun, 24 Jun 2012 21:50:00 -0500</pubDate>
      <link>https://mwop.net/blog/2012-06-24-git-deploy.html</link>
      <guid>https://mwop.net/blog/2012-06-24-git-deploy.html</guid>
      <author>contact@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>I read a <a href="http://seancoates.com/blogs/deploy-on-push-from-github">post recently by Sean Coates about deploy on push</a>.
The concept is nothing new: you set up a hook that listens for commits on
specific branches or tags, and it then deploys your site from that revision.</p>
<p>Except I'd not done it myself. This is how I got there.</p>


<p>Sean's approach uses <a href="https://help.github.com/articles/post-receive-hooks">Github webhooks</a>,
which are a fantastic concept. Basically, once your commit completes, Github
will send a JSON-encoded payload to a specific URI. Sean uses this to trigger
an API call to a specific page in his website, which will then trigger a
deployment activity.</p>
<p>Awesome, this should be easy; I already have a deploy script written that I
trigger manually.</p>
<p>One small problem: my site, while in Git, is not on Github. I maintain it on my
own <a href="https://github.com/sitaramc/gitolite">Gitolite</a> repository. Which means I
needed to write my own hooks.</p>
<p>I originally went down the route of using a post-receive hook. However, I had
problems determining what branch the given commit was on, despite a variety of
advice I found on the subject on <a href="http://stackoverflow.com/">StackOverflow</a> and
git mailing lists. I ended up finding a great example using <code>post-update</code>, which
was actually perfect for my needs.</p>
<p>In order to keep the <code>post-update</code> script non-blocking when I commit, I made it
do very little: It simply determines what branch the commit was on, and if it
was the master branch, it touches a specific file on the filesystem and
finishes. The entire hook looks like this:</p>
<pre><code class="language-bash hljs bash" data-lang="bash"><span class="hljs-meta">#!/bin/bash</span>
branch=$(git rev-parse --symbolic --abbrev-ref <span class="hljs-variable">$1</span>)
<span class="hljs-built_in">echo</span> <span class="hljs-string">"Commit was for branch <span class="hljs-variable">$branch</span>"</span>
<span class="hljs-keyword">if</span> [[ <span class="hljs-string">"<span class="hljs-variable">$branch</span>"</span> == <span class="hljs-string">"master"</span> ]];<span class="hljs-keyword">then</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"Preparing to deploy"</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"1"</span> &gt; /var/<span class="hljs-built_in">local</span>/mwop.net.update
<span class="hljs-keyword">fi</span>
</code></pre>
<p>Now I needed something to detect such a push, and act on it.</p>
<p>I considered using cron for this; it'd be relatively easy to have it fire up
once a minute, and simply act on it. But I decided instead to write a simple
little daemon using perl. Perl daemons are trivially easy to write, and if you
use module such as <code>Proc::Daemon</code> and follow a few trivial defensive coding
practices, you can keep memory leaks contained (or at least minimal). Besides,
it gave me a chance to dust off my perl chops.</p>
<p>I decided I'd have it check for the file in 30 second intervals, simply
sleeping if no changes were detected. If the file was found, however, it should
attempt to deploy. Additionally, I wanted it to quit if it was unable to remove
the file (as this could lead to multiple deploy attempts), and log success and
failure status of the deploy. The full script looks like this:</p>
<pre><code class="language-perl hljs perl" data-lang="perl"><span class="hljs-comment">#!/usr/bin/perl</span>
<span class="hljs-keyword">use</span> strict;
<span class="hljs-keyword">use</span> warnings;
<span class="hljs-keyword">use</span> Proc::Daemon;

Proc::Daemon::Init;

<span class="hljs-keyword">my</span> $continue = <span class="hljs-number">1</span>;
$SIG<span class="hljs-string">{TERM}</span> = <span class="hljs-function"><span class="hljs-keyword">sub</span> </span>{ $continue = <span class="hljs-number">0</span> };

<span class="hljs-keyword">my</span> $updateFile   = <span class="hljs-string">"/var/local/mwop.net.update"</span>;
<span class="hljs-keyword">my</span> $updateScript = <span class="hljs-string">"/home/matthew/bin/deploy-mwop"</span>;
<span class="hljs-keyword">my</span> $logFile      = <span class="hljs-string">"/var/local/mwop.net-deploy.log"</span>;
<span class="hljs-keyword">while</span> ($continue) {
    <span class="hljs-comment"># 30s intervals between iterations</span>
    <span class="hljs-keyword">sleep</span> <span class="hljs-number">30</span>;

    <span class="hljs-comment"># Check for update file, and restart loop if not found</span>
    <span class="hljs-keyword">unless</span> (-e $updateFile) {
        <span class="hljs-keyword">next</span>;
    }

    <span class="hljs-comment"># Remove update file</span>
    <span class="hljs-keyword">if</span> (!<span class="hljs-keyword">unlink</span>($updateFile)) {
        <span class="hljs-comment"># If unable to unlink, we need to quit</span>
        <span class="hljs-keyword">system</span>(<span class="hljs-string">'echo "'</span> . <span class="hljs-keyword">time</span>() . <span class="hljs-string">': Failed to REMOVE '</span> . $updateFile . <span class="hljs-string">'" &gt;&gt; '</span> . $logFile);
        $continue = <span class="hljs-number">0</span>;
        <span class="hljs-keyword">next</span>;
    }

    <span class="hljs-comment"># Deploy</span>
    <span class="hljs-keyword">system</span>($updateScript);
    <span class="hljs-keyword">if</span> ( $? == -<span class="hljs-number">1</span> ) {
        <span class="hljs-keyword">system</span>(<span class="hljs-string">'echo "'</span> . <span class="hljs-keyword">time</span>() . <span class="hljs-string">': FAILED to deploy: '</span> . $! . <span class="hljs-string">'" &gt;&gt; '</span> .  $logFile);
    } <span class="hljs-keyword">else</span> {
        <span class="hljs-keyword">system</span>(<span class="hljs-string">'echo "'</span> . <span class="hljs-keyword">time</span>() . <span class="hljs-string">': Successfully DEPLOYED" &gt;&gt; '</span> . $logFile);
    }
}
</code></pre>
<p>The <code>system()</code> calls for logging could have been done using Perl, but I didn't
want to deal with additional error handling and file pointers; simply proxying
to the system seemed reasonable and expedient.</p>
<p>When all was ready, I started the above listener, which automatically
daemonizes itself. I then installed the <code>post-update</code> hook into my bare
repository, and tested it out. And it runs! When I push to master, my site is
automatically deployed, typically within 15-20 seconds from completion.</p>
<h4>Caveats</h4>
<p>This solution, of course, relies on a daemonized process. If that process were
to terminate, I'd have no idea until I discovered my site didn't refresh after
the most recent push. Clearly, some sort of monitor checking for the status of
the daemon should be in place.</p>
<p>Also, note that I'm having this update on changes to the master branch; you may
need to adapt it for your own needs, depending on your branching strategy.</p>
<p>Finally, this approach does not address issues that might require a roll-back.
Ideally, the script should probably log what revision was current prior to the
deployment, allowing roll-back to the previous state. Alternately, the
deployment script should create a new clone of the site and swap symlinks to
allow quick roll-back when required.</p>


<div class="h-entry">
    <img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&u=79dd2ea1d4d8855944715d09ee4c86215027fa80&s=140" alt="matthew">
    <a class="u-url u-uid p-name" href="https://mwop.net/blog/2012-06-24-git-deploy.html">Automatic deployment with git and gitolite</a> was originally
    published <time class="dt-published" datetime="2012-06-24T21:50:00-05:00">24 June 2012</time>
    on <a href="https://mwop.net">https://mwop.net</a> by
    <a rel="author" class="p-author" href="https://mwop.net">Matthew Weier O&#039;Phinney</a>.
</div>
]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
    <item>
      <title>Why Conventions Matter</title>
      <pubDate>Wed, 11 Jan 2012 22:58:28 -0600</pubDate>
      <link>https://mwop.net/blog/why-conventions-matter.html</link>
      <guid>https://mwop.net/blog/why-conventions-matter.html</guid>
      <author>contact@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>When I started teaching myself scripting languages, I started with Perl. One
Perl motto is <a href="http://en.wikipedia.org/wiki/TMTOWTDI">&quot;TMTOWTDI&quot;</a> — &quot;There's
More Than One Way To Do It,&quot; and pronounced &quot;tim-toady.&quot; The idea is that
there's likely multiple ways to accomplish the very same thing, and the culture
of the language encourages finding novel ways to do things.</p>
<p>I've seen this principle used everywhere and in just about every programming
situation possible, applied to logical operations, naming conventions,
formatting, and even project structure. Everyone has an opinion on these
topics, and given free rein to implement as they see fit, it's rare that two
developers will come up with the same conventions.</p>
<p>TMTOWTDI is an incredibly freeing and egalitarian principle.</p>
<p>Over the years, however, my love for TMTOWTDI has diminished some. Freeing as
it is, is also a driving force behind having coding standards and conventions —
because when everyone does it their own way, projects become quickly hard to
maintain. Each person finds themselves reformatting code to their own
standards, simply so they can read it and follow its flow.</p>
<p>Additionally, TMTOWTDI can actually be a foe of simple, elegant solutions.</p>
<p>Why do I claim this?</p>


<p>Recently, discussing module structure in Zend Framework 2, some folks were
arguing that our recommended directory structure invokes the
<a href="http://en.wikipedia.org/wiki/YAGNI">YAGNI</a> principle: You Ain't Gonna Need It.
Our recommendation is this:</p>
<pre><code class="language-arduino hljs arduino" data-lang="arduino">ModuleName/
    autoload_classmap.php
    Module.php
    <span class="hljs-built_in">config</span>/
        <span class="hljs-keyword">module</span>.<span class="hljs-built_in">config</span>.php
        (other <span class="hljs-built_in">config</span> files)
    <span class="hljs-keyword">public</span>/
        css/
        images/
        js/
    src/
        ModuleName/
            (source files)
    test/
    view/
</code></pre>
<p>The argument is that since most modules implement a single namespace, and
because we recommend following
<a href="https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md">PSR-0</a>
for autoloaders, it makes sense to simply have the source files directly under
the module directory.</p>
<pre><code class="language-arduino hljs arduino" data-lang="arduino">ModuleName/
    autoload_classmap.php
    Module.php
    (other source files)
    <span class="hljs-built_in">config</span>/
        <span class="hljs-keyword">module</span>.<span class="hljs-built_in">config</span>.php
        (other <span class="hljs-built_in">config</span> files)
    <span class="hljs-keyword">public</span>/
    test/
    view/
</code></pre>
<p>The argument myself and others made was that it makes sense to group the files
by responsibility. However, the module system ultimately <em>doesn't care</em> how you
organize the module — we've embraced TMTOWTDI, and our only requirement is that
for your module to be consumed, you must define a <code>ModuleName\Module</code> class,
and notify the module manager how to find it. Anything goes.</p>
<p>How does that bolster my argument about the importance of conventions? It
doesn't. What does is what following the recommended structure enabled me to
do.</p>
<p>One common concern identified with having a re-usable module system is that you
should be able to expose public assets easily: things like module-specific CSS
or JavaScript, or even images. The first question that arises when you consider
this is: where do I put them in my module? That's why the recommendation
includes a <code>public</code> directory. In fact, the recommendation goes a step further,
and suggests <code>css</code>, <code>images</code>, and <code>js</code> directories as well.</p>
<p>Now, your modules are typically <em>outside</em> the document root. This is a
rudimentary and fundamental security measure, and also simplifies deployment to
a degree — you don't need to worry about telling the web server about what it
<em>shouldn't</em> serve. But if the modules are outside the document root, how can I
expose their public assets?</p>
<p>There are a two possibilities that immediately jump to mind:</p>
<ul>
<li>Install scripts for modules, which copy the files into the document root.</li>
<li>Symlink the files into the document root.</li>
</ul>
<p>Both are valid, and easy to accomplish. Both raise the same question: where,
exactly? What if multiple modules have public assets named the same? how do I
refer to my assets withing things like view scripts?</p>
<p>This is where having a convention starts to make sense: having a convention
should answer these questions unambiguously.</p>
<p>My answer: public access should be at <code>/css/ModuleName/stylesheetname</code>, or
<code>/js/ModuleName/scriptname</code> or <code>/images/Modulename/imagename</code>. It's a
dirt-simple rule that fulfills the use cases.</p>
<p>However, I'm now stuck with having to develop either install scripts or
remembering to create symlinks — ugh. And that's where having conventions led
me to a simple, elegant solution.</p>
<p>I added one line to my Apache vhost definition:</p>
<pre><code class="language-apacheconf hljs apache" data-lang="apacheconf"><span class="hljs-attribute">AliasMatch</span> /(css|js|images)/([^/]+)/(.*) /path/to/module/<span class="hljs-number">$2</span>/public/<span class="hljs-number">$1</span>/<span class="hljs-number">$3</span>
</code></pre>
<p>The translation:</p>
<blockquote>
<p>When I come across a path to CSS, JS, or image files that are in a
subdirectory, alias it to the corresponding public asset of the matched
module directory.</p>
</blockquote>
<p>I dropped this into my vhost, restarted Apache, and now not only were the
assets I'd created already served, but any new ones I create are immediately
available as well. Having a convention actually simplified my choices and my
solutions.</p>
<p>Rapid application development at its finest.</p>
<p>My point is this: there will always be more than one way to do things when
you're programming, and you may not always agree with the decisions your team
has made, or the component library or framework you're using has made. However,
if you poke around a little and play within those confines, you may find that
those decisions make other decisions easier, or disappear altogether.</p>


<div class="h-entry">
    <img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&u=79dd2ea1d4d8855944715d09ee4c86215027fa80&s=140" alt="matthew">
    <a class="u-url u-uid p-name" href="https://mwop.net/blog/why-conventions-matter.html">Why Conventions Matter</a> was originally
    published <time class="dt-published" datetime="2012-01-11T22:58:28-06:00">11 January 2012</time>
    on <a href="https://mwop.net">https://mwop.net</a> by
    <a rel="author" class="p-author" href="https://mwop.net">Matthew Weier O&#039;Phinney</a>.
</div>
]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
    <item>
      <title>Seven Things - Tagged by Keith Casey</title>
      <pubDate>Sun, 04 Jan 2009 16:31:52 -0600</pubDate>
      <link>https://mwop.net/blog/204-Seven-Things-Tagged-by-Keith-Casey.html</link>
      <guid>https://mwop.net/blog/204-Seven-Things-Tagged-by-Keith-Casey.html</guid>
      <author>contact@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>I'm really not sure I understand these &quot;seven things&quot; or &quot;tagged&quot; memes, but I'm going to give it a shot, after <a href="http://caseysoftware.com/blog/seven-things-tagged-by-tony-bibbs">Keith Casey</a> did a drive-by tagging of me on New Year's Eve.</p>
<p>So, without further ado, seven things you may not know about me…</p>


<ul>
<li>
<p><em>My actual college degree is in comparative religion.</em> I ended up in the Religion department at the <a href="http://www.ups.edu/">University of Puget Sound</a> (yes, the initials are UPS, which can easily cause confusion with brown, parcel-bearing trucks), due to a line of questioning that occurred during an Artificial Intelligence course I was taking. The instructor was asking if there would be any ethical barrier to unplugging an AI — i.e., since it would be capable of thought, would this be equivalent to &quot;killing&quot; it? My initial response was, &quot;No,&quot; because humans consist of more than thought… and then I started wondering a bit about that. My emphasis in religion was in Eastern religions. I have a minor in Mathematics (CS at UPS was actually CS/Mathematics).</p>
</li>
<li>
<p><em>I have an FCC Commercial Radio Operator's License.</em> My parents were volunteer DJs at <a href="http://www.kglt.net/">KGLT</a> while I was growing up, and I did my first radio announcing at… get this… the ripe age of 11. I finally got my license before starting college so that I could be a DJ at the university station… and ended up as the General Manager of <a href="http://en.wikipedia.org/wiki/KUPS">KUPS</a> my last two years.</p>
</li>
<li>
<p><em>I had long hair — down to my butt at times — for around ten years.</em> Which likely comes as a huge shock to those of you who have met me at conferences. Ironically, I cut it off just prior to moving to Vermont as part of an effort to increase the success of my job hunt.</p>
</li>
<li>
<p><em>Before I started my programming career, I was a graphics technician.</em> The job immediately prior to my first programming position was with a small book publisher that specialized in bird hunting and flyfishing guidebooks, for which I created maps, scanned and processed images for books, and did book and catalog layout.</p>
</li>
<li>
<p><em>My first Object Oriented Programming was in Perl.</em> If you've ever done OOP in Perl, you'll likely agree with the following statement: OOP in any other language is easy by comparison. I mean, come on, a syntax where the very definition of an object requires that you &quot;bless&quot; a &quot;thingy&quot;? Truly; this is from the &quot;bless&quot; documentation:</p>
<blockquote>
<p>bless REF: This function tells the thingy referenced by REF that it is now an object in the CLASSNAME package. If CLASSNAME is omitted, the current package is used. Because a bless is often the last thing in a constructor, it returns the reference for convenience. Always use the two-argument version if a derived class might inherit the function doing the blessing. See perltoot and perlobj for more about the blessing (and blessings) of objects.</p>
</blockquote>
<p>This made OOP in PHP look easy.</p>
</li>
<li>
<p><em>I hold the degree of shodan in Aikido,</em> though I haven't trained in several years, due to time and travel constraints. I love the movement and flow of Aikido, and always found it very meditative. I also liked working with weapons, especially the bokken (wooden sword). This is why when I say, &quot;don't make me get my clue bat out,&quot; you should take heed; I know from experience that white oak leaves a mark.</p>
</li>
<li>
<p><em>I could have been <a href="http://calevans.com/">Cal</a>.</em> When <a href="http://www.zend.com/">Zend</a> first interviewed me, it was for the position of Editor-in-Chief of <a href="http://devzone.zend.com/">DevZone</a>. After my in-house interview, I had reservations — I didn't feel experienced or connected enough, and was worried I'd botch it. Fortunately for me, and probably the PHP community in general, they decided to hire me as a PHP developer instead.</p>
</li>
</ul>
<p>So, that's seven things (and quite a bit more, really) about me. And now it's time to tag some others:</p>
<ul>
<li><a href="http://calevans.com/">Cal Evans</a> is an obvious choice for me. Besides having worked together for some years, he's a great friend.</li>
<li><a href="http://www.leftontheweb.com/">Stefan Koopmanschap</a>, who took a train to Amsterdam just to have dinner and a beer with me.</li>
<li><a href="http://seancoates.com/">Sean Coates</a>, whom I met in an airport on the way back from ZendCon two years ago, who lives less than two hours away, and whom I haven't seen since that ZendCon.</li>
<li><a href="http://www.lornajane.net/">Lorna Jane Mitchell</a>, with whom I'll be doing a tutorial session on Subversion at php|tek, and who will be clearly flustered by being tagged.</li>
<li><a href="http://jansch.nl/">Ivo Jansch</a>, whom I met almost two years ago, and somebody I admire and respect greatly.</li>
<li><a href="http://www.khankennnels.com/blog/">Ligaya Turmelle</a>, one of my co-authors for &quot;The PHP Anthology,&quot; the woman who got me to volunteer as a phpwomen Booth Babe, and now MySQL guru.</li>
<li><a href="http://akrabat.com/">Rob Allen</a>, who has made my job easier by publishing tutorials and now a book on Zend Framework, and who in real-life is a mild-mannered Clark Kent I'd gladly raise a pint with any day.</li>
</ul>
<p>And here are the rules I'm supposed to pass on to the above bloggers:</p>
<ul>
<li>Link your original tagger(s), and list these rules on your blog.</li>
<li>Share seven facts about yourself in the post - some random, some wierd.</li>
<li>Tag seven people at the end of your post by leaving their names and the links to their blogs.</li>
<li>Let them know they've been tagged by leaving a comment on their blogs and/or Twitter.</li>
</ul>


<div class="h-entry">
    <img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&u=79dd2ea1d4d8855944715d09ee4c86215027fa80&s=140" alt="matthew">
    <a class="u-url u-uid p-name" href="https://mwop.net/blog/204-Seven-Things-Tagged-by-Keith-Casey.html">Seven Things - Tagged by Keith Casey</a> was originally
    published <time class="dt-published" datetime="2009-01-02T10:44:54-06:00">2 January 2009</time>
    on <a href="https://mwop.net">https://mwop.net</a> by
    <a rel="author" class="p-author" href="https://mwop.net">Matthew Weier O&#039;Phinney</a>.
</div>
]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
    <item>
      <title>Mumbles irssi integration</title>
      <pubDate>Fri, 12 Dec 2008 15:19:50 -0600</pubDate>
      <link>https://mwop.net/blog/197-Mumbles-irssi-integration.html</link>
      <guid>https://mwop.net/blog/197-Mumbles-irssi-integration.html</guid>
      <author>contact@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>I've been using IRC regularly for the past six to nine months, in large part
due to the growing ZF community on the <a href="http://freenode.net/">Freenode</a>
<code>#zftalk</code> channel (unfortunately, I simply don't have time to be in that
particular channel any more, but you can generally find me in <code>#zftalk.dev</code>),
but also to keep in contact with other peers, friends, and colleagues.</p>
<p>One difficulty, however, is keeping productivity high while staying on IRC. To
me, the ultimate client would provide me notifications when somebody mentions
my name or a watch word — allowing me to read the channel at my leisure, yet
still respond to people in a timely fashion.</p>


<p>I've tried a variety of IRC clients over the months, starting with Pidgin (poor
interface for IRC), mirc (huge difficulties figuring out the UI), xchat (not
bad, but seemed a bit heavy), Chatzilla (I liked the interface, but once you
got many tabs going, it was unwieldy switching around between them; I also
hated that Firefox dying or restarting caused Chatzilla to do likewise), and
now <a href="http://irssi.org/">irssi</a>.</p>
<p>So far, irssi is the best I've tried — I can run it in screen, allowing me to
keep it open as long as my machine is running. The interface is reasonable, and
cleanly keeps channels separate from private messages. Opening, closing, and
manipulating windows is easy. And it's highly scriptable… including in a
language I actually use! The perl bindings are top notch, though sometimes
cryptic. What's important, however, is that there are plenty of examples out
there if you want to try doing something. So, I figured I'd write up a quick
plugin to trigger notifications.</p>
<p>I've been using a number of different notification servers for linux, and
personally like both <a href="http://gnotify.sourceforge.net">gnotify</a> and
<a href="http://www.mumbles-project.org/">mumbles</a>. Both are very lightweight and offer
network protocols for triggering notifications.</p>
<p>I first tried using gnotify. It has a very, very simple TCP protocol, and I've
had success creating messages from the shell, PHP, and perl. Unfortunately, for
some reason, using it in irssi displayed some odd behavior: I'd lose the cursor
and the ability to enter input from the time a notification triggered until it
completed (i.e., the notification disappeared). Forking the process did not
appear to help.</p>
<p>So, I decided to try out mumbles. Mumbles is written in python, and has
themeable notifications — already a plus. It runs via dbus by default, but can
also optionally spawn a server that implements the <a href="http://growl.info/">Growl protocol</a>
— making it accessible for any process to send notifications. Additionally, it
has a command-line utility for triggering notifications — by default over dbus,
but optionally by contacting the growl server, if running.</p>
<p>Growl's protocol is a bit involved, and I didn't want to spend too much time on
this. So, I did a quick, dirty hack: I used backticks to trigger the CLI
utility. And it works <em>fantastically</em> — no delays whatsoever. Here's the code:</p>
<pre><code class="language-perl hljs perl" data-lang="perl"><span class="hljs-comment"># $HOME/.irssi/scripts/mumbles.pl</span>
<span class="hljs-keyword">use</span> strict;
<span class="hljs-keyword">use</span> Irssi;
<span class="hljs-keyword">use</span> Irssi::Irc;
<span class="hljs-keyword">use</span> vars <span class="hljs-string">qw($VERSION %IRSSI)</span>;

$VERSION = <span class="hljs-string">'0.1.0'</span>;
%IRSSI = (
    <span class="hljs-string">authors     =&gt;</span> <span class="hljs-string">"Matthew Weier O'Phinney"</span>,
    <span class="hljs-string">contact     =&gt;</span> <span class="hljs-string">'matthew@weierophinney.net'</span>,
    <span class="hljs-string">name        =&gt;</span> <span class="hljs-string">'Mumbles notifications for irssi'</span>,
    <span class="hljs-string">description =&gt;</span> <span class="hljs-string">'This script enables mumbles notifications for irssi'</span>,
    <span class="hljs-string">license     =&gt;</span> <span class="hljs-string">'New BSD'</span>,
    <span class="hljs-string">changed     =&gt;</span> <span class="hljs-string">"2008-12-10"</span>
);


<span class="hljs-function"><span class="hljs-keyword">sub</span> <span class="hljs-title">mumbles_sig_printtext</span> </span>{
  <span class="hljs-keyword">my</span> ($dest, $text, $stripped) = @_;

  <span class="hljs-keyword">if</span> (($dest-&gt;{level} &amp; (MSGLEVEL_HILIGHT|MSGLEVEL_MSGS)) &amp;&amp; ($dest-&gt;{level} &amp; MSGLEVEL_NOHILIGHT) == <span class="hljs-number">0</span>)
  {
    <span class="hljs-keyword">if</span> ($dest-&gt;{level} &amp; MSGLEVEL_PUBLIC)
    {
      mumbles($dest-&gt;{target} . <span class="hljs-string">" : "</span> . $text);
    }
  }
}

<span class="hljs-function"><span class="hljs-keyword">sub</span> <span class="hljs-title">mumbles</span> </span>{
    <span class="hljs-keyword">my</span> $message = <span class="hljs-keyword">shift</span>;
    <span class="hljs-keyword">my</span> $response;

    $message =~ <span class="hljs-regexp">s/[^!-~\s]//g</span>;

    <span class="hljs-string">`/usr/bin/mumbles-send -g 127.0.0.1 -s "IRC" "$message"`</span>;
}

Irssi::command_bind <span class="hljs-string">'mumbles'</span> =&gt; <span class="hljs-function"><span class="hljs-keyword">sub</span> </span>{
    <span class="hljs-keyword">my</span> ($message) = @_;
    mumbles($message);
};

Irssi::signal_add({
  <span class="hljs-string">'print text'</span>    =&gt; \&amp;mumbles_sig_printtext
});
</code></pre>
<p>This triggers a notification for any &quot;highlight&quot; event — basically, anytime
anybody &quot;says&quot; my name in a channel, or mentions a keyword I've marked for
highlighting. Additionally, I created a <code>mumbles</code> command so that I can send
test messages (usage: <code>/mumbles &quot;this is the message...&quot;</code>). You could certainly
bind to other events, such as topic changes, joins, parts, etc — I'm only
interested in highlight events.</p>
<p>You may note the regexp in there. One thing I discovered was that most messages
contained control and non-ascii characters that often resulted in unreadable
notifications, as well as some nasty messages reported by irssi. The regexp
removes anything not in the ascii character set or the set of whitespace
definitions prior to emitting the notification.</p>
<p>Something else I needed to do was configure compiz to ensure that the
notifications actually popped <em>above</em> my windows. I did this by going into the
compiz configuration manager, selecting &quot;General Options&quot;, selecting the &quot;Focus
&amp; Raise Behaviour&quot; tab, and modifying the &quot;Focus Prevention Windows&quot; to read as
follows:</p>
<pre><code class="language-text">(any) &amp; !(class=Mumbles)
</code></pre>
<p>To test it, I placed the script in <code>$HOME/.irssi/scripts/mumbles.pl</code>, and then,
in irssi, executed <code>/load mumbles.pl</code>.</p>
<p>Once I had it to my liking, I symlinked it into my
<code>$HOME/.irssi/scripts/autorun/</code> directory, allowing it to run as soon as irssi
loads. I can now have irssi running in a screen session, or minimize the
terminal, and get notifications — keeping me productive and informed at the
same time.</p>
<p><strong>UPDATED 2008-12-12:</strong> Added information on how to load the script, as well as
fixed the location to the autorun directory. Thanks, @sidhighwind!</p>


<div class="h-entry">
    <img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&u=79dd2ea1d4d8855944715d09ee4c86215027fa80&s=140" alt="matthew">
    <a class="u-url u-uid p-name" href="https://mwop.net/blog/197-Mumbles-irssi-integration.html">Mumbles irssi integration</a> was originally
    published <time class="dt-published" datetime="2008-12-10T15:01:50-06:00">10 December 2008</time>
    on <a href="https://mwop.net">https://mwop.net</a> by
    <a rel="author" class="p-author" href="https://mwop.net">Matthew Weier O&#039;Phinney</a>.
</div>
]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
    <item>
      <title>Vimgrep and Vim Project</title>
      <pubDate>Wed, 22 Oct 2008 21:55:03 -0500</pubDate>
      <link>https://mwop.net/blog/194-Vimgrep-and-Vim-Project.html</link>
      <guid>https://mwop.net/blog/194-Vimgrep-and-Vim-Project.html</guid>
      <author>contact@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>Chris Hartjes today was
<a href="http://www.littlehart.net/atthekeyboard/2008/10/20/vim-programming-bounty-fuzzyfind-inside-files/">on a quest for a &quot;find in project&quot; feature for Vim</a>.
&quot;Find in Project&quot; was a feature of Textmate that he'd grown accustomed to and
was having trouble finding an equivalent for.</p>
<p>The funny thing is that Textmate is a newcomer, and, of course, vim has had
such a feature for years. The thing to remember with vim, of course, is its
unix roots; typically if you know the unix command for doing something, you can
find what you need in vim. In this case, the key is the vimgrep plugin, which
ships in the standard vim distribution.</p>


<p>There are a variety of resources on vimgrep. The vim documentation includes a
chapter on it, and a quick <a href="http://www.google.com/search?q=vimgrep">google search</a>
on the subject turns up some nice tutorials immediately. If you've ever used
grep, the syntax is very straightforward:</p>
<pre><code class="language-markdown hljs markdown" data-lang="markdown">vimgrep /{pattern}/[<span class="hljs-string">g</span>][<span class="hljs-symbol">j</span>] {file} ...
</code></pre>
<p>The &quot;g&quot; option indicates that all matches for a search will be returned instead
of just one per line, and the &quot;j&quot; option tells vim <em>not</em> to jump to the first
match automatically. What does the &quot;g&quot; flag really mean, though, and how are
searches returned?</p>
<p>Vimgrep returns search results in what's known as a &quot;quickfix&quot; window, and this
is where the vimgrep documentation falls apart… it doesn't explain what this
is, or link to it (which would be a nice indication that it actually has a
separate topic for this).</p>
<p>The Quickfix window is a pane that shows a search result per line. Each line
shows the file that matches, the line number, and the contents of that line:</p>
<pre><code class="language-awk hljs awk" data-lang="awk"><span class="hljs-regexp">/home/m</span>atthew<span class="hljs-regexp">/git/</span>bugapp<span class="hljs-regexp">/application/</span>controllers<span class="hljs-regexp">/helpers/</span>GetForm.php|<span class="hljs-number">10</span>| * @var Zend_Loader_PluginLoader
</code></pre>
<p>You can't do much from this window; it simply serves as a visual indicator of
what file you're currently looking at from the list. However, in the main
window, you can start iterating through the results one at a time, using a
subset of the Quickfix commands. As a quick summary:</p>
<ul>
<li><strong>:cc</strong> will move to the next match in the list</li>
<li><strong>:cn</strong> will move to the next match in the list</li>
<li><strong>:cp</strong> will move to the previous match in the list</li>
<li><strong>:cr</strong> will rewind to the first match in the list</li>
<li><strong>:cla</strong> will fast forward to the last match in the list</li>
</ul>
<p>When done, you can simply close the Quickfix window/pane, and continue working.</p>
<p>I should note that vimgrep <em>is</em> cross-platform. On *nix-based systems, it
defaults to using the native grep command, but it also contains an internal
(slower) implementation for use on operating systems that do not provide grep
by default. You may also map the command to alternate implementations if
desired.</p>
<p>I personally use this feature most with the <a href="http://www.vim.org/scripts/script.php?script_id=69">project plugin</a>.
Project maps vimgrep to two different commands: <code>&lt;Leader&gt;g</code> and <code>&lt;Leader&gt;G</code>.
The first will grep all files in the current project at the current level; the
second does the same, but also recurses into subprojects. This is an incredibly
easy way to refactor code, particularly for name changes.</p>


<div class="h-entry">
    <img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&u=79dd2ea1d4d8855944715d09ee4c86215027fa80&s=140" alt="matthew">
    <a class="u-url u-uid p-name" href="https://mwop.net/blog/194-Vimgrep-and-Vim-Project.html">Vimgrep and Vim Project</a> was originally
    published <time class="dt-published" datetime="2008-10-21T07:36:49-05:00">21 October 2008</time>
    on <a href="https://mwop.net">https://mwop.net</a> by
    <a rel="author" class="p-author" href="https://mwop.net">Matthew Weier O&#039;Phinney</a>.
</div>
]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
    <item>
      <title>Vim 7 code completion</title>
      <pubDate>Fri, 22 Sep 2006 09:21:27 -0500</pubDate>
      <link>https://mwop.net/blog/123-Vim-7-code-completion.html</link>
      <guid>https://mwop.net/blog/123-Vim-7-code-completion.html</guid>
      <author>contact@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>I may work at <a href="http://www.zend.com/">Zend</a>, but I've never been a fan of IDEs.  They simply don't suit my programming style. I can usually keep track of file locations in my head pretty easily, and what I really need is a blank slate on which I can write, and one that doesn't consume resource that can better be used running web servers and other programs. Syntax highlighting, good indentation — these are important, but you can get these from good, minimal text editors very easily. <a href="http://www.vim.org">Vim is my editor of choice</a>.</p>
<p>I will admit, though, that one area where I have had IDE-envy is the area of code completion. I often find myself doing quick lookups to php.net or perldoc to determine the order of arguments to a function or method call, or checking for the expected return value. Most of the time, this doesn't take much time, however, so I just live with it.</p>
<p>Today, however, cruising through the blogosphere, I came across <a href="http://linuxhelp.blogspot.com/2006/09/visual-walk-through-of-couple-of-new.html">an article showcasing some new features of Vim 7.0</a>, and discovered Vim 7's code completion.</p>
<p>Basically, while in insert mode, you can type <code>&lt;C-x&gt; &lt;C-o&gt;</code> to have vim attempt to autocomplete the current keyword. If more than one possibility exists, it shows a dropdown, and you can use your arrow keys to highlight the keyword that you wish to use.</p>
<p>But it gets better! Not only does it do this kind of autocompletion, but it also opens a small 'scratch preview' pane showing the function/method signature — i.e., the expected arguments and return value!</p>
<p>I thought I had little need for IDEs before… now I have even less! Bram and the rest of the Vim team, my hat's off to you for more fine work!</p>




<div class="h-entry">
    <img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&u=79dd2ea1d4d8855944715d09ee4c86215027fa80&s=140" alt="matthew">
    <a class="u-url u-uid p-name" href="https://mwop.net/blog/123-Vim-7-code-completion.html">Vim 7 code completion</a> was originally
    published <time class="dt-published" datetime="2006-09-19T17:45:00-05:00">19 September 2006</time>
    on <a href="https://mwop.net">https://mwop.net</a> by
    <a rel="author" class="p-author" href="https://mwop.net">Matthew Weier O&#039;Phinney</a>.
</div>
]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
    <item>
      <title>Telcos are Attacking the Internet</title>
      <pubDate>Fri, 28 Apr 2006 13:47:28 -0500</pubDate>
      <link>https://mwop.net/blog/107-Telcos-are-Attacking-the-Internet.html</link>
      <guid>https://mwop.net/blog/107-Telcos-are-Attacking-the-Internet.html</guid>
      <author>contact@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>I generally try to stay out of politics on this blog, but this time something has to be said, as it affects anyone who uses the internet, at least in the US.</p>
<p>Basically, a number of telcos and cable providers are talking about charging internet content providers — the places you browse to on the internet, places like Google, Yahoo!, Amazon, etc. — fees to ensure bandwidth to their sites. Their argument is that these content providers are getting a 'free ride' on their lines, and generating a lot of traffic themselves, and should thus be paying for the cost of bandwidth.</p>
<p>This is patently ridiculous. Content providers already have to pay for their bandwidth — they, too, have ISPs or agreements with telcos in place, either explicitly or via their hosting providers. Sure, some of them, particularly search engines, send out robots in order to index or find content, but, again, they're paying for the bandwidth those robots generate. Additionally, people using the internet are typically paying for bandwidth as well, through their relationship with their ISP. What this amounts to is the telcos getting paid not just by each person to whom they provide internet access, but every end point on the internet, at least those within the US.</p>
<p>What this is really about is telcos wanting more money, and wanting to push their own content. As an example, let's say your ISP is AOL. AOL is part of Time Warner, and thus has ties to those media sources. Now, those media sources may put pressure on AOL to reduce bandwidth to sites operated by ABC, CBS, NBC, FOX, Disney, PBS, etc. This might mean that your kid can no longer visit the Sesame Street website reliably, because AOL has reduced the amount of bandwidth allowed to that service — but any media site in the TWC would get optimal access, so they could get to Cartoon Network. Not to slam Cartoon Network (I love it), but would you rather have your kid visiting cartoonnetwork.com or pbskids.org? Basically, content providers would not need to compete based on the value of their content, but on who they can get to subscribe to their service.</p>
<p>Here's another idea: your ISP is MSN. You want to use Google… but MSN has limited the bandwidth to Google because it's a competitor, and won't accept any amount of money to increase that bandwidth. They do the same with Yahoo! So, now you're limited to MSN search, because that's the only one that responds reliably — regardless of whether or not you like their search results. By doing so, they've just artificially inflated the value of their search engine — without needing to compete based on merit.</p>
<p>Additionally, let's say Barnes and Noble has paid MSN to ensure good bandwidth, but part of that agreement is a non-compete clause. Now you find your connections to Amazon timing out, meaning that you can't even see which book provider has the better price on the book you want; you're stuck looking and buying from B&amp;N.</p>
<p>Now, let's look at something a little more close to home for those of us developing web applications. There have been a number of success stories the last few years: MySpace, Digg, and Flickr all come to mind. Would these endeavors have been as successful had they needed to pay multiple times for bandwidth, once to their ISP and once each to each telco charging for content providers? Indeed, some of these are still free services — how would they ever have been able to pay the extra amounts to the telcos in the first place?</p>
<p>So, basically, the only winners here are the telcos.</p>
<p>Considering how ludicrous this scheme is, one must be thinking, isn't the US Government going to step in and regulate against such behaviour? <a href="http://www.businessweek.com/technology/content/apr2006/tc20060426_553893.htm?chan=technology_technology+index+page_more+of+today">The answer, sadly, is no.</a> The GOP doesn't like regulation, and so they want market forces to decide.  Sadly, what this will likely do is force a number of content providers to offshore their internet operations — which is likely to have some pretty negative effects on the economy.</p>
<p>The decision isn't final — efforts can still be made to prevent it (the above link references a Senate committee meeting; there's been no vote on it). Call your representatives today and give them an earful. Tell them it's not just about regulation of the industry, but about fair competition in the market. Allowing the telcos to extort money from content providers will only reduce the US' economic chances in the world, and stifle innovation and choice.</p>




<div class="h-entry">
    <img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&u=79dd2ea1d4d8855944715d09ee4c86215027fa80&s=140" alt="matthew">
    <a class="u-url u-uid p-name" href="https://mwop.net/blog/107-Telcos-are-Attacking-the-Internet.html">Telcos are Attacking the Internet</a> was originally
    published <time class="dt-published" datetime="2006-04-28T11:31:00-05:00">28 April 2006</time>
    on <a href="https://mwop.net">https://mwop.net</a> by
    <a rel="author" class="p-author" href="https://mwop.net">Matthew Weier O&#039;Phinney</a>.
</div>
]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
    <item>
      <title>PHP error reporting for Perl users</title>
      <pubDate>Tue, 28 Mar 2006 09:19:35 -0600</pubDate>
      <link>https://mwop.net/blog/105-PHP-error-reporting-for-Perl-users.html</link>
      <guid>https://mwop.net/blog/105-PHP-error-reporting-for-Perl-users.html</guid>
      <author>contact@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>On <a href="http://www.perlmonks.org">perlmonks</a> today, a user was needing to maintain a PHP app, and wanted to know what the PHP equivalent of <code>perl -wc script.pl</code> was — specifically, they wanted to know how to run a PHP script from the commandline and have it display any warnings (ala perl's strict and warnings pragmas).</p>
<p>Unfortunately, there's not as simple a way to do this in PHP as in perl. Basically, you need to do the following:</p>
<ul>
<li>
<p><strong>To display errors:</strong></p>
<ul>
<li>In your <code>php.ini</code> file, set <code>display_errors = On</code>, <strong>or</strong></li>
<li>In your script, add the line <code>ini_set('display_errors', true);</code></li>
</ul>
</li>
<li>
<p><strong>To show notices, warnings, errors, deprecation notices:</strong></p>
<ul>
<li>In your <code>php.ini</code> file, set <code>error_reporting = E_ALL | E_STRICT</code>, <strong>or</strong></li>
<li>In your script, add the line <code>error_reporting(E_ALL | E_STRICT);</code></li>
</ul>
</li>
</ul>
<p>Alternatively, you can create a file with the lines:</p>
<pre><code class="language-php hljs php" data-lang="php"><span class="hljs-meta">&lt;?php</span>
error_reporting(E_ALL | E_STRICT);
ini_set(<span class="hljs-string">'display_errors'</span>, <span class="hljs-keyword">true</span>);
</code></pre>
<p>and then set the <code>php.ini</code> setting <code>auto_prepend_file</code> to the path to that file.</p>
<p><strong>NOTE: do not do any of the above on a production system!</strong> PHP's error messages often reveal a lot about your applications, including file layout and potential vectors of attack. Turn <code>display_errors</code> off on production machines, set your <code>error_reporting</code> somewhat lower, and <code>log_errors</code> to a file so you can keep track of what's going on on your production system.</p>
<p>The second part of the question was how to run a PHP script on the command line. This is incredibly simple: <code>php myscript.php</code>. No different than any other scripting language.</p>
<p>You can get some good information by using some of the switches, though. <strong><code>-l</code></strong> turns the PHP interpreter into a linter, and can let you know if your code is well-formed (which doesn't necessarily preclude runtime or parse errors). <strong><code>-f</code></strong> will run the script through the parser, which can give you even more information. I typically bind these actions to keys in vim so I can check my work as I go.</p>
<p>If you plan on running your code <em>solely</em> on the commandline, add a shebang to the first line of your script: <code>#!/path/to/php</code>. Then make the script executable, and you're good to go. This is handy for cronjobs, or batch processing scripts.</p>
<p>All of this information is readily available in <a href="http://www.php.net/manual">the PHP manual</a>, and the commandline options are always available by passing the <code>--help</code> switch to the PHP executable. So, start testing your scripts already!</p>




<div class="h-entry">
    <img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&u=79dd2ea1d4d8855944715d09ee4c86215027fa80&s=140" alt="matthew">
    <a class="u-url u-uid p-name" href="https://mwop.net/blog/105-PHP-error-reporting-for-Perl-users.html">PHP error reporting for Perl users</a> was originally
    published <time class="dt-published" datetime="2006-03-27T23:10:00-06:00">27 March 2006</time>
    on <a href="https://mwop.net">https://mwop.net</a> by
    <a rel="author" class="p-author" href="https://mwop.net">Matthew Weier O&#039;Phinney</a>.
</div>
]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
    <item>
      <title>Sign of a Geek</title>
      <pubDate>Wed, 17 Nov 2004 16:05:42 -0600</pubDate>
      <link>https://mwop.net/blog/51-Sign-of-a-Geek.html</link>
      <guid>https://mwop.net/blog/51-Sign-of-a-Geek.html</guid>
      <author>contact@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>It's now been confirmed: I'm a geek.</p>
<p>Okay, so that probably comes as no shocker to those of you who know me, but it's
the little things that make me realize it myself.</p>
<p>I've been frequenting <a href="http://www.perlmonks.org">Perl Monks</a> for a couple of
years now, mainly to garner ideas and code to help me with my personal or work
projects. I rarely post comments, and I've only once submitted a question to the
site. However, I <strong>do</strong> frequent the site regularly, and the few comments I've
put in — generally regarding usage of
<a href="http::/search.cpan.org/search?query=CGI%3A%3AApplication">CGI::Application</a> —
have been typically well-moderated.</p>
<p>Well, yesterday I <a href="http://www.perlmonks.org/?node_id=408255">made a comment</a> to
a user <a href="http://www.perlmonks.org/?node_id=408231">asking about editors to use with perl</a>.
I was incensed by a remark he made about <a href="http://www.vim.org">VIM</a> not having
the features he needed. Now, as I said in my comment, I've used VIM on a daily
basis for over two years, and I'm <em>still</em> discovering new features — and I've
used all of the features he was looking for.</p>
<p>This is where I discovered I'm a geek: my comment made it into the
<a href="http://www.perlmonks.org/?node=Best%20Nodes">Daily Best</a> for today, peaking
around number 5. The fact that that made my day indicates to me that I <em>must</em> be
a geek.</p>
<p>Oh — and VIM rules!</p>




<div class="h-entry">
    <img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&u=79dd2ea1d4d8855944715d09ee4c86215027fa80&s=140" alt="matthew">
    <a class="u-url u-uid p-name" href="https://mwop.net/blog/51-Sign-of-a-Geek.html">Sign of a Geek</a> was originally
    published <time class="dt-published" datetime="2004-11-17T16:04:39-06:00">17 November 2004</time>
    on <a href="https://mwop.net">https://mwop.net</a> by
    <a rel="author" class="p-author" href="https://mwop.net">Matthew Weier O&#039;Phinney</a>.
</div>
]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
    <item>
      <title>PHP_SELF versus SCRIPT_NAME</title>
      <pubDate>Tue, 12 Oct 2004 21:35:03 -0500</pubDate>
      <link>https://mwop.net/blog/45-PHP_SELF-versus-SCRIPT_NAME.html</link>
      <guid>https://mwop.net/blog/45-PHP_SELF-versus-SCRIPT_NAME.html</guid>
      <author>contact@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>I've standardized my PHP programming to use the environment variable
<code>SCRIPT_NAME</code> when I want my script to refer to itself in links and form
actions. I've known that <code>PHP_SELF</code> has the same information, but I was more
familiar with the name <code>SCRIPT_NAME</code> from using it in perl, and liked the feel
of it more as it seems to describe the resource better (<code>PHP_SELF</code> could stand
for the path to the PHP executable if I were to go by the name only).</p>
<p>However, I just noticed a post on the php.general newsgroup where somebody asked
what the difference was between them. Semantically, there isn't any; they should
contain the same information. However, historically and technically speaking,
there is. <code>SCRIPT_NAME</code> is defined in the CGI 1.1 specification, and is thus a
standard. <em>However</em>, not all web servers actually implement it, and thus it
isn't necessarily <em>portable</em>. <code>PHP_SELF</code>, on the other hand, is implemented
directly by PHP, and as long as you're programming in PHP, will always be
present.</p>
<p>Guess I have some grep and sed in my future as I change a bunch of scripts…</p>




<div class="h-entry">
    <img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&u=79dd2ea1d4d8855944715d09ee4c86215027fa80&s=140" alt="matthew">
    <a class="u-url u-uid p-name" href="https://mwop.net/blog/45-PHP_SELF-versus-SCRIPT_NAME.html">PHP_SELF versus SCRIPT_NAME</a> was originally
    published <time class="dt-published" datetime="2004-10-12T21:34:57-05:00">12 October 2004</time>
    on <a href="https://mwop.net">https://mwop.net</a> by
    <a rel="author" class="p-author" href="https://mwop.net">Matthew Weier O&#039;Phinney</a>.
</div>
]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
  </channel>
</rss>
