Accessing a method defined in the current class’ “granpa”

Posted on Wednesday, August 4th, 2010 under ,

Problem: we have an hierarchy of 3 classes, each extending the one in front (grandfather, father, son). A method – let’s say foo() – is defined in the grandfather class and overridden with a new functionality in the father class.

Question: Is there a way in the son class to access the original method (with the grandfather code) in the son class?

Of course, the obvious solution is to try something like:

parent::parent::method();

But it won’t work. It will just yield an error like:

Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM in …

After some struggling, I have found a way to get around and access a method from the grandparent class that was overridden in the parent and run its “original” code. It’s loosely based on the strange PHP scoping that I wrote about in this article. The approach goes something like this:

class Grandfather
{
    protected $_message = 'Luke, I am your grandfather';
 
    public function say()
    {
        echo $this->_message;
    }
}
 
class Father extends Grandfather
{
    protected $_message = 'Luke, I am your father';   
 
    public function say()
    {
        throw new Exception("I can't breath under this f**cking mask :(");
    }
}
 
class Son extends Father
{
    protected $_message = 'I have a very bad feeling about this';
 
    public function say()
    {
        Grandfather::say();
    }
}
 
$son = new Son();
$son->say();

Now PHP will bind the $this pointer in the body of the say() method – using the code defined in the grandfather. I guess that weird scoping is there for a reason.

Remove empty array elements with recursive lambda in PHP 5.3

Posted on Thursday, June 17th, 2010 under , , ,

How do you remove empty elements from a PHP array? The answer’s quite simple: array_filter(). Straight from manual and works like a charm:

$filtered = array_filter($raw);

Well, most of the time. It’s not recursive by default, so it only removes empty items on the first level of the array. If you have nested arrays and wish to remove all the empty items, regardless of their position in the matrix, array_filter() won’t work.

For example, let’s consider the following construct:

$raw = array(
    'firstname' => 'Foo',
    'lastname'  => 'Bar',
    'nickname' => '',
    'birthdate' => array( 
        'day'   => '',
        'month' => '',
        'year'  => '',
    ),
    'likes' => array(
        'cars'  => array('Subaru Impreza WRX STi', 'Mitsubishi Evo', 'Nissan GTR'),
        'bikes' => array(),
    ),
);

In this case, PHP’s built in array_filter() will miss the “birthdate” and “bikes” items. So, what now? Of course, you can create a function that will remove empty items recursively and pass it as a callback to PHP’s array_filter() function:

function removeEmptyItems($item)
{
    if (is_array($item)) {
        return array_filter($item, 'removeEmptyItems');
    }
 
    if (!empty($item)) {
        return true;    
    }
}
 
$filtered = array_filter($raw, 'removeEmptyItems');

But if you’re using a framework like Zend Framework that forbids using functions in the global scope and asks that all functions are wrapped in classes as static methods, things become more complicated and verbose. Yeah, yeah, I know, I’m a standards nazi :)

But if you’re using PHP 5.3, there’s a much simpler solution:

$callback = function($item) use (&$callback) {
    if (is_array($item)) {
        return array_filter($item, $callback);
    }
    if (!empty($item)) {
        return $item;
    }
};
 
$filtered = array_filter($raw, $callback);

Lambdas are sweet :)

Strange PHP scoping

Posted on Tuesday, May 11th, 2010 under , ,

I came to the conclusion that PHP is the programing language with the weirdest features. After the variable variables mess, that allows to you to name your variables stuff like !@#$%^&*()_+= and not be able to use them directly, I thought I saw everything. But no, yesterday I’ve bumped in another strange PHP feature. An even stranger feature.

Take a look at the code below:

class Example
{
    public function dynamicMethod($string)
    {
        // calls method baz() of the same class
        // class Example *does not have* a baz() method 
        $this->baz($string);
    }    
}
 
class Foo
{
    public function bar()
    {
        // a dynamic method called statically
        // no Example object is being instantiated
        Example::dynamicMethod('whatever');
    }
 
    public function baz($string)
    {
        echo 'Method baz() called with param "' . $string . '"' . PHP_EOL;
    }
}
 
$foo = new Foo();
$foo->bar();

What do you think the code will do? Yield an exception? A syntax error? Work? Well, strangely enough, it works:

Tudor-Barbus-MacBook% php blog-example.php
Method baz() called with param "whatever"

…and it seems that this feature is here to stay and be supported in the future, since I’m using the new PHP 5.3 version:

Tudor-Barbus-MacBook% php -v
PHP 5.3.1 (cli) (built: Feb 11 2010 02:32:22) 
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2009 Zend Technologies

