PHP to Groovy bridge

The PHP Groovy Bridge in WebSphere sMash can be used to interact with Groovy objects, classes, closures and ranges. It also provides dynamic evaluation of Groovy code from PHP.

When to use the PHP to Groovy bridge

The Groovy bridge for PHP in IBM® WebSphere® sMash provides access to Groovy classes and functionality in PHP. This feature can help an application developer, for example, who wants to share a WebSphere sMash library built in Groovy with the rest of the community.

Note: Using the bridge requires PHP developers to read and understand the Groovy classes that they are accessing.

If you do not want PHP developers to have to understand Groovy classes you can write an extension to the PHP language using the extension interfaces described in the Extending PHP article. This enables you to provide a PHP view of the function provided by the Groovy class.

Example

The following code snippet shows how to access Groovy classes from a PHP script - first an example Groovy script:

class Import {
    def public FIELD = "Hello World!";
    def public static VALUE = "BlahBlahBlah";

    def getMessage() {
        return "Hello World!";
    }

    def static getStaticMessage() {
        return "Static Hello World!";
    }
}

The class defines some instance and static members (methods and fields). Here is a PHP snippet that uses the Groovy class:

<?php
groovy_import("import.groovy");

echo Import::getStaticMessage()."\n";
echo Import::$VALUE."\n";
Import::$VALUE = "FooBarGuff";
echo Import::$VALUE."\n";

$foo = new Import();
echo $foo->getMessage()."\n";
echo $foo->FIELD."\n";
$foo->FIELD = "FooBarGuff";
echo $foo->FIELD."\n";
?>

The snippet shows the Groovy class being imported into the PHP runtime. It then calls static and instance methods on the class, and also accesses static and instance fields.

Running the Example

1. Copy the PHP and Groovy scripts into the public folder of an IBM® WebSphere® sMash application.

2. Run the application and point a Web Browser at http://localhost:8080/sample.php. The Web browser displays the result:

Static Hello World!
BlahBlahBlah
FooBarGuff
Hello World!
Hello World!
FooBarGuff

Another Example

This example shows PHP using another Groovy class. In the snippet shown below the Groovy script defines a class called Builder. This uses a Groovy XMLBuilder to construct an XML document. The writeFile method constructs the document and returns it to the caller as a string.

import groovy.xml.*
import java.io.*

class Builder {
    def writeFile(String[] friendNames) {
        def writer = new StringWriter()
        def builder = new MarkupBuilder(writer)

        builder.person() {
            name(first:"Megan", last:"Smith") {
                age("33")
                gender("female")
            }
            friends() {
                for (nextFriend in friendNames) {
                    friend(nextFriend)
                }
            }
        }
        return writer.toString()
    }
}

The following snippet shows the class being imported and called from PHP:

<?php
groovy_import("builder.groovy");
$builder = new Builder();
$content = $builder->writeFile(array("Rob", "Colin", "Ant"));
var_dump($content);
?>

The output in a Web Browser is as follows (you will need to view page source in your browser):

string(222) "<person>
  <name first='Megan' last='Smith'>
    <age>33</age>
    <gender>female</gender>
  </name>
  <friends>
    <friend>Rob</friend>
    <friend>Colin</friend>
    <friend>Ant</friend>
  </friends>
</person>"

Callbacks from Groovy to PHP

Methods

This example shows Groovy calling back into PHP runtime - first the Groovy class:

class Callback {
    def callbackToThisObject(Object foo) {
        foo.callback("Hello World!");
    }
}

And now the PHP snippet that calls the Groovy class:

<?php
groovy_import("callback.groovy");
$callback = new Callback();

class Foo {
    function callback($message) {
        echo "Callback [".$message."]\n";
    }
}

$foo = new Foo();

$callback->callbackToThisObject($foo);
?>

The output in a Web Browser is as follows:

Callback [Hello World!]

There are several points to highlight about this example:

1. The PHP snippet defines a class called Foo which has one method called callback.

2. The PHP script calls the callbackToThisObject on the Groovy class and passes an instance of Foo to it.

2. The Groovy script calls back into the PHP script to the callback method on Foo.

Fields

This example shows Groovy accessing fields back in PHP runtime - first the Groovy class:

class Callback {
    def propertyStuff(Object foo) {
        Object previousValue = foo.blah;
        foo.blah = 1234567890;
        return previousValue;
    }
}

And now the PHP snippet that calls the Groovy class:

<?php
groovy_import("callback.groovy");
$callback = new Callback();

class Foo {
    var $blah = "BlahBlahBlah";
}

$foo = new Foo();

$value = $callback->propertyStuff($foo);
var_dump($value);
var_dump($foo->blah);
?>

The output in a Web Browser is as follows:

string(12) "BlahBlahBlah"
int(1234567890)

There are several points to highlight about this example:

1. The PHP snippet defines a class called Foo which has one public field called blah.

2. The PHP script calls the propertyStuff method on the Groovy class and passes an instance of Foo to it.

2. The Groovy class gets and sets fields on the PHP object that was passed to it.

Basic Closures

The following code snippet shows how to use Groovy closures from a PHP script - first an example Groovy script:

class Blah {
    def getDate() {
        def date = new java.util.Date()
        return { return date.toString() }
    }
}

