Archive for the 'PHP certification' Category

IE9 and JPEG-XR: first impressions

Monday, April 5th, 2010

One of the new features in IE9 is the support for the JPEG-XR format, which reportedly has a better compression. Is it something we should dive into ASAP?

JPEG-XR

The wikipedia article is here. This format is developed and patented (red flag!) by Microsoft (yellow flag! :) ), it replaces the suggested JPEG-2000 format and is an official standard as of mid '09. It's formerly known as "HD photo" and "Microsoft something something" and is heavily used in Vista and Windows 7 - two OSes I'm yet to experience. Anyway.

The wikipedia article says that the format has a better compression, so I had to take a look at it!

Software support

That's where the problems start. The list of software that supports the format is not too long and most of the software just reads it, like IE9. IE9 doesn't run on XP, so I couldn't actually test it.

What I managed to try was:

  • a plugin for Paint.NET that read/writes JPEG-XR
  • a 60-day trial version of MS' Expression Design 3 that reads/writes - this required an upgrade of my .Net platform, so the whole process took forever on the poor XP VMWare (but hey, I have a book to finish, so no distraction is too long!)
  • a plugin for IrfanView that reads the format

Nothing for Mac though.

There's rumors all over the place that MS have a beta version of a Photoshop plugin that works on the Mac, but even the MS' press release linked to a 404. (which redirected to a bing search - here's the secret to gaining search market share!)

Actually before I digged into these programs, my first instinct was to check if ImageMagick supports this format. Turns out no. IMagick used libjpeg like pretty much all image programs out there and curiously enough here's what libjpeg's README has to say:

FILE FORMAT WARS
================

The ISO JPEG standards committee actually promotes different formats like
JPEG-2000 or JPEG-XR which are incompatible with original DCT-based JPEG
and which are based on faulty technologies.  IJG therefore does not and
will not support such momentary mistakes (see REFERENCES).
We have little or no sympathy for the promotion of these formats.  Indeed,
one of the original reasons for developing this free software was to help
force convergence on common, interoperable format standards for JPEG files.
Don't use an incompatible file format!
(In any case, our decoder will remain capable of reading existing JPEG
image files indefinitely.)

Sounds like another red flag to me. IDG (Independent JPEG Group) are the creators of libjpeg. If libjpeg doesn't sounds like it will support it JPEG-XR, that means adoption can be really slow if not feasible at all. But even if IE is the only browser under the sun that supports the format and the format is so much better, then there might be cases where it could be beneficial to browser-sniff and send different image versions, as far-fetched as that may sound.

Test in Paint.NET

I started with Paint.NET because it was the easiest. I took a photo I've taken with the iPhone, keeping the use case real, and resized to a 600x450px which sounds like a normal thing to do in a blog post for example. I used IrfanView and PNG, so that the original is lossless (click the thumb for the actual source image).

I converted the photo with Paint.NET to JPEG and to JPEG-XR (also called WDP/HD Photo). In both cases I used quality of 80%. There was also an option for WDP which was 32bit image by default, which I changed to 24 bits because the image was smaller filesize.

WDP export in Paint.NET

The results were - 45K for XR/WDP and 24K for JPEG. So the good old JPEG was smaller - the exact opposite of what should've happened. Additionally JPEGTran shaved off another 1.3K from the file. Seemed like JPEG-XR is not that good after all. But as I said I had a book to write so I kept going with the distractions, determined to avoid writing for as long as I can.

Test with Expression Design

Expression Design produced the exact same WDP/HD Photo/JPEG-XR file - 45K. And this is not surprising actually, since there is an image framework from MS, called WIC, part of .Net, which is probably what Paint.NET and Expression Design both use. But surprisingly enough the JPEG outcome from Expression Design was significantly bigger - 57K. What?!

Then I looked at the visual quality and the number of colors and it turned out the JPEGs were pretty different, although they were converted from the same PNG and using 80% in both programs.

Software/Format JPEG JPEG-XR aka WDP aka HD Photo
Paint.NET 24K (50 000+ colors) 45K (104 000+ colors)
Expression Design 57K (54 000+ colors)

Visually the JPEG from Paint.NET is clearly lower quality than the one from Expression Design and from the WDP format. Interestingly, IrfanView produced an pretty much identical file when converting the PNG to JPEG with quality 80. So Expression Design seems to be doing something differently.

Using IrfanView I increased the quality of the JPEG until the file size reaches the file size of the WDP. (After all, all I want to know is which format has the smaller filesize). The quality of 93 resulted in a JPEG that was about the same file size as quality 80 JPEG-XR. Then I tried so look at the visual quality and although I'm not a designer, it seemed to me that the two images are pretty identical and XR is maybe just a little better. But that's a little subjective.

Here's the two files for comparison. Let me know which one you think is better. In this case they are both losslessly converted to PNG, so all browsers can see the WDP.

Here's also an image diff (from ImageMagick's compare) - it shows that technically the two images are very different (the white dots are pixels with the exact same color values)

