+Michael Sanford :: Development, Performance

Twitter0Google+7Reddit0LinkedIn0Facebook0Pinterest0

We make heavy use of xslt at work (parsing xml data generated by php controllers), so the xslcache pecl module is pretty fundamental to our infrastructure. Of course, if you are using PHP 5.4 or above, like many pecl modules, it breaks. Here's how to get it to work.

Currently, trying sudo pecl install xslcache-beta with PHP >= 5.4 throws the following error at make:

/tmp/pear/temp/xslcache/php_xsl.c: In function 'xslcache_objects_new':
 /tmp/pear/temp/xslcache/php_xsl.c:211:52: error: 'zend_class_entry' has no member named 'default_properties'
 make: *** [php_xsl.lo] Error 1
 ERROR: `make' failed

Download xslcache

Download the original source from the pecl svn repository, the 5.4 patch, and patch it manually:

svn checkout http://svn.php.net/repository/pecl/xslcache/trunk xslcache
cd xslcache
wget -O php_xsl.c.patch 'https://bugs.php.net/patch-display.php?bug_id=62856&patch=xslcache-php5.4-compat&revision=1362641549&download=1'
patch < php_xsl.c.patch

Make and install

This is a pretty straightforward make process for most linux software (you may need to adjust the location of xslcache.ini):


phpize
./configure
make
make test
sudo make install
sudo nano /etc/php5/cgi/conf.d/xslcache.ini
#add "extension=xslcache.so"

Note that if you make test the tenth may fail with the following:

=====================================================================
FAILED TEST SUMMARY
---------------------------------------------------------------------
Test 10: EXSLT Support [tests/xslt010.phpt]
=====================================================================

If you're using XSLT 2.0, you probably don't need to worry about it.

Verify that xslcache is installed and enabled

Since we're already in the command line, let's check there:

php -i | grep XSLCACHE

Hopefully, you will see the following line:

XSLCACHE => enabled

Furthermore, you should be able to actually know it's doing its job because your benchmarks should improve.

+Michael Sanford :: Development

Twitter0Google+0Reddit0LinkedIn0Facebook0Pinterest0

Here's a regex string I came up with in PHP for testing GSM 03.38 7-bit characters for validation in text fields.

The common Latin characters and punctuation are globbed into the unicode character span.

+Michael Sanford :: Development

Twitter0Google+8Reddit0LinkedIn0Facebook0Pinterest0

My Dev circle on Google+ has alerted me, just before the end of the early bird deadline, to the existence of jQueryTO - Toronto's jQuery Conference ! It boasts such speakers as Dave Methvin (jQuery Foundation President), Paul Irish (of Google Chrome), Jen Fong-Adwent (of Mozilla) among many more!

$("#TO").register({
    transporation: function(){
        $(this).comparePrice("Porter", "VIA_Rail", "car")
        .convenienceFactorTranslate().book();
    },
    hotel: function(venue){
        $(this).onAnnounce(venue).book();
    },
    fee: function(){
        $(this).pay("earlybird");
    }
});

Topics don't seem to be limited to jQuery, and will include talks on AngularJS and possibly other frameworks.

jQueryTO Logo

See you there!

+Michael Sanford :: Development

Twitter0Google+0Reddit0LinkedIn0Facebook0Pinterest0

One of my favourite frameworks in which to quickly develop a small web app is CodeIgniter. Most CI developers will admit that the default configuration is somewhat sub-optimal. Here's my contribution: a simple CodeIgniter .htaccess file that enables controller rewriting that doesn't break the /user_guide (which one may actually want to consult locally from time to time) and provides for a project-root /static folder to store your static resources.

Feel free to fork, comment, improve !

+Michael Sanford :: UX

Twitter0Google+6Reddit0LinkedIn0Facebook0Pinterest0

Well, we've come full circle. This morning, I took a Journal métro (while exiting the Métro) to discover that an enterprising marketing guy had stuck a popup on my print media.

An ad sticker placed over a front-page article's headline and content.

I'm a fan of print media. I prefer to read Le Monde Diplomatique or Monocle in their print forms (even considering tablets). I also think that traditional media can learn from new media. But, seriously, let popups and popovers die already.

+Michael Sanford :: Development

Twitter0Google+2Reddit0LinkedIn0Facebook0Pinterest0

We use xhprof to profile our web application framework. The pecl installer was failing with `[xhprof.lo] Error 1` in the make phase with PHP 5.4. Here's how to fix that.

Currently, trying

sudo pecl install xhprof-beta

throws the following errors in the `make` phase for PHP >= 5.4:

In file included from /usr/include/php5/main/php.h:33:0,
from /tmp/pear/temp/xhprof/extension/xhprof.c:27:
/usr/include/php5/main/php_config.h:2396:0: warning: "_GNU_SOURCE" redefined [enabled by default]
/tmp/pear/temp/xhprof/extension/xhprof.c:24:0: note: this is the location of the previous definition
/tmp/pear/temp/xhprof/extension/xhprof.c:236:1: warning: 'visibility' attribute ignored [-Wattributes]
/tmp/pear/temp/xhprof/extension/xhprof.c:240:28: warning: 'visibility' attribute ignored [-Wattributes]
/tmp/pear/temp/xhprof/extension/xhprof.c: In function 'hp_get_function_name':
/tmp/pear/temp/xhprof/extension/xhprof.c:898:10: warning: assignment discards 'const' qualifier from pointer target type [enabled by default]
/tmp/pear/temp/xhprof/extension/xhprof.c:909:13: warning: assignment discards 'const' qualifier from pointer target type [enabled by default]
/tmp/pear/temp/xhprof/extension/xhprof.c:911:13: warning: assignment discards 'const' qualifier from pointer target type [enabled by default]
/tmp/pear/temp/xhprof/extension/xhprof.c:930:34: error: 'znode_op' has no member named 'u'
/tmp/pear/temp/xhprof/extension/xhprof.c:963:9: warning: passing argument 1 of 'hp_get_base_filename' discards 'const' qualifier from pointer target type [enabled by default]
/tmp/pear/temp/xhprof/extension/xhprof.c:856:14: note: expected 'char *' but argument is of type 'const char *'
/tmp/pear/temp/xhprof/extension/xhprof.c: In function 'hp_execute_internal':
/tmp/pear/temp/xhprof/extension/xhprof.c:1650:24: error: 'znode_op' has no member named 'u'
/tmp/pear/temp/xhprof/extension/xhprof.c:1651:59: error: 'struct <anonymous>' has no member named 'return_reference'
/tmp/pear/temp/xhprof/extension/xhprof.c:1652:25: error: 'znode_op' has no member named 'u'
/tmp/pear/temp/xhprof/extension/xhprof.c: In function 'hp_compile_file':
/tmp/pear/temp/xhprof/extension/xhprof.c:1683:3: warning: passing argument 1 of 'hp_get_base_filename' discards 'const' qualifier from pointer target type [enabled by default]
/tmp/pear/temp/xhprof/extension/xhprof.c:856:14: note: expected 'char *' but argument is of type 'const char *'
make: *** [xhprof.lo] Error 1
ERROR: `make' failed

