33 views

CHAPTER 13 - OTHER CHANGES

Although the compatibility mode covers a few changes between PHP 4 and
PHP 5, it does not fix all possible changes. For example, PHP 5 does not allow
assigning to $this, which is a problem for a few PEAR classes (at the time of
this writing). For example, the Pager/Pager.php file has the following code in
its constructor:
$mode = (isset($options['mode']) ? $options['mode'] : ‘Jumping’);
$pager_class = ‘Pager_’ . ucfirst($mode);
$pager_classfile = ‘Pager’ . DIRECTORY_SEPARATOR . $mode . ‘.php’;
require_once $pager_classfile;
$this = new $pager_class($options);
Another PHP 5 change not reverted by compatibility mode is the behav-
ior of get_class().

Assigning to $this
When you use a line in PHP 4 that assigns a value to $this inside a class,
depending on an option, a class is selected and an instance to that newly cre-
ated class is returned. Simplified, the code looks like this (with the offending
line in bold):
<?php
class Jumping {
}

class Sliding {
}

class Pager {
function Pager($type)

{
$this = new $type;
}
}

$pager = new Pager(’Jumping’);
?>
Assigning a new object to $this does not work in PHP 5. When the script
runs, it throws the following error:
Fatal error: Cannot re-assign $this in /book/13-making-the-move/oo
assign-to-this.php on line 11
The only solution for this problem is to redesign the classes. In this case,
an alternative that works with both PHP 4 and PHP 5 is
<?php
class Pager {
function Pager($options)
{
var_dump($options);
}
}

class Jumping extends Pager {
function Jumping($options)
{
Pager::Pager($options);
}
}

class Sliding extends Pager {
function Jumping($options)
{
Pager::Pager($options);
}
}

$pager = new Jumping(’foo’);
?>

Assigning to $this can also be used to “emulate” an exception, which is
necessary because you cannot return errors from a constructor. For example,
the Net_Curl PEAR package has the following in its constructor:
function Net_Curl()
{

$ch = curl_init();
if (!$ch) {
$this =
new PEAR_Error(”Couldn’t initialize a new curl handle”);
}

}
This is used to emulate an exception. In PHP 5, the correct way would be
to use an . . . exception. For this to work, the PEAR_Error class needs to extend
the internal PHP Exception class. In the examples here, we suppose a new
PEAR error mechanism with PEAR_Exception is used, but the PEAR project
doesn’t yet know how they are solving it at the time of writing. The rewritten
constructor might look like this:
function Net_Curl()
{

$ch = curl_init();
if (!$ch) {
throw
PEAR_Exception(”Couldn’t initialize a new curl handle”);
}
}
Besides changing the constructor, code that uses this class needs to be
changed to catch the exception too, as in
try {
$curl = new Net_Curl();
} catch {

}
Unfortunately, this code will not work in PHP 4. You can support both
PHP 4 and PHP 5 by using a new approach to the class implementation–for
example, with a singleton pattern. An example might be
<?php
require_once “PEAR.php”;
class Net_Curl {
var $type;
function Net_Curl($type) {
$this->__construct($type);
}
function __construct($type) {
$this->type = $type;
}
function singleton($type) {
if ($type == “lala”) {
return PEAR::raiseError(”Unable to do foo.”);
} else {
return new Net_Curl($type);
}
}
}
$instance = Net_Curl::singleton(”lala”);
if (PEAR::isError($instance)) {
die(”Error: ” . $instance->getMessage() . “\n”);
}
echo $instance->type . “\n”;
?>
Tip: To find assignments to $this in your own code, you can use the UNIX
tool grep:
egrep -r ‘\$this\s+=’ *
This command finds all instances in this directory and all subdirectories
where an assignment to $this is made.

get_class
Although PHP 4 always returns the class name with lowercased letters, in PHP 5,
the get_class() function returns the case-preserved version of the class name:
<?php
class BookPage {
}
$page = new BookPage;
$name = get_class($page);
echo $name, “\n”;
?>

The output is bookpage in PHP 4 and BookPage in PHP 5. If you need to
rely on the PHP 4 behavior, use the following code instead:
$name = strtolower(get_class($page));
echo $name, “\n”;
This code works for both PHP 4 and PHP 5.

Post a Comment

You must be logged in to post a comment.