One other thing about Expression Design - when exporting WDR, it has a "transparency" checkbox ON. This results is bigger images, so make sure you turn it off when using, it makes no sense for photos.
Expression Design options

Batch conversion?

My motivation in this experiment was to see if there's a way (and a reason) to do a batch conversion of all JPEG imagery to JPEG-XR. This would be my favorite performance optimization - you run one script and wake up to a 5-10% less image bandwidth.

Looks like JPEG-XR could probably look better for the same filesize, meaning maybe a smaller filesize for the same quality. But it's not easy to decide when it comes to quality and certainly even harder for a machine (a simple batch conversion script) to tell. I was hoping that there's a way to losslessly convert to JPEG-XR. From what I can see, there isn't. JPEG-XR does have a lossless option but it creates huge files (like 250K instead of 45), so the lossless versions are not meant to be on the web. BTW, the lossless option is the same as 100 quality (which is not the same in normal JPEG, where even 100% is lossy).

So, in conclusion - JPEG-XR may look promising but is currently unusable for practical purposes, because of

  • the extremely limited support in browsers (browser, actually),
  • very limited choices of creation software
  • the benefits are hard to distinguish
  • not possible to batch-and-forget process all old JPEGs

And there's the other turn off - patents. Although Microsoft has promised to promise not to sue people around for implementing JPEG-XR, a patent is a patent and all software patents must die on general principle :)

 

What’s $this?

Thursday, August 31st, 2006

Simple question, what's $this - a or b?

<?php
class a {
    function aa(){
        var_dump($this);
    }

}

class b {
    function bb(){
        a::aa();
    }

}

$b_obj = new b;
$b_obj->bb();
?>

Answer: object(b)#1 (0) { }

 

Resources are passed by reference

Wednesday, September 7th, 2005

When copying one resource to another, you're actually creating a reference to the original resource, this is not an actual copy.

This is illustrated by the following example:


echo '<pre>';
// create an image resource
$image = imagecreate(100, 100);

// print the resource
var_dump($image);
// the above prints "resource(30) of type (gd)"

// create a copy
// (actually creating a reference,
// although =& is not implicitly used)
$copy = $image;

// print the reference
var_dump($copy);

// the above prints "resource(30) of type (gd)", same as before

// destroy the image resource
imagedestroy($image);

// this prints "resource(30) of type (Unknown)"
// so the image was destroyed
var_dump($image);

// this also prints "resource(30) of type (Unknown)"
// meaning that the reference points to a destroyed image
var_dump($copy);

echo '</pre>';
 

Discount on the Zend PHP certification exam

Wednesday, August 24th, 2005

Expires August 31, $75 off the "normal" price of $200. For details and purchase, see the PHP certification section of the Zend.com site.

Zend are celebrating the 600th PHP certified engineer, so they've decided on this discount. Which is nice. $200 has always seemed a bit more than an open-source developer is willing to pay for an exam, so a discount is always appreciated ;) (I, myself, profited from another discount, offered at a local PHP conference earlier this year.)

 

My certification story

Friday, August 5th, 2005

Here are the stories of some guys that have passed the PHP certification exam already.

If you've been reading my blog, you already know my story. Here's everything I've written in this blog that is related to the Zend Cert exam.

 

Another PHP cert blog

Sunday, June 26th, 2005

