PHP Extensions and Mappings

PHP Extensions and MappingsPHP Language Extensions and Type MappingsPHP Extensions

The bridge implementations add the following primitives to PHP. The type mappings are shown in table 1 below.

  • new Java("CLASSNAME"): References and instantiates the class CLASSNAME. After script execution the referenced classes may be garbage collected. Example:

    <?php
    $v = new Java("java.util.Vector");
    $v->add($buf=new Java("java.lang.StringBuffer"));
    $buf->append("100");
    echo (int)($v->elementAt(0)->toString()) + 2;
    ?>

  • new JavaClass("CLASSNAME"): References the class CLASSNAME without creating an instance. The returned object is the class object itself, not an object of the class. After script execution the referenced classes may be garbage collected. Example:

    $Object = new JavaClass("java.lang.Object");
    $obj = $Object->newInstance();

    $Thread = new JavaClass("java.lang.Thread");
    $Thread->sleep(10);

  • java_require("JAR1;JAR2"): Makes additional libraries available to the current script. JAR can either be a "http:", "ftp:", "file:" or a "jar:" or a default location. On "Security Enhanced Linux" (please see the README section on "Security Enhanced Linux"<– incorporate this info into other pages in site) the location must be tagged with a lib_t security context. Example:

    // load scheme interpreter
    // try to load it from /usr/share/java/ or from sourceforge.net
    try { java_require("kawa.jar"); } catch (JavaException $e) {/*ignore*/}
    java_require("http://php-java-bridge.sourceforge.net/kawa.jar");
    $n=100;
    $System = new JavaClass("java.lang.System");
    $t1 = $System->currentTimeMillis();
    $code="(letrec ((f (lambda(v) (if (= v 0) 1 (* (f (- v 1)) v))))) (f $n))";
    $scheme = new java("kawa.standard.Scheme");
    $res = (float)java_values($scheme->eval($code));
    echo "${n}! => $resn";
    $delta = $System->currentTimeMillis() - $t1;
    echo "Evaluated in $delta ms.n";

  • java_context(): Makes the javax.script.ScriptContext available to the current script. All implicit web objects (session, servlet context, etc.) are available from the context, if the back end is running in a servlet engine or application server. The following example uses the jdk1.6 jrunscript to eval PHP statements interactively:

    /opt/jdk1.6/bin/jrunscript -l php-intractive
    php-interactive> echo (string)(java_context()->getAttribute("javax.script.filename"));
    => <STDIN>

  • java_values(JAVA_OBJECT): Fetches the values for JAVA_OBJECT, if possible. Examples:

    $str = new java("java.lang.String", "hello"); echo $str;
    => [o(String):"hello"]

    // fetch the php string from the java string
    echo (java_values($str));
    => hello

    // fetch the values of the java char array
    print_r (java_values($str->toCharArray()));
    => array('h', 'e', 'l', 'l', 'o')

    // no php type exists for java.lang.Object
    print (java_values(new java("java.lang.Object")));
    => [o(Object):"java.lang.Object@4a85fc"]

  • java_cast(JAVA_VALUE, php_type): Converts a primitive JAVA_VALUE to a php value of type php_type. Unlike java_values, which return the "natural" php value for the JAVA_VALUE, the cast can convert the JAVA_VALUE into the desired php_type before it is returned. Allowed conversions are "string", "boolean", "integer" or "long", "double" or "float", "null", "array" and "object". The "object" conversion is the identiy function. Since PHP5 (php_type)JAVA_VALUE is identical to java_cast(JAVA_VALUE, php_type) (Zend Engine 2 and above only). Examples:

    $str = new java("java.lang.String", "12"); echo $str;
    => [o(String):"12"]

    // fetch the php string from the java string
    echo java_cast($str, "string");
    => "12"

    echo java_cast($str, "integer" );
    => 12

    var_dump (java_cast($str, "boolean"));
    => true

  • java_begin_document() and java_end_document(): Enables/disables XML stream mode. In XML stream mode the PHP/Java Bridge XML statements are sent in one XML stream. Compared with SOAP, which usually creates the entire XML document before sending it, this mode uses much less resources on the web-server side. Raised server-side exceptions are reported when java_end_document() is invoked. Example:

    // send the following XML statements in one stream
    java_begin_document();
    for ($x = 0; $x < $dx; $x++) {
       $row = $sheet->createRow($x);
       for ($y = 0; $y < $dy; $y++) {
         $cell = $row->createCell($y);
         $cell->setCellValue("$x . $y");
         $cell->setCellStyle($style);
       }
    }
    java_end_document(); // back to synchronous mode

  • java_closure(ENVIRONMENT, MAP, TYPE): Makes it possible to call PHP code from Java. It closes over the PHP environment, packages it up as a java class and returns an instance of the class. If the ENVIRONMENT is missing, the current environment is used. If MAP is missing, the PHP procedures must have the same name as the required procedures. If TYPE is missing, the generated class is "generic", i.e. the interface it implements is determined when the closure is applied. Example:

    <?php
    function toString() { return "hello" ; }
    echo (string)java_closure();
    ?>
    => hello

  • $session=java_session(): Creates or retrieves a session context. When the back end is running in a J2EE environment, the session is taken from the request object, otherwise it is taken from PHP. Please see the ISession interface documentation for details. The java_session() must be called before the response headers have been sent and it should be called as the first statement within a PHP script.

    $session = java_session();

  • $session=java_session(SESSIONNAME): Creates or retrieves the session SESSIONNAME. This primitive uses a session store with the name SESSIONNAME which is independent of the current PHP- or Java session. Please see the ISession interface documentation for details. For Java values $_SESSION['var']=val is syntactic sugar for java_session("internal-prefix@".session_id())->put('var', val).

    $session=java_session("testSession");
    if($session->isNew()) {
       echo "new sessionn";
       $session->put("a", 1);
       $session->put("b", 5);
    } else {
       echo "cont sessionn";
    }
    $session->put("a", $session->get("a")+1);
    $session->put("b", $session->get("b")-1);

    $val=$session->get("a");
    echo "session var: $valn";

    if($session->get("b")==0) $session->destroy();

    The java_session primitive is meant for values which must survive the current script. If you want to cache data which is expensive to create, bind the data to a class. Example:

    // Compile this class, create cache.jar and copy it to /usr/share/java
    public class Cache {
       private static final Cache instance = makeInstance();
       public static Cache getInstance() { return instance; }
    }

    <?php
    java_require("cache.jar");
    $Cache = new JavaClass("Cache");
    $instance=$Cache->getInstance(); //instance will stay in the VM until the VM runs short of memory
    ?>

  • JavaException: A java exception class. Available in PHP 5 and above only. Example:

    try {
       new java("java.lang.String", null);
    } catch(JavaException $ex) {
       $exStr = java_cast($ex, "string");
       echo "Exception occured; mixed trace: $exStrn";
       $trace = new java("java.io.ByteArrayOutputStream");
       $ex->printStackTrace(new java("java.io.PrintStream", $trace));
       print "java stack trace: $tracen";
    }

    The original exception can be retrieved with $ex->getCause(), for example:

    function rethrow($ex) {
       static $NullPointerException=new JavaClass("java.lang.NullPointerException");
       $ex=$ex->getCause();
       if(java_instanceof($ex, $NullPointerException)) {
         throw new NullPointerException($ex);
       }
       ...
       die("unexpected exception: $ex");
    } try {
       new java("java.lang.String", null);
    } catch(JavaException $ex) {
       rethrow($ex);
    }

  • foreach(COLLECTION): It is possible to iterate over values of java classes that implement java.util.Collection or java.util.Map. Available in PHP 5 and above only. Example:

    $conversion = new java("java.util.Properties");
    $conversion->put("long", "java.lang.Byte java.lang.Short java.lang.Integer");
    $conversion->put("boolean", "java.lang.Boolean");
    foreach ($conversion as $key=>$value)
       echo "$key => $valuen";

  • [index]: It is possible to access elements of java arrays or elements of java classes that implement the java.util.Map interface. Available in PHP 5 and above only. Example:

    $Array = new JavaClass("java.lang.reflect.Array");
    $String = new JavaClass("java.lang.String");
    $entries = $Array->newInstance($String, 3);
    $entries[0] ="Jakob der Lügner, Jurek Becker 1937--1997";
    $entries[1] ="Mutmassungen über Jakob, Uwe Johnson, 1934--1984";
    $entries[2] ="Die Blechtrommel, Günter Grass, 1927--";
    for ($i = 0; $i < $Array->getLength($entries); $i++) {
       echo "$i: " . $entries[$i] ."n";
    }

  • java_instanceof(JAVA_OBJ, JAVA_CLASS): Tests if JAVA_OBJ is an instance of JAVA_CLASS. Example:

    $Collection=new JavaClass("java.util.Collection");
    $list = new java("java.util.ArrayList");
    $list->add(0);
    $list->add(null);
    $list->add(new java("java.lang.Object"));
    $list->add(new java("java.util.ArrayList"));
    foreach ($list as $value) {
       if($value instanceof java && java_instanceof($value, $Collection))
         /* iterate through nested ArrayList */
       else
         echo "$valuen";
    }

  • java_last_exception_get(): Returns the last exception instance or null. Since PHP 5 you can use try/catch instead.
  • java_last_exception_clear(): Clears the error condition. Since PHP 5 you can use try/catch instead.

