Tudor Barbu's blog

Ramblings about software development

03 Apr

Logical operators in PHP

Posted by Tudor. Tags: , ,

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 C++ – 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!

27 Mar

CSS magik

Posted by Tudor. Tags: ,

Although I’m not a designer and I only know about 10 colors, I’m a great fan of the client side disciplines. I like nifty pieces of CSS, I enjoy coding in Javascript and I advocate semantic web. Unfortunately, my job focuses more on the server-side these days, but that doesn’t mean that I can’t have a look from time to time over some CSS tutorials.

This time, I’ve tried this tutorial, written by Eric Meyer. Pretty nifty! I’ve decided to give it a try myself, and I drew a house. And made a CSS love declaration to my girlfriend, here.

Pretty cool, isn’t it? And, perhaps, web 2.0 will mean another transition, from ASCII art to CSS art :)

16 Feb

Exploding new lines in PHP

Posted by Tudor. Tags: ,

One question I get a lot is “how do I explode a string into lines?”. The “default” approach, not necessarily bad, is the following:

$lines = explode( "\n", $string );

This is pretty simple and self explanatory. Use PHP’s explode() function and pass the newline \n character as a delimiter. This should work and yet, in some “strange” cases, it does not. First of all, the newline character or sequence of characters differs from OS to OS. On Microsoft operating systems, the newline is represented by a sequence of \r\n (carriage return – ASCII 10 & line feed – ASCII 13). On older Mac Operating Systems the newline char is \r (carriage return) while on *nix systems is \n. So the correct way to break a string into lines is to use all three of them as delimiters. The easiest way is with regular expressions and preg_split().

$lines = preg_split( '/\r\n|\r|\n/', $string );

If you have enough free time on your hands, you can try strtok or other, more exotic, methods.

I’ve came across a strange error today in PHP. Something like:

Fatal error: Can’t use method return value in write context in {file_path}

This error is trigger by PHP’s empty language construct, because empty() can only be used on variables and not on function returns.

function f() {
    return 'Hello world';
}

// bad - will trigger an E_ERROR level exception, killing the script
if( empty( f() ) ) {
    // do something
}

// good - it works as expected
$variable = f();
if( empty( $variable ) ) {
    // do something
}

Kinda lame…

08 Feb

Prepared statements

Posted by Tudor. Tags: , ,

While studing for the ZCE exam, I’ve read a lot about prepared statements, especially prepared statements with PDO. According to the textbook, using prepared statements in repetitive queries (such as inserting multiple rows in the database and so on) can lead to a substantial improvement due to the fact that the query is compiled one time and the the values are quoted and put in place, whereas in the “traditional” way, a query is compiled every time it’s executed.

So I’ve decided to give it a try, and see how faster prepared statements actually are. To give the test some objectivity and relevance, I’ve calculated the amount of time required for 1000 inserts, repeated this operation 100 times and computed the average execution time. Read the rest of this entry »

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…

Few weeks ago I was in the middle of a debate with my girlfriend – which is also a programmer – about the increment unary operator. The main topic was what will the following code display:

$i = 1;
$i = $i++;
echo $i;

I said 1, she said 2. Of course, I was right in the end. But we were having this conversation while we were heading out to meet some friends, so, inevitably, others were drawn into the debate. One of which is Costin, who posted on his blog an entry called The trials and tribulations of the C incrementer on this subject. Long story short, if you post increment a variable, this operation will take place last and its result will be poped first from the stack and in some cases will be lost (our case – read Costin’s post for more details).

Other annoying examples using the increment operator:

$i = 1;
function someFunction( $_value ) {
    echo $_value;
}

someFunction( $i++ ); // will display 1
someFunction( ++$i ); // will display 2

$j = 1;
$j = ++$j;
echo $j; // will display 2

And again, the ZCE exam features this kind of questions.

19 Jan

Variable interchange

Posted by Tudor. Tags: , , ,

How to interchange 2 variables? A simple question with a simple answer. Most people will do it like this:

// interchanging using a temporary variable
$a = 2;
$b = 3;

$temp = $a;
$a = $b;
$b = $temp;

echo $a . ' ' . $b . PHP_EOL; // will display 3 2

Quite elementary. But it can be done in a much more elegant manner, using arithmetical (addition & subtraction) or logical (xor) operators. Read the rest of this entry »

02 Jan

Force download in php

Posted by Tudor. Tags: ,

Sometimes you need the browser to download a resource – like an image or a pdf file – but instead of poping up the “Save link as” window, the browser opens the content in a new window. The reason why this happens is quite simple: the browser receives a header from the server containing the file’s MIME type. The browser then checks to see if it has a handler for that MIME type and if it does, it displays the content in a window, using the handler to parse the data. If it doesn’t find any suitable handler, the browser opens the download dialog. That’s why, by default, when you click on a pdf, the browser opens the download dialog, but if you install Adobe’s Reader, then the pdf is open within a browser window, because now the browser “knows” how to interpret pdf data.

If you want the browser to always download a file, you must send that file to the browser as binary data, with no specific MIME type. The php snippet below does just that.

/**
 * forces the browser to download a file rather than open it
 * very useful if you want to download images
 */
if ( !file_exists( $url ) )
{
	header( 'HTTP/1.0 404 Not Found' );
	die();
}

session_cache_limiter( 'none' );
@ set_time_limit( 0 );

header( 'Cache-Control: must-revalidate, post-check=0, pre-check=0');
header( 'Content-Description: File Transfer');
header( 'Content-Type: application/octet-stream');
header( 'Content-Length: ' . filesize( $url ) );
header( 'Content-Disposition: attachment; filename=' . basename( $url ) );
readfile( $url );

Enjoy!