Update 2007-01-04: Seems like this blog is dead and domain was apparently took over by one of those "search" copanies.

Recently I've been feeling kind of guilty for not posting much about PHP certification... ZCE PHP cert was the original purpose for which I started this blog but later on I moved to other PHP (and not only) related projects of mine.

Anyway, I still have a few PHP programming posts stored as drafts, these date back from the time I read the Certification guide and it is my intent to publish those as soon as I can. But for those blog readers who are subscribed to my blog RSS feeds, expecting more certification prep posts, there is "A new hope", a new blog.

It has been around for a few weeks, but it wasn't until today when I stumbled upon it. The URL is http://www.easyhttp.com/zce/ and the first post says: This blog meant to be daily dairy of ZCE candinate, to share experience with others, I will be posting a weekly update and might be daily *Depends on my laziness* about every topic I pass reading and practicing it, and every topic I stuck at.

Good luck to the new blog author, Jad Madi, and I hope everyone will find it useful and fun to read! Once again, the URL is: http://www.easyhttp.com/zce/.

 

Certification press release from Zend

Wednesday, June 22nd, 2005

Here it is »
Major corporations benefit from Zend certified engineers.

Every press release polishes the truth at least a little bit, but nevertheless this one sounds promising .

 

ZCE certificate

Saturday, May 21st, 2005
ZCE printed certificate
Click for a larger view of
the print certificate


ZCE logo
That's the ZCE logo / sticker

Wo-hoo! The printed certicate found its way to my wall :) Technically I received it on Tuesday (May 17th), which is about 6 weeks after the exam (March 31st), but being kinda busy I didn't have time to go to the post office and pick it up until yesterday.

The surprise was that it even came in a frame and with a ZCE sticker (still wondering where to place it...).

If the above doesn't make sense to you...

  • I took the exam to become a Zend Cetrified Engineer which basically means that I know my around some PHP coding (to say the least). More about me taking the PHP certification exam here...
  • I was blogging while preparing for the exam, just in case somebody else is preparing for the same exam and my thoughts can be of any help to them

Welcome to my PHP Certified.com blog :)

 

PHP certification books – sample chapters

Wednesday, May 4th, 2005

php|architect's "Zend PHP Certification Practice Book"
http://www.phparch.com/cert/ZPCPB_sample.pdf

Zend's official PHP certification study guide
http://phpcertguide.com/resources/sample.pdf

 

Zend Certified Engineer

Tuesday, April 26th, 2005

ZCE logoYep, it's a fact. Here's the proof.

I took the exam almost a month ago but waited so that most of the details are erased from my memory, so that I don't accidentally violate the exam's rules which state that you should not reveal information about the exam.

So I took the exam at a discounted price - just about a 100 Canadian dollars (1 CAD < 1 USD). There was a PHP conference in town , guys from Zend were attending and as part of the conference, Zend were offering the exam at such a price. I even get to speak to the guy himself, I mean Daniel Kushner, the guy responsible for the certification and the education at Zend.

There were a few surprises during the exam, both in terms of the exam questions and the administration of the exam.

The first surprise was that the test was paper based. My guess is that this was because the exam was administered as part of the conference, in a hotel, and not in a specially designed VUE test center. Well, actually there was another surprise before that and this was that one had to have a zend.com account and a registration ID in order to take the exam. I don't know if that has something to do with the fact that the exam was not administered in "normal" test center. Anyway, Daniel gave me his laptop so I was able to register pretty quickly.

The actual exam surprise was that I didn't have enough time! I've always been a fast test taker and have always completed the tests well before my classmates and I've always wondered why it takes them so much. It's either you know something or you don't. Well, in most cases. Well, it's actually either you think you know it or you don't. Or you don't remember. Or something :) Whatever. Then in addition to that, I've read a blog posting about this guy who said he completed the test in no time and then had enough time to go back and change most of the answers. So I expected to have enough time and I decided to play it safe and just "pencil" my answers on the answer sheet with a small dot and then to go back and review the answers. Well, the time was passing and I still haven't completed all the questions, so I gradually started filling out the circles completely when I was sure about my answer. In any event, I spent the last 5 or 10 minutes of the exam just filling out circles. I didn't have time to review any of my answers. I thought it's either the exam questions are too difficult or I'm just getting old. There was a total of 70 questions and I had hour and a half to complete the exam. So this makes a minute or so per question. In the last 10 questions you were expected to write down the answers as text, they were not just multiple-answers.