Table 1. Type Mappings PHP Java Description Example object java.lang.Object An opaque object handle. However, we guarantee that the first handle always starts with 1 and that the next handle is n+1 (useful if you work with the raw XML protocol, see the python and scheme examples). $buf=new java("java.io.ByteArrayOutputStream");
$outbuf=new java("java.io.PrintStream", $buf); null null NULL value $outbuf->println(null); exact number integer (default) or long. 64 bit data on protocol level, coerced to 32bit int/Integer or 64bit long/Long $outbuf->println(100); boolean boolean boolean value $outbuf->println(true); inexact number double IEEE floating point $outbuf->println(3.14); string byte[] binary data, unconverted $bytes=$buf->toByteArray(); string java.lang.String An UTF-8 encoded string. Since PHP does not support Unicode, all java.lang.String values are auto-converted into a byte[] (see above) using UTF-8 encoding. The encoding can be changed with the java_set_file_encoding() primitive. $string=$buf->toString(); array (as array) java.util.Collection or T[] PHP4 sends and receives arrays as values. PHP5 sends arrays as values and receives object handles which implement the new iterator and array interface. // pass a Collection to Vector
$ar=array(1, 2, 3);
$v=new java("java.util.Vector", $ar);
echo $v->capacity();

// pass T[] to asList()
$A=new JavaClass("java.util.Arrays");
$lst=$A->asList($ar);
echo $lst->size(); array (as hash) java.util.Map PHP4 sends and receives hash-tables as values. PHP5 sends hash-tables as values and receives object handles which implement the new iterator interface. $h=array("k"=>"v", "k2"=>"v2");
$m=new java("java.util.HashMap",$h);
echo $m->size(); JavaException java.lang.Exception A wrapped exception class. The original exception can be retrieved with $exception->getCause(); …
catch(JavaException $ex) {
    echo $ex->getCause();
}

