11

I have some PHP 5.3 code which builds an array to be passed to a view. This is the code I have.

# Select all this users links.
$data = $this->link_model->select_user_id($this->user->id);
if (count($data) > 0) {
    # Process the data into the table format.
    $table = array
    (
        'properties' => array
        (
            'delete_link_column' => 0,
        ),
        'callbacks' => array
        (
            # Callback for the name link.
            function($value) {
                return sprintf('<a href="/links/view/name/%s">%s</a>', $value, $value);
            },
            # Callback for the category link.
            function($value) {
                return sprintf('<a href="/category/view/name/%s">%s</a>', $value, $value);
            },
            # Callback for the creation date.
            function($value) {
                return date('jS M Y', $value);
            },
            # Callback for the delete link.
            function($value) {
                return sprintf('<a href="links/delete/name/%s">delete</a>', $value);
            },
        ),
        'columns' => array
        (
            'name', 'category', 'creation date',
        ),
        'data' => array
        (

        ),
        'sorting' => array
        (
            'sort' => false,
        ),
    );

However the problem is that I cannot use anonymous functions in PHP 5.2, which is the server I must upload this schoolwork. The view requires callback functions to be defined so it can call them.

What would be the neatest way to convert this PHP code to not using anonymous functions? Thanks.

2
  • 1
    When and how and why are theses callbacks called? Commented Sep 28, 2010 at 3:12
  • @deceze This array is passed to a view which processes the array and creates a table from the data. The callbacks are called for the data in each column to format the data. So if a table cell value was 'Boats' in the first column, the view would process that into the value '<a href="/links/view/name/Boats">Boats</a> I didn't really want to change the view because I have alot of controllers using it like this. Commented Sep 28, 2010 at 3:15

2 Answers 2

8

You could call one of those function like so:

$func = $callbacks[0];
$func();

Which also works with create_function() and using strings for named functions like so:

function test() {
  echo "test";
}
$func = 'test';
$func();

$func = create_function('' , 'echo "test 2"; ');
$func();

Also, if the calling is done using call_user_func you can use array($object, 'func_name') to call a public method on an object or a class with array('Class_Name', 'func_name'):

class Test {
  public static function staticTest() { echo "Static Test"; }
  public function methodTest() { echo "Test"; }

  public function runTests() {
    $test = array('Test', 'staticTest');
    call_user_func($test);

    $test = array($this, 'methodTest');
    call_user_func($test);
  }
}

$test = new Test();
$test->runTests();
Sign up to request clarification or add additional context in comments.

Comments

8

Anonymous functions are great for ephemeral one-offs, like event listeners in patterns like Observer.

However, since you've already formalized an interface (callbacks for rendering names, categories, creation dates, and a delete link) you may as well go the extra step of defining a 'renderer' interface that requires those 4 methods to be implemented. Instead of passing callbacks you'd pass a single renderer subclass to the view, which could then be used to call the appropriate methods. The view could also validate it by checking the parent class. That would still allow you to swap renderers in the spirit of portable, reusable OOP without requiring anonymous functions.

Is there a situation where your callbacks would ever be coming from arbitrary code (e.g. plugins)? If not, there's really no benefit to making those callbacks anonymous. It might seem like you're saving a little namespace bloat, but you're also making it tougher to debug or document.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.