So my overall impression is that the exam should not be underestimated and some questions were a bit time-consuming. Not that you need to do calculations or something, but when it comes to regexps or several string functions combined... OK, I've said enough. In any case, I don't think there were trick questions (or I was tricked so I didn't notice) but there were a few occasions when I was sure a spotted the correct answer and I was finding even more correct ones :)

Good luck to everyone who is preparing for the exam! I'll keep on blogging on exam-related topics, I even have some unfinished blog entries from back then when I was preparing for the exam. And when I come across an interesting php tidbit that looks "examie" I'll make sure I drop it here. In case you haven't read my previous blog entries from back then when I was preparing for the exam, here's the PHP certification category.

So again good luck to everybody who's preparing for the exam! You can do it!

 

strcmp

Tuesday, March 29th, 2005

strcmp() compares two strings and gives -1, 0 or 1 depending on wheather the first string is "smaller", equal to or greater than the second one.

< ?php
echo strcmp('aa','bb'); // prints -1
echo strcmp('bb','bb'); // prints 0
echo strcmp('zz','yy'); // prints 1
?>

Thus being said there's an error in the php certification guide that explains the strcasecmp() function, which is the same as strcmp() only case insensitive. There is a snippet in the book that goes like:
< ?php
$a = 'hello';
if (strcasecmp($a, 'HELLO')) {
echo 'the same';
}?>
The book says that the echo will be executed but it will not, as the comparison will return 0, since 'hello' and 'HELLO' are the same string when regarded at case-insensitively.

 

serializing

Tuesday, March 29th, 2005

Serializing is a nice way to get a string out of more complicated data structure. It's probably mostly used to sting-alize array data, although you can serialize scalar data as well.

The result of the serialization is no nature wonder, it's just a string that describes what is serialized and a value of the serialized ... thing.

The cert guide explains it all very well, I think just maybe an example of how something looks when it's serialized would have been nice. Otherwise the serialization may sound scary and mysterious.

Here's an example:
< ?php
$s = 'PHP';
echo serialize($s);
?>
This prints:
s:3:"PHP";
Which means:

  • 's' is a string, the type of the serialized var
  • '3' is the length
  • 'PHP' is the value
  • ';' is a delimiter

A slightly more complicated example - serializing an array:

< ?php
$ar = array('PHP','key'=>'serialize');
echo serialize($ar);
?>
The result is:
a:2:{i:0;s:3:"PHP";s:3:"key";s:9:"serialize";}

  • 'a' means an array
  • 'i' as in integer
  • 'i:0' is the integer key of the first element of the array, remember when you don't specify a key, PHP assigns one
 

A character from a string

Tuesday, March 29th, 2005

You can get a specific character from a string as if the string was an array.
< ?php
$s = 'PHP';
echo $s[0]; // will print "P"
?>
This syntax may be confusing, because someone looking at the code might expect that $s is an array. Well it is an array, an array of characters, but that's not the point. The point is that if might be confusing.

The same result may be achieved with curly braces.
< ?php
$s = 'PHP';
echo $s{1}; // will print "H"
?>
The numbering is zero-based, the first character in the string has offset 0.

 

Array sorting options

Tuesday, March 29th, 2005

When sorting an array, for example by using sort() there are three constants you can use to determine how the sorting will work:

  • SORT_REGULAR (default) when you have mixed types of variables in the array it won't cast them. The results can be ... hmm .. interesting. It will sort first all string types and them all numeric types
  • SORT_NUMERIC - all elements will be casted to their numeric values
  • SORT_STRING - all array elements will be sorted as strings.

Here's an example of the three options:

< ?php
echo '

';
$a = array(3, 1, '01', '011', '0001', 'a', 'a0', 'b0', '0b0', '1a1', '0a0', 'xyz', '99a', 991, '992');
sort($a, SORT_REGULAR); // default
print_r($a);
sort($a, SORT_NUMERIC);
print_r($a);
sort($a, SORT_STRING);
print_r($a);
?>
The result will be:
Array
(
    [0] => 01
    [1] => 0001
    [2] => 011
    [3] => 0a0
    [4] => 0b0
    [5] => 1a1
    [6] => 992
    [7] => 99a
    [8] => a
    [9] => a0
    [10] => b0
    [11] => xyz
    [12] => 1
    [13] => 3
    [14] => 991
)
Array
(
    [0] => a0
    [1] => a
    [2] => 0b0
    [3] => 0a0
    [4] => xyz
    [5] => b0
    [6] => 01
    [7] => 1a1
    [8] => 0001
    [9] => 1
    [10] => 3
    [11] => 011
    [12] => 99a
    [13] => 991
    [14] => 992
)
Array
(
    [0] => 0001
    [1] => 01
    [2] => 011
    [3] => 0a0
    [4] => 0b0
    [5] => 1
    [6] => 1a1
    [7] => 3
    [8] => 991
    [9] => 992
    [10] => 99a
    [11] => a
    [12] => a0
    [13] => b0
    [14] => xyz
)
 

Walking the array

Tuesday, March 29th, 2005

The certification guide demonstrates what is probably the fastest (performance-wise) way to go through the elements of an array - using the array_walk() function. The example in the guide is using a callback function to use the elements of the array. But there's more than that.

Using the array_walk() function you can also make use of the keys of that array. And you can also pass to the walking callback function some values you may find appropriate - these are known as "user-defined" parameters.

An example that uses keys and values:
< ?php
// here's an array
$french_numbers = array('one' => 'une', 'two' => 'deux', 'three' => 'trois');

// the function we're going to call back
function dumpEm($value, $key) {
echo $key . ' - ' . $value . '
';
}

// call array_walk()
array_walk($french_numbers, 'dumpEm');
?>This example will produce:

one - une
two - deux
three - trois

You can see how the keys were also used. Now for the user-defined data you can pass to your callback function. This data can be of any type. Let's take an array as an example.
< ?php
// here's an array
$french_numbers = array('one' => 'une', 'two' => 'deux', 'three' => 'trois');

// the function we're going to call back
function dumpEm($value, $key, $legend) {
echo $key . '('. $legend['en'] .') - ' . $value . '('. $legend['fr'] .')
';
}

// call array_walk()
array_walk($french_numbers, 'dumpEm', array('en' => 'English', 'fr' => 'Fran?�ais'));
?>
This will produce:

one(English) - une(Fran?�ais)
two(English) - deux(Fran?�ais)
three(English) - trois(Fran?�ais)

Finally, you can change the array values you pass to the callback function. To do so, you need to pass those elements by reference. Note that you cannot do the same on the array keys though.
< ?php
// here's an array
$french_numbers = array('one' => 'une', 'two' => 'deux', 'three' => 'trois');

// the function we're going to call back
function dumpEm(&$value, &$key) {
$value = ucfirst($value);
$key = ucfirst($key);
echo $key . ' - ' . $value . '
';
}

// call array_walk()
array_walk($french_numbers, 'dumpEm');

print_r($french_numbers);
?>This will give you:

One - Une
Two - Deux
Three - Trois
Array ( [one] => Une [two] => Deux [three] => Trois )

 

Array keys and case sensitivity

Tuesday, March 29th, 2005

Yep, array keys are case sensitive.
So you can do:
< ?php
$a = array('key'=> 1, 'Key' => 2);
print_r($a);
?>and it will print

Array ( [key] => 1 [Key] => 2 )

Similarly if you call array_keys() on $a, like:
< ?php
$a = array('key'=> 1, 'Key' => 2);
print_r(array_keys($a));
?>...you'll get:

Array ( [0] => key [1] => Key )

Defining the same key in an array (even in the same array declaration) won't cause an error, but will result in the latest value taking precedence. Like:
< ?php
$a = array('key'=> 1, 'key' => 2);
print_r($a);
?>will output:

Array ( [key] => 2 )

 

The old superglobals

Tuesday, March 29th, 2005

Prior to php 4.1. there were no $_POST, $_GET, etc. superglobal arrays, but there were a bunch of other superglobals, like $HTTP_POST_VARS, $HTTP_GET_VARS and so on.
The guide mentions this in the forms chapter but there is a typo (repeated several times :) ) so I thought I should mention it.