There is one example provided: test.php. You can either invoke the test.php by typing ./test.php or copy the example into the document root of your web-server and evaluate the file using the browser.

Custom java libraries (.jar files) can be stored in the following locations:

  1. Somewhere on a HTTP or FTP server, see PHP function java_require. On Security Enhanced Linux .jar files can only be loaded from locations which are tagged with the lib_t security context.
  2. In the sub-directory "lib" of the PHP extension directory, if it exists and is accessible when the JVM starts the bridge. This is usually "`php-config –extension-dir`/lib". On Security Enhanced Linux this directory is tagged with the lib_t security context.
  3. In the /usr/share/java/ directory, if it exists and is accessible when the JVM starts the bridge. On Security Enhanced Linux this directory is tagged with the lib_t security context.

利用php DOM函数库创建xml文档

<?php

/**
* filename: domEx.php
*
* Editor: richard_ma
*
* Date: 2007-07-27
*
* Description:
*   利用php DOM函数库创建xml文档
*/

// 设置Http头属性为xml
header("Content-Type:text/xml");

/**
* 创建文档对象及根节点
*/
// 创建DOM对象,xml版本为1.0编码方式为UTF-8
$dom = new DOMDocument(‘1.0’, ‘UTF-8’);
// 创建节点
$response = $dom->createElement(‘rootNode’);
// 将节点作为子节点加入xml文档中
$dom->appendChild($response);

/**
* 创建属性
*/
// 创建属性节点
$resAttribute = $dom->createAttribute(‘attrNode’);
// 插入属性节点
$response->appendChild($resAttribute);
// 创建属性值
$attrValue = $dom->createTextNode(‘attrValue’);
// 插入属性值
$resAttribute->appendChild($attrValue);