I wonder how this can be useful to somebody.

Logical operators in PHP

Posted on Friday, April 3rd, 2009 under , ,

Early in his career, every PHP programmer writes code like:

mysql_query( $sql ) or die( mysql_error() );

Come on! We’ve all been there. Of course, now we all agree that that’s lame and stupid and we use PDO or even ActiveRecord, but back in the days, that was widely used. What does that mean, actually? or die()?

It’s an optimization originally implemented in – I think – gone wild.

For instance, if you have a condition like:

if ( ( $a == $b ) || ( $c == $d ) ) { /* whatever */}

…if the the result in the first set of parenthesis evaluates to true, the second one isn’t evaluated because its result is irrelevant in this context. The parser already knows the answer, as “true or anything” always equals true.

The mysql_query() function returns a value that can be evaluated from a boolean point of view. If that result is evaluated to true (the query was okay), then the die() part gets left out. If the query fails and mysql_query() returns something that evaluates as false, then the die() call gets executed. That’s all, in a nutshell.

The above code could have been rewritten as:

if ( ! mysql_query( $sql ) ) {
    die( mysql_error() );
}

Still lame, but with improved readability.

Of course, you can do nifty tricks with this kind of constructs:

is_numeric ( $_GET['id'] ) || redirect( '/my/error/url' );

Cool!

Dynamic or variable variables in PHP

Posted on Tuesday, February 3rd, 2009 under , , ,

Variable variables (or their official name – pointed out by Ionut Stan in the comments) or “dynamic variables” (how I like to call them) is the name of a feature of the PHP programming language which allows a programmer to define a variable that has its name given by the content of another variable. Like such:

$foo = 'bar';
/*
 * declare a variable called bar into the 
 * current scope and initialise it with Hello world
 */
$$foo = 'Hello world';
 
echo $bar; // will echo Hello world

If find this really useless and very annoying, because a typo such as a double dollar sign in front of a variable can result in some very hard to track bugs. But this isn’t just another strange feature that made its way into the trunk. This is very, very well implemented and some programmers strived a lot to make it work under all possible circumstances. It works so well that you can use strings that cannot be normally used to represent variable names, such as !@#$%^&*()_+-=/*. Really, it works!

$foo = '!@#$%^&*()_+-=/*';
$$foo = 'Hello world';
 
$variables = get_defined_vars();
echo $variables['!@#$%^&*()_+-=/*']; 
/**
 * will echo Hello world - the content of a variable called !@#$%^&*()_+-=/*
 */

Further more, it even works with objects:

class Example {
     /**
      * sample attribute
      * 
      * @var string
      */
     private $value;
 
     /**
      * default constructor
      * 
      * @param $_value
      */
     public function __construct( $_value ) {
          $this->value = (string) $_value;
     }
 
     /**
      * returns a string representation
      * of this object
      * 
      * @return string
      */
     public function __toString() {
          return $this->value;
     }
}
 
$foo = new Example( 'bar' );
$$foo = 'Hello world';
 
echo $bar; // will echo Hello world

I think this one of those features reserved for the most gurus of the gurus, because after 5 years experience with PHP and a Zend Certification, I haven’t yet grasped the logic behind this…

Multithreading in php

Posted on Friday, January 2nd, 2009 under , ,

Some time ago, I’ve wrote a small server in PHP. Nothing fancy. It would listen on a socket and when a new client would connect, the server would start a new thread and manage the client’s request. Since threading it’s not available in PHP, I’ve emulated the threads with child processes which are available in php. A thread object simply encapsulates a new process started with pnctl_fork() and emulates – to some extent – the behaviour of the java.lang.Thread class, the main difference being that in my implementation, you don’t extend the Thread class, you simply provide the name of a callback function in the constructor.

A simple multithreaded application would look like this:

require_once( 'Thread.php' );
 
// test to see if threading is available
if( ! Thread::available() ) {
	die( 'Threads not supported' );
}
 
// function to be ran on separate threads
function paralel( $_limit, $_name ) {
	for ( $index = 0; $index < $_limit; $index++ ) {
		echo 'Now running thread ' . $_name . PHP_EOL;
		sleep( 1 );
	}
}
 
// create 2 thread objects
$t1 = new Thread( 'paralel' );
$t2 = new Thread( 'paralel' );
 
// start them
$t1->start( 10, 't1' );
$t2->start( 10, 't2' );
 
// keep the program running until the threads finish
while( $t1->isAlive() && $t2->isAlive() ) {
 
}

This will display Now running thread 1 and Now running thread 2 messages with 1 second delays. I know, not that impressive, but hey, it’s multithreaded. Keep reading»