The guide talks about these older vars with an underscore before the name, like $_HTTP_POST_VARS, $_HTTP_GET_VARS and so on which is not true. The correct names are $HTTP_POST_VARS, $HTTP_POST_VARS and so on, without the underscores.

BTW, a trick if you want use old code, written prior to 4.1.0. on newer php versions is to use something like:
< ?php
$_GET = &$HTTP_GET_VARS;
$_POST = &$HTTP_POST_VARS;
$_SERVER = &$HTTP_SERVER_VARS;
?>

 

Redefine $this?

Monday, March 28th, 2005

I was wondering - can you redefine the special variable $this when in a method of a class. It turns out that yes, you can.

Consider this class:
< ?php
class Some {
function Some(){}
function another(){
$this = 5;
var_dump($this);
}
}
?>
If you create an object and call the another() method, it will redefine $this and will make it an integer as opposed to an object.
< ?php
$s = new Some();
$s->another();
?>
This gives

int(5)

If you dump the instance after the method call it will still return 5, so it's not just a temporary re-definition.

Similarly, you can even destroy an object from within a method of the class, like
< ?php
class Some {
function Some(){}
function another(){
$this = null;
}
}

$s = new Some();
$s->another();
var_dump($s);
?>
This will output NULL.

 

Static methods and performance