/**
* 创建标签内容
*/
// 创建文字节点
$resContent = $dom->createTextNode(‘textNode’);
// 将文字节点作为子节点加入根节点中
$response->appendChild($resContent);

// 导出xml字符串
$xmlStr = $dom->saveXML();

// 输出xml字符串
echo $xmlStr;

?>

使用PHP的DOM functins读到RSS的新闻的实例

<?php
/*
*@作者:旭日
*@Email:54ano@163.com
*/

/*
*@实例化一个DOM类
*@version:1.0
*encoding:gb2312
*/
$dom = new DomDocument(‘1.0’, ‘gb2312’);
/*
*@载个文件
*/
$dom->load(‘http://rss.cnfol.com/news.xml’);
/*
*@获取channel节点
*/
$items = $dom->getElementsByTagName(‘channel’);

/*=====如果是中文内容,必须经过iconv编码转换,否则显示为乱码=====*/

/*
*@采channel下的子节点descrīption等节点的内容
*/
foreach (Array(‘descrīption’, ‘title’, ‘link’, ‘language’, ‘lastBuildDate’, ‘generator’, ‘copyright’) AS $node) {
   $global[‘cont’][$node] = iconv(‘utf-8’, ‘gb2312’, $items->item(0)->getElementsByTagName($node)->item(0)->nodeValue);
}
/*
*@采channel下的子节点image节点的信息
*/
foreach (Array(‘url’, ‘link’, ‘title’, ‘descrīption’) AS $node) {
   $global[‘cont’][‘image’][$node] = iconv(‘utf-8’, ‘gb2312’, $items->item(0)->getElementsByTagName(‘image’)->item(0)->getElementsByTagName($node)->item(0)->nodeValue);
}
/*
*@采channel下的子节点item节点的信息
*/
foreach ($items->item(0)->getElementsByTagName(‘item’) AS $key => $item) {
   foreach (Array(‘title’, ‘descrīption’, ‘link’, ‘author’, ‘pubDate’) AS $node) {
       $global[‘cont’][‘items’][$key][$node] = iconv(‘utf-8’, ‘gb2312’, $item->getElementsByTagName($node)->item(0)->nodeValue);
   }
}
print_r($global);
?>

定界符<<<的用法

定界符
给字符串定界的方法使用定界符语法(“<<<”)。应该在 <<< 之后提供一个标识符,然后是字符串,然后是同样的标识符结束字符串。
结束标识符必须从行的第一列开始。同样,标识符也必须遵循 PHP 中其它任何标签的命名规则:只能包含字母数字下划线,而且必须以下划线或非数字字符开始。

举个例子:
<?php
$str = <<<EOD
Example of string
spanning multiple lines
using heredoc syntax.
EOD;
?>

但要注意的是:
结束标识符所在的行不能包含任何其它字符,可能除了一个分号(;)之外。这尤其意味着该标识符不能被缩进,而且在分号之前和之后都不能有任何空格或制表 符。同样重要的是要意识到在结束标识符之前的第一个字符必须是你的操作系统中定义的换行符。例如在 Macintosh 系统中是 r。 如果破坏了这条规则使得结束标识符不“干净”,则它不会被视为结束标识符,PHP 将继续寻找下去。如果在这种情况下找不到合适的结束标识符,将会导致一个在脚本最后一行出现的语法错误。

ps:定界符文本表现的就和双引号字符串一样,只是没有双引号。这意味着在定界符文本中不需要转义引号,不过仍然可以用以上列出来的转义代码。

例一:

<?php
echo <<< EOT
                  <table width=80% border="2" cellpadding="3" cellspacing="0" bordercolor="#808080">
                 <tr bgcolor="#84A9E1">
                 <td align="center">ClassID</td>
                 <td align="center">stuno</td>
                 <td   align="center">学生姓名</td>
                 <td align="center">家长姓名</td>
                 <td align="center">家长手机号</td>
                 </tr>
EOT;
?>

例二:

<?
               $xml=<<<EOT
<message name="getTermRequest">
<part name="term" type="xs:string"/>
</message>

<message name="getTermResponse">
<part name="value" type="xs:string"/>
</message>

<portType name="glossaryTerms">
<operation name="getTerm">
<input message="getTermRequest"/>
<output message="getTermResponse"/>
</operation>
</portType>
EOT;

echo $xml;

?>