The class defines a method called getDate that returns a closure. And now the PHP snippet that calls the Groovy class:

<?php
groovy_import("closure.groovy");
$blah = new Blah();

$closure = $blah->getDate();
var_dump($closure->call());

$function = array($closure, 'call');
$result = call_user_func($function);
var_dump($result);
?>

The snippet shows the Groovy class being imported and an instance of the Blah class being created. The PHP script calls getMethod to get a closure from Groovy. The PHP script shows two ways to call closures, either directly by invoking the call method on the closure, or indirectly by using the call_user_func extension function.

The Web browser displays the result:

string(28) "Mon Jan 12 15:42:33 GMT 2009"
string(28) "Mon Jan 12 15:42:33 GMT 2009"

Advanced Closures

The following code snippet shows how to create closures in PHP which can be used in Groovy - first an example Groovy script:

class Advanced {
    def useClosure(closure) {
        [1,2,3].each(closure)
    }

    def searchList(closure) {
        return (1..10).findAll(closure)
    }
}

The class defines two methods called useClosure and searchList both of which expect a closure to be passed to them. Here is a PHP snippet that calls the Groovy class:

<?php
groovy_import("advanced.groovy");
$advanced = new Advanced();

class Foo {
    function callback($value) {
        echo $value."\n";
    }
}

$foo = new Foo();

$closure = groovy_create_closure(array($foo, "callback"));
$advanced->useClosure($closure);

function check_value($value) {
    echo "Checking [".$value."]\n";
    return (($value % 2) != 0);
}

$closure = groovy_create_closure("check_value");
$advanced->searchList($closure);
?>

The snippet shows the Groovy class being imported and an instance of the Advanced class being created. The PHP script creates a Groovy compatible closure with groovy_create_closure. The Groovy closure closes around the callback method on the Foo class. The PHP script passes the closure to the Groovy useClosure method. When the closure is invoked by Groovy, it automatically calls back into the PHP runtime. The second example of groovy_create_closure creates a Groovy compatible closure around a function check_value instead of a method call.

The Web browser displays the result:

1
2
3
Checking [1]
Checking [2]
Checking [3]
Checking [4]
Checking [5]
Checking [6]
Checking [7]
Checking [8]
Checking [9]
Checking [10]

Currying

The following code snippet shows how to use curried closures in PHP - first an example Groovy script:

class Curry {
    def getMultiply() {
        return { x, y -> return x * y }
    }
}

The class defines a method called getMultiply which returns a closure. The closure requires two arguments and when invoked multiplies them together and returns the result. Here is the PHP snippet that uses the Groovy class:

<?php
groovy_import("curry.groovy");
$curry = new Curry();

// Closure with multiple arguments
$multiply = $curry->getMultiply();
$result = $multiply->call(3, 4);
var_dump($result);

// triple = { y -> return 3 * y }
$triple = $multiply->curry(3);
var_dump($triple->call(6));

// quadruple = { y -> return 4 * y }
$quadruple = $multiply->curry(4);
var_dump($quadruple->call(5));
?>

The snippet shows the Groovy class being imported and an instance of the Curry class being created. The PHP script invokes getMultiply and then calls the resulting closure. The PHP script then curries the closure by defining the first argument (x). Currying a closure creates another closure with one or more of the arguments defined.

The Web browser displays the result:

int(12)
int(18)
int(20)

Dynamic Groovy Classes

The following code snippet shows how to use dynamic classes in PHP - first an example Groovy script:

class Dynamic {
    def storage = [:]

    def invokeMethod(String name, args) {
        return "Hello World!";
    }

    def getProperty(String name) {
        storage[name]
    }

    void setProperty(String name, value) {
        storage[name] = value
    }
}

Another Groovy script can use this class as follows:

foo = new Dynamic();
foo.bar();
foo.guff = "Hello World!";
print foo.guff;

The class makes heavy use of Groovy's interceptors. Here is a PHP snippet that uses the Groovy class:

<?php
groovy_import("dynamic.groovy");

$foo = new Dynamic();
$foo->bar();
$foo->guff = "Hello World!";
echo $foo->guff;
?>

The snippet shows the Groovy class being imported and an instance of the Dynamic class being created. The PHP script invokes the dynamic bar method and gets/sets the property called guff on the object. The method calls and field accesses are passed to the Groovy interceptors as expected.

The Web browser displays the result:

Hello World!

Groovy Evaluation

The following code snippet shows how to use Groovy script evaluation in PHP:

<?php
var_dump(groovy_eval("1 + 2"));
?>

The groovy_eval extension function can be passed any Groovy script. The return value from the evaluation is passed back to the PHP script.

The Web browser displays the result:

int(3)

Groovy Ranges

The Groovy bridge provides built in access to Groovy's Range, IntRange, ObjectRange and ObjectRange classes.

The following code snippet shows how to use Groovy ranges in PHP:

<?php
$range = new IntRange(1,10);
var_dump($range->contains(-1));
var_dump($range->contains(1));
var_dump($range->contains(10));

// Iterate over the range
foreach ($range as $value) {
    echo $value."\n";
}
?>

The Web browser displays the result:

bool(false)
bool(true)
bool(true)
1
2
3
4
5
6
7
8
9
10

Version 1.1.31300