Monday, March 28th, 2005

How fast/slow are the static methods?
I did a test once to try and figure that out.

It turns out:

  • Calling a method statically is just a bit faster than calling it "normally"
  • Calling a static method is twice as fast if your object didn't exist to begin with
  • Static methods are twice as slow than function calls

By calling statically I mean:
< ?php
Some_Class::someMethod();
?>
An calling "normally" is when you create an object and call the method using ->
< ?php
$sc = new Some_Class();
$sc->someMethod();
?>

 

Static methods and $this

Monday, March 28th, 2005

The book tells about static methods but it forgets to mention that you cannot use $this in static methods. A static method is pretty much like a normal stand-alone function is not aware about the object as a whole. So you can call the static method when no object of that class exists. In this case the method would have no idea what $this is.

 

Modulus

Monday, March 28th, 2005

Just a thought on the exam prep question 1.

The question in its essence is "How much is 3 - 5 % 3";
The answer is 1 because 5 % 3 is 2 and 3 - 2 is 1.

That's exactly what the book says but in the explanation of the correct answer there's a mistake saying that 5%2 is 2 when it should be 1.

So just a quickie - how the modulus thing works?
Well, it's starts with a division and then gives the reminder of the division that would give a whole number. In other words:

  • 5 % 3 is like 5 - 3 because 3 / 3 will give the whole number 1.
  • 5 % 2 is 5 - 4 because 4 /2 will give the whole number 2
  • 5 % 4 is 1 because 4/4 is a whole number and 5-4 is 1
  • 5 % 5 and 5 % 1 both give a nice round 0, because 5/5 gives the whole number 1 and there is no reminder. The same way 5 / 1 gives the whole number 5 and there is no reminder.

The important thing the guide mentions is that the modulus operation in php can give negative results unlike the modulus in the math. The result will be negative only if the first number is negative. I.e.
5 % (-2) = 1
while
-5 % 2 = -1

 

Superglobals

Monday, March 28th, 2005

So far (end of chapter 1, just before jumping into the OO part) the book doesn't say a word about superglobals. I think this is an important topic and I suppose there must be questions about the superglobals on the exam.

The best place to get an idea about the superglobals is this PHP.net manual entry.
Note how there was a different set of superglobals prior to php.4.1 but I was lead to believe that the exam is concentrated on stuff after 4.1. (and before php5).

Briefly, here's the list of superglobals:

  • $_GET - variables sent using a GET HTTP request
  • $_POST - variables sent using a POST HTTP request
  • $_COOKIE - array of all cookies that are sent by the server
  • $_REQUEST - a merge of the three above
  • $_SESSION - array containing the session data
  • $_SERVER - server variables like REMOTE_ADDR, SCRIPT_NAME, REQUEST_URI, etc.
  • $_ENV - more or less the same as $_SERVER
  • $_FILE - data about uploaded files
  • $GLOBALS - array of all global variables, see the previous blog entry for an example
 

