Archive for the 'php' Category

Practical example php implementation of the Observer pattern

October 12, 2010

Observer is a pattern where an object called the subject maintains a list of dependents (observers) and notifies them of any state changes. I implemented this recently to log changes to an Account object, and to notify the account holder if their account had expired – here’s the basics of the code, hopefully it’ll help someone else figure out how the pattern works

<?php
interface Observer
{
 public function update(Observable $subject);
} 

interface Observable
{
 public function attachObserver(Observer $dependent);
 public function detachObserver(Observer $dependent);
 public function notify();
}

class Account implements Observable
{
 public $status;
 private $_observers = array();

 public function __construct()
 {
  $this->attachObserver(new Logger());
  $this->attachObserver(new Mailer());
 }

 public function attachObserver(Observer $object)
 {
  $this->_observers[] = $object;
 }

 public function detachObserver(Observer $object)
 {
  foreach ($this->_observers as $index => $observer) {
   if ($object == $observer) {
    unset($this->_observers[$index]);
   }
  }
 }

 public function notify()
 {
  foreach ($this->_observers as $observer) {
   $observer->update($this);
  }
 }

 public function save()
 {
  $this->notify($this);
  $this->notify();
 }
}

class Logger implements Observer
{
 public function update(Observable $subject)
 {
 //Update status in log table
 echo "Updating status in log table.\n";
 }
}

class Mailer implements Observer
{
 public function update(Observable $subject)
 {
 switch (get_class($subject)) {      
 case "Account":
 if ($subject->status == "Expired") {
 //send email: "account expired"
 echo "Sending account expired email.\n";
 }
 }
 }
}

$account = new Account();
$account->status = "Expired";
$account->save();

The interfaces aren’t strictly necessary, but they help make the whole thing clearer (I hope).

$this->notify($this);

Call a MODx snippet from within a snippet

April 22, 2010

This is really just  a note to remind myself how to to it, I keep forgetting:

$modx->runSnippet(string $snippetName [, array $params]);

http://wiki.modxcms.com/index.php/API:runSnippet

Managing which fields are displayed in a form in the MODx manager

April 2, 2010

There’s a plugin called managermanager, and the rules are set in /assets/plugins/managermanager/mm_rules.inc.php

You can hide fields, tabs and templates from the template dropdown for particular user roles. Handy for uncluttering your admin interface

Last resort debugging

September 4, 2009

When all else fails, I use The Scientific Method:

  1. comment out half the code
  2. see if I still get the bug
  3. if no then uncomment half the commented-out code and go to step 2
  4. if yes then comment out half the un-commented-out code and go to step 2

It’s fairly rare I need to do this in php, but currently hacking in vbscript which I don’t know at all …

phpunit bootstrap not working in windows

July 8, 2009

While following this tutorial and trying to set up phpunit to work with the Zend Framework, I couldn’t for the life of me figure out why my phpunit bootstrap seemed to be having no effect whatsoever. When I did figure it out, the problem was an old version of phpunit (3.3.2 instead of 3.3.17) – to update it I had to type (on the windows command line)

pear upgrade pear

and then

pear uninstall phpunit/PHPUnit

and then

pear install --alldeps phpunit/PHPUnit

Enhancing wordpress themes with regular expressions

June 22, 2009

I’ve been using wordpress quite a bit lately, and didn’t seem to be able to do something I wanted within the confines of a regular wordpress theme. Regular expressions came to the rescue – you can just use them in your theme and plugin files to do more-or-less anything you want with the content.

Here’s how I extracted the images so that they weren’t displayed within the post but instead in another div separate from the post text:

$images = ""; $matches = array();
if (preg_match_all("/(<img[^>]*>)/iUs",$content,$matches)) {
    $images = implode(" ",$matches[1]);
    $content = preg_replace("/<img[^>]*>/iUs","",$content);
}
$content = "<div class=\"text\">$content</div>".
           "<div class=\"images\">$images</div>\n";

See what I did? I grabbed all the image tags out of $content with preg_match_all(), put them all into the variable $images, and then got rid of them all in $content using preg_replace(). Then I displayed $content and $images in separate divs.

You can use it on a page level too – on the index.php page of a theme, say, you can do an ob_start() to buffer the content, then ob_get_clean() it into a variable and manipulate the variable with regular expressions before echoing it out. So, for example, you could extract all the images or links (or whatever) from the content and display them somewhere else on the page.

jpg not displaying in nokia browser

March 30, 2009

Ok so I’m doing a mobile website. When my application receives a GET request for an image, it uses wurfl to check the User-Agent header and figure out what phone the user has, then resizes the image accordingly (with caching, obviously).

It seemed to work fine on every phone in the office except my own – on mine (a basic nokia 2600) the image seemed to download, but just wouldn’t display (I was left with a correctly-sized blank instead). I could see the image was being generated and cached, and I could even save it on the phone, but when I tried to look at it it wouldn’t display.

Discovered it worked ok for gifs, and eventually I figured out the problem was jpeg image interlacing. The phone doesn’t seem to support it – turned it off and it works fine.

Triggers within php objects using the __set() magic method

February 3, 2009

I don’t know if “trigger” is the right word for this behaviour, but if you want to automatically cause something to happen when an object variable is updated you can do so like this:

<?php
class classWithTrigger
{
    private $varOne = 0;
    private $varTwo = 0;

    public function __set($varName,$varValue)
    {
        $this->$varName = $varValue;
        if ($varName == "varOne") {
            $this->varTwo = $this->varOne * 9;
        }
    }

    public function __get($varValue)
    {
        return $this->$varValue;
    }
}

$test = new classWithTrigger;

echo $test->varOne; // Outputs 0
echo $test->varTwo; // Outputs 0

$test->varOne = 1;

echo $test->varOne; // Outputs 1
echo $test->varTwo; // Outputs 9

The __get() method gets called whenever an attempt is made (from outside the class) to get the value of an undefined or inaccessible (private or protected) variable – in this case it just returns the value as it would if the variable was public. Similarly, the __set() method gets called whenever an attempt is made (from outside the class) to set the value of an undefined or inaccessible variable. As you can see, you can use the fact that this gets called to trigger something, whether it’s an update to another object variable like here, or a DB update, or anything else you can think of.

Read-only object variables in php using magic methods

January 22, 2009

You can create read-only object variables by using the “private” keyword and the __get() and __set() magic methods like this:

<?php
class classWithReadOnlyVar
{
    private $readOnlyVar;

    public function __get($varName)
    {
        return $this->$varName;
    }

    public function __set($varName,$varValue)
    {
    }
}

So now classWithReadOnlyVar::readOnlyVar is only settable from inside the class, but you can read it from anywhere. For example, if you add the above constructor to the code above:

    public function __construct()
    {
        $this->readOnlyVar = "foo";
    }

Then the following code:

$test = new classWithReadOnlyVar();
echo $test->readOnlyVar;

$test->readOnlyVar = "bar";
echo $test->readOnlyVar;

has this output:

foo
foo

Zend_Db_Adapter::update() returns number of rows in which values have been changed

December 5, 2008

… and not the number of rows that match the conditions.

Just so you know. Caught me out for a while there – I was using the return value from update() to check that certain values (including a timestamp) were set correctly while at the same time updating the timestamp, but if the method got called twice in a second I’d get zero as a return value the 2nd time because the timestamp was the same and so no values were being changed.