19. June 2013

Pointless Promises in PHP

A promise is a way to defer the execution of a given routine until the data it needs to run is ready. This is a very useful pattern in asynchronous languages, so using promises in a language like javascript is a great idea.

Of course PHP is (without forking) totally synchronous so there is really no reason to implement the promise pattern in PHP.

But the motto of every programmer is “if it’s a bad idea, I will do it!” (no, it isn’t), so here’s an implementation of promises in PHP:

class PromiseClass {
    private $callbacks = array();
    private $last_return;
    function promise($promise) {
        if (get_class($promise) == 'Promise') {
            return $promise;
        } else if (is_callable($promise)) {
            $this->then($promise);
            return $this;
        }
    }
    function then (callable $callback) {
        $this->callbacks[] = $callback;
        return $this;
    }
    function resolve () {
        $callback = array_shift($this->callbacks);
        if (is_callable($callback)) {
            $this->last_return = $callback($this->last_return);
        }
        if (count($this->callbacks) > 0) {
            $this->resolve();
        }
    }
}

A few things to note here:

  1. First you will have to make an instance of the class.
  2. You start by passing a function to the promise method. You could use then but the code wouldn’t look as descriptive or read as well.
  3. You can then add any functions that would be run after with successive calls to then.
  4. None of the functions that have been set up will be run until you call the resolve method on the object.

Here’s an example of usage of this useless and pointless class:

$promiser = new PromiseClass();

$promiser->promise(function() {
        echo "sleepingn";
        sleep(3);
        return 3;
    })
    ->then(function($args) {
        echo "that farn$argsn";
        sleep(1);
    })
    ->then(function() {
        echo "even farthernn";
    });

$promiser->resolve();    

Note: I’ve added some sleep statements here so it almost seems like something asynchronous is happening. Really sleep is just blocking. The output will be something like:

sleeping
that far
3
even farther

11. June 2013

Longest Common Substring in PHP

Longest common substring is a function that can be useful once in a while. Here’s a PHP implementation. Be forewarned, this runs in O(mn) time.

function longest_common_substring($string1, $string2) {
    $L = array();
    $length = 0;
    $pos = 0;
    $array1 =str_split($string1);
    $array2 =str_split($string2);
    foreach ($array1 as $i => $c1) { 
        $L[$i] = array();
        foreach ($array2 as $j => $c2) { 
            $L[$i][$j] = 0;
            if ($c1 == $c2) {
                if ($i == 0 || $j == 0) {
                    // initialize that this character position exists.
                    $L[$i][$j] = 1;
                } else {
                    // increment previous or reset.
                    if (isset($L[$i-1][$j-1])) {
                        $L[$i][$j] = $L[$i-1][$j-1] + 1;
                    } else {
                        $L[$i][$j] = 0;
                    }
                }
                if ($L[$i][$j] > $length) {
                    $length = $L[$i][$j];
                }
                if ((isset($L[$i][$j]))&&($L[$i][$j] == $length)) {
                    $pos = $i;
                }
            }
        }
    }
    if ($length > 0) {
        return substr($string1, $pos - $length + 1, $length);
    } else {
        return '';
    }
}

Usage:

$string1 = 'sadjjasdf this is the string  sdlkjhaskl';
$string2 = 'eriuhysdfnbasi this is the stringbhdjubsdi';

echo longest_common_substring($string1, $string2);

10. June 2013

Finding the main content element on a page in javascript

Short of going to something more complex like measuring information or doing some natural language processing, you can estimate which element on a page contains the content by determining which element has the highest ratio of contained content to contained markup. Here’s a javascript snippet that does just that:

// not perfect obviously. Not terrible neither.

var id, tag;
var all = document.querySelectorAll('body *'), max = 0, el, i, L;

// list some commons ids that denote the outermost element on a page.
var badIds = {
    "wrapper" : 1,
    "container" : 1,
    "wrapper-content" : 1
};

// we don't want to include content from certain tags.
var badTags = {
    "SCRIPT" : 1,
    "STYLE" : 1,
    "HEADER" : 1
}

// the goal rate of markup per content
var contentPercent = 0.45;

var contentRatio = function(el) {
    var i, L, totalScript = 0, scripts = el.getElementsByTagName("script");
    for (i =0, L= scripts.length; i < L; i++) {
        totalScript += scripts[i].length;
    }
    totalScript = 0;
    return (el.textContent.length - totalScript) / el.innerHTML.length;
};

for (i = 0, L =all.length; i < L; i++) {
    id = all[i].getAttribute('id');
    tag = all[i].tagName;
    if (all[i].textContent && all[i].textContent.length > max && (contentRatio(all[i]) > contentPercent) && !badIds[id] && !badTags[tag]) {
        max = all[i].textContent.length;
        el = all[i];
    }
}

// show the results.
console.log(el)
console.log(el.textContent.length / el.innerHTML.length)