Variable scope

Friday, March 25th, 2005

The certification book goes on with the calc_weeks example:

< ?php
function calc_weeks() {
$years += 10;
return $years * 52;
}
$years = 28;
echo calc_weeks();
?>

Exactly as the guide says, the $years var in the function won't get the 28 value, it will get a null instead. But then the guide says that the result of the function will be 0, while it is going to be 520.

Simply put the variables have visibility only in the brackets where they reside. That is, unless you global-ize them. Like:
< ?php
function calc_weeks() {
global $years;
$years += 10;
return $years * 52;
}
$years = 28;
echo calc_weeks();
?>

A different approach is to use a global variable by the $GLOBALS superglobal array. The example above will translate to
< ?php
function calc_weeks() {
$GLOBALS['years'] += 10;
return $GLOBALS['years'] * 52;
}
$years = 28;
echo calc_weeks();
?>

 

Function parameters passed by reference

Friday, March 25th, 2005

Consider the following example from the book that is supposed to illustrate how a parameter is passed to a function by reference, not by value.
< ?php
function calc_weeks(&$years) {
$my_years += 10;
return $my_years * 52;
}

$my_years = 28;
echo calc_weeks($my_years);
?>
Something wrong? Yes, the function calc_weeks() is taking $years parameter, passed by reference, but never uses it. Instead, the function uses $my_years, this is probably a typo. And if you run this code with error reporting set to E_ALL, you'll get a notice from the compiler, because we're trying to increment a variable ($my_years += 10;) but without initializing $my_years first.

So the correct way to do the example is
< ?php
function calc_weeks(&$years) {
$years += 10;
return $years * 52;
}

$my_years = 28;
echo calc_weeks($my_years);
?>

In terms of results, the first example will return 520 which is (null + 10) * 52. The second one will return (28 + 10) * 52.

 

Evaluating expressions in for-loops

Friday, March 25th, 2005

The usual syntax of a for-loop is
< ?php
for($i = 0; $i < 10; $i++){
// do your thing
}
?>

where

  1. $i = 0 is evaluated once before the loop starts
  2. $i < 10 is the condition of the loop, it's executed the number of times the loop executes plus 1. Why plus 1? Well the plus 1 is just to check we're at the end of the loop and no more looping is needed. In this example, this expression will be evaluated 11 times
  3. $i++ is an expression that executes after everything in the brackets is executed, i.e. at the end of each iteration. So in our example it's executed 10 times

The three expressions described above can be also function calls or something else, they are not necessarily always used as in the example above. Consider the next example as an illustration of how other functions can be called. All these functions print a line, so executing this will give you a visual idea what is executed, when and how many times.
< ?php
function start(){
echo '
start';
return 0;
}
function condition($i){
echo '
condition: ' . $i;
return 10;
}
function increment(&$i){
echo '
increment: ' . $i;
$i++;
}
for ($i = start(); $i < condition($i); increment($i)){
// do nothing
}
?>
The loop in this example is doing exactly the same as the first loop, only it's defined fancier, using functions and all the three functions print a line. Here's what the output of the script would be:

start
condition: 0
increment: 0
condition: 1
increment: 1
condition: 2
increment: 2
condition: 3
increment: 3
condition: 4
increment: 4
condition: 5
increment: 5
condition: 6
increment: 6
condition: 7
increment: 7
condition: 8
increment: 8
condition: 9
increment: 9
condition: 10

So just a word of caution - in the conditions, be careful not to you use potentially slow functions or expressions that return the same value every time they're exeuted, as they are going to be needlessly executed the loop count plus 1 times.

As a quick example:
< ?php
// not good
for ($i = 0; $i < 100*99%98+189*345/2*56-1; $i++) {
echo $i;
}
// better
$boundary = 100*99%98+189*345/2*56-1;
for ($i = 0; $i < $boundary; $i++) {
echo $i;
}
?>