According to a PHP bug report, this issue was fixed by Facebook but not made available on pecl, so you will need to install from the xhprof github repo, like so:

wget https://github.com/facebook/xhprof/archive/master.zip
unzip master.zip
cd xhprof-master/extension/
phpize
./configure
make
sudo make install

And enable the module in your php.ini, where `xhprof.output_dir` is the directory into which profiles will be generated.

[xhprof]
extension=xhprof.so
xhprof.output_dir="/var/tmp/xhprof"

And restart apache, with either of the following two:

sudo service apache2 restart
sudo apachectl graceful

Existing users who have upgraded to PHP 5.4 may opt for this xhprof-0.9.2 patch.

+Michael Sanford :: Development

Twitter0Google+4Reddit0LinkedIn0Facebook0Pinterest0

I'm a meticulous person. I will correct a typo in a 2-year old post. I refactor like I vote: early and often. However, I was recently confronted with a very simple problem that stumped me completely. No, it wasn't FizzBuzz. The solution eluded me because it entirely broke what I thought of as good practice, especially given my experience in accessible web development. Having often been the go-to guy for thinking 'outside the box', I found myself inside one of my own creation. The ugly kludge of a solution was, in retrospect, a perfectly acceptable one given the circumstances. So why didn't I think of it?

My friend, who is not a developer, asked me to give him a hand off the cuff, at the end of the day and over IM. I had a few minutes to offer advice on solving his problem. He complained of "doubled bullets" on an HTML page (which was presumably rendered from an OCR or document export) similar to the following HTML fragment:

