PHP

I Want a goto and I Want it NOW!

This evening I was working on testing some code that is called by AJAX. It returns a string which is either "OK", if everything is fine or something else, if it isn't. If something else is returned the user is alerted.

So to test this I pull it into my test framework - except that the calls to "exit" mess everything up and make the test framework exit too. wget and curl are too clunky so, proceeding with the elegant solution I need to change the code so that instead of exiting it jumps to the end of the script, that way it will return to the test suite even if there is a problem. I'm sure PHP has a GOTO so go look in the documentation - its 5.30 - nightmare!

So instead move the AJAX code into a function and change the exit calls to be returns. Ta-da unit testable AJAX.

Still this is a milestone. The first time in my life I ever wanted a goto.

PHP exec unlike other execs

In PHP the exec call is part of a family of calls that can run commands on the server. These include system, passthru and shell_exec. They all offer slightly different functionality and all require careful security audit to ensure that you do not allow unscrupulous users of your site access to the operating system.

An empty abstract class can be useful

I've been working on a system that takes different types of things in an order. The order system is split up by the type of the thing beng ordered, which isn't very clever but historically that's the way someone wrote it so we just have to live with it, refactoring the code and data is not an option.

In modelling the data for the differnet types of thing being ordered it turns out to be useful to have an empty abstract class:

abstract class AbstractOrderItem implements Model {
// Add a constructor to initialise the model
}

Now order items extend AbstractOrderItem:

class CarOrderItem extends AbstractOrderItem ...
class PlaneOrderItem extends AbstractOrderItem ...
class TrainOrderItem extends AbstractOrderItem ...

Now it you want to handle a list of OrderItems that's fine:

    function paintBlue(AbstractOrderItem $item) {
      $item->color='blue';
      $item->save();
    }
  

Simple PHP Copy vs Clone Example

Assigning object instances results in assigning references:

<?php
class s {
  public $state = 1;
}

$s = new s();
$t=$s;

$s->state=4;

echo "s state ".$s->state."\n";
echo "t state ".$t->state."\n";

s state 4
t state 4

Using clone creates a shallow copy of the object. (Add a __clone() method to define your own deep copy. See http://php.net/manual/en/language.oop5.cloning.php)

<?php

class s {
  public $state = 1;
}

$s = new s();
$t=clone $s;

$s->state=4;

echo "s state ".$s->state."\n";
echo "t state ".$t->state."\n";

s state 4
t state 1

Note: Use debug_zval_dump() to see the reference count for a variable.

When to Refactor

Today I found a class file that had been created with 1161 lines in it. Files this big should immediately ring alarm bells because the class they contain is almost certainly doing too many things. Class files this big are inevitably difficult to test and sure enough the test file was about 1700 lines.

Some guidelines on when to refactor:

  • The class is doing more than one thing.
  • You can't get a method on one screen.
  • There is poor on non existent documentation.
  • There is poor or no unit testing.

Why Stuff2send.com was Such a Success

In just 7 weeks of November and December 2008 I wrote the initial code for http://www.stuff2send.com, a site which allows people travelling round the country to earn extra money by delivering packages as part of their journey. The site, which included Google Map and PayPal integration, went live on time and within budget and support and development was then taken over by the brilliant Tom and Lisa at 18aproductions.com.

Comments: Who are you talking to?

I've always thought that the best programmers have the worst memories. The reason is simple. If you have a bad memeory you have to write your code in a way that you will understand it in the future. If you have a good memory you can do what you like, give variables stupid names, make the code as unreadable as you like - you can rely on your memory to help you out when you revisit the code.

How method scope affects functionality

Its not always obvious which method gets called when overloading methods with different access controls and calling them from the parent class. Consider:

<?php
class C1 {
  public function __construct() {
    $this->go();
  }

  private function go() {
    echo "In the C1::go()\n";
  }
}

class C2 extends C1 {
  public function __construct() {
    parent::__construct();
  }

  protected function go() {
    echo "In the C2::go()\n";
  }
}
$c=new C2();


The output is "In the C1::go()"

Now consider:

class C1 {

Another thing you can't do with PHP

I want to run a test that should take less than a second but could perhaps get into a longer / infinite loop, so I want to set a timer interrupt to go off in 1 seconds time and handle the exception it generates to force a test failure.

What is the probability of being able to do this with PHP?

Building PHP from scratch - Tests Fail

I've just built 2 copies of PHP 5.2.9 from scratch on different linux versions (with very slightly different configurations).

In the first case make test returns 40 errors (from 6529 tests) (0.6% of tests which were run fail) In the second case 54 (0.8%) of 6550 tests fail.

That's a lot of tests failing. It should build cleanly.

Did all tests run when 5.2.9 was released? Who knows. Maybe its just developers failing to run and update tests when code is updated. Maybe its even more serious.

Mimicing overriden methods in PHP

PHP's lack of support for overriding methods is a real performance hog. You have to work out what the programmer meant by the types of the parameters sent to the method manually. All this takes time and has to be done every time the method is called.

You end up with code that looks like this:

/**
* I want to do something like calling myfunc(new Instance("thingstring")) or just
* myclass("thingstring");
*/
public function myfunc( $instance ) {
if (is_string($instance)) $instance=new Instance($instance);

Get a hold of $this

$this is spurious.
$this is almost never needed. If a variable is not available in local scope then it must be in class scope, so why on earth do I have to clutter my PHP classes with $this?

Another example of PHP lunacy

Guess what the output of the following code is:

<?php
error_reporting(E_ALL|E_STRICT);
session_write_close();

Answer: Nothing. PHP lets you try to close a session that was never opened and doesn't even murmur a warning.

OO PHP5

The lack of proper OO capabilities in PHP makes me want to scream. For example operator overloading and method overloading are so fundamental to what everyone else is doing with OO code. These are really essential areas of OO design that PHP just chooses to ignore.

Why can't the PHP designers just bite the bullet and make everything a proper class and do the job properly instead of the half-baked pseudo-OO currently offered?

Will PHP 6 be any better? Somehow I doubt it.

Syndicate content