<ul>
  <li>
    <span class="bullet">• </span>
    <span>First item</span>
  </li>
  <li>
    <span class="bullet">• </span>
    <span>Second item</span>
  </li>
</ul>

Obviously, the doubled bullet was the result of a hard-coded bullet entity, which has a simple fix: find and replace the whole span string. Done.

What I didn't realize is that there were other, similar problems in the export parsing that had caused output like this:

<ul>
  <li>
    <span class="bullet">a) </span>
    <span>First item.</span>
  </li>
  <li>
    <span class="bullet">b) </span>
    <span>Second item.</span>
  </li>
</ul>

This is only a slightly bigger problem:

  1. Pattern match
    ^<span class="bullet">.*?</span>$
    to find relevant entities (there were a variable number of spaces after the letters throughout the document, or the <span> could be empty).
  2. Ascend to the parent `<ul>` and transform it into an `<ol type="a">`.
  3. Using the pattern from (1), delete all instances of the superfluous `<span>`.

The problem with this solution comes with the fact that there were 250 <ul>s in the document and changing the relevant parent <ul> to <ol> had to be done manually (not every `<ul>` was destined to become an `<ol>`, nor all of `type="a"`).

Sorry, dude, you're on your own!

Yes, I could have written a script to actually parse the DOM, ascend to targeted parent <ul>s by pattern matching ^<span class="bullet">[a-z].*?</span>$ (for `type="a"`) and ^<span class="bullet">[0-9]{1,2}.*?</span>$ (for `type="1"`) and perform the transformations that way.

I didn't realistically have the time or the desire to write such a script, and it was well past dinner time.

Returning from dinner, I see a new message: "OVERTHINKING 101"

The solution someone else proposed was:

ul, ol
{
  list-style: none;
}

li
{
  position: relative;
}

.bullet
{
  position: absolute; left: -1em; top: 0px;
}

Are you serious?!

This, to me, was the ugliest kludge: it breaks semantic convention and doesn't address the fact that `<ul>` and `<ol>` mean something to machines. In my mind, it's akin to using `<p style="font-size: large; font-weight: bold">` for a header, rather than using an `<h1>`. In a vaguely similar vein, the proposed solution takes a semantically unordered list and coerces it into becoming a de facto ordered list with plain text.

But is that even a problem?

In this case, not really! That's the key to this issue. The document was destined for a very specific purpose and a very restricted audience. Visual presentation was the only thing that mattered to both the author and the readers.

I would never deploy this code in a production environment for general consumption because I feel that standards are a good thing and ought to be adhered to. However, I think wilfully disregarding them can be done effectively in certain circumstances and isn't a problem 100% of the time. I would never have devised this perfectly acceptable solution because I had built a cognitive box around my way of thinking, following standards so automatically that a good, quick solution never came to mind.

And that's precisely what my friend needed: a decent, quick solution that responded to his specific criteria (solely visual presentation).