PHP/Java Bridge的使用

PHP/Java Bridge的使用

一、需求背景

    之前介绍过我们项目的架构,由于历史原因,架构演变成as<-->java<-->php这样,java与as通过tcp长连接通信,java与php通过两条http通道来通信(java与php各自有个http server,并各自作为对方的http client,java转发as以前的post给php;php需要跨session推送或者广播时变为http client向java的http server做post)。

    这之前的架构是as的功能逻辑大部分直接与php进行http通信。

    项目的目标是慢慢将php部分写的糟糕的已有逻辑(例如帮派这种交互和广播同步比较多的)改到java服务器上。项目人员配备跟不上,所以不能一下子全转了。

    如果用之前的两条http通道来小步快跑式的移逻辑,就需要再封装这两个通道之间的通信,费时间还不一定好使,所以我们需要一个java直接调用php的技术。

    goole了解后,最终决定使用PHP/Java Bridge。 

 

二、PHP/Java Bridge

(一)示例

CallPhp.java

 1  package me.sheppardy.study;
 2 
 3  import java.io.ByteArrayOutputStream;
 4  import java.io.FileReader;
 5 
 6  import javax.script.ScriptEngine;
 7  import javax.script.ScriptEngineManager;
 8 
 9  /**
10   * 
11   * PHP/Java Bridge, example
12   *  @author  sheppard([email protected]) 2013-01-18
13   *
14    */
15  public  class CallPhp
16 {
17         
18          public  static  void main(String[] args)  throws Exception
19         {
20                 test(1104);
21                 test(531);
22                 test(1221);
23                 test(110);
24         }
25         
26          public  static  void test( int id)  throws Exception
27         {
28                 Response rep =  new Response();
29                 call( new Request(id), rep);
30                 System.out.println("CallPhp.test, id=" + id + " message=" + rep.message);
31         }
32         
33          public  static  void call(Request req, Response rep)  throws Exception
34         {
35                 ScriptEngineManager engineManager =  new ScriptEngineManager();
36                 ScriptEngine engine = engineManager.getEngineByName("php-invocable");
37 
38                 ByteArrayOutputStream log =  new ByteArrayOutputStream();
39 
40                  try
41                 {
42                         engine.put("phpRootDir", "data/php");
43                         engine.put("log", log);
44                         engine.put("req", req);
45                         engine.put("rep", rep);
46                         FileReader reader =  new FileReader("data/php/gate.php");
47                         engine.eval(reader);
48                         System.out.println("CallPhp.call phpLog=" + log.toString());
49                 }
50                  catch(Exception e)
51                 {
52                         System.out.println("CallPhp.call phpLog=" + log.toString());
53                          throw e;
54                 }
55         }
56 }
57 
58  class Request
59 {
60          public Request( int id)
61         {
62                  this.id = id;
63         }
64          public  int id;
65 }
66 
67  class Response
68 {
69          public String message;
70 }

java-bin/data/php/gate.php

 1 <?php
 2 
 3  /* *
 4   *
 5   * 脚本统一入口
 6   * @author sheppard([email protected]) 2013-01-18
 7   *
 8    */
 9 
10  define('PHP_ROOT_DIR', java_context()->get('phpRootDir'));
11  $log = java_context()->get('log');
12  $log->write("\n\tjava give phpRootDir is " . PHP_ROOT_DIR);
13 
14  require_once(PHP_ROOT_DIR . '/function.php');
15 
16  $log->write(getDoomsday());
17 
18  $rep = java_context()->get('rep');
19  $rep->message = handle(java_context()->get('req'),  $log);
20 
21 ?>

java-bin/data/php/function.php

 1 <?php
 2 
 3  /* *
 4   *
 5   * 具体功能举例
 6   * @author sheppard([email protected]) 2013-01-18
 7   *
 8    */
 9 
10  function getDoomsday()
11 {
12          return "\n\tdoomsday is 20121221";      
13 }
14 
15  function handle( $req$log)
16 {
17          $id =  $req->id;
18          $log->write("\n\tfunction.php handle id=$id");
19          if('1104' ==  $id)
20                  return 'guess?';
21          else  if('531' ==  $id)
22                  return 'score';
23          else  if('1221' ==  $id)
24                  return 'maybe doomsday';
25          else
26                  return '404 not found';
27 }
28 
29 ?>

output

 1 CallPhp.call phpLog=
 2 java give phpRootDir is data/php
 3 doomsday is 20121221
 4  function.php handle id=1104
 5 CallPhp.test, id=1104 message=guess?
 6 CallPhp.call phpLog=
 7 java give phpRootDir is data/php
 8 doomsday is 20121221
 9  function.php handle id=531
10 CallPhp.test, id=531 message=score
11 CallPhp.call phpLog=
12 java give phpRootDir is data/php
13 doomsday is 20121221
14  function.php handle id=1221
15 CallPhp.test, id=1221 message=maybe doomsday
16 CallPhp.call phpLog=
17 java give phpRootDir is data/php
18 doomsday is 20121221
19  function.php handle id=110
20 CallPhp.test, id=110 message=404 not found

(二)注意事项

1. 由于是java调用的php,所以php里当前工作路径变成了java的。

2. FileReader加载*.php文件之后ScriptEngine.evel(FileReader)的耗时大概为230+ms,StringReader时为180+ms,速度都不咋滴,但是这不是我们项目急着考虑的问题,之前的http方式也好不到哪去,优化留到以后再说。

3. php的解释器运行路径配置:-Dphp.java.bridge.php_exec=。

 

三、相关资料

1. 官网:http://php-java-bridge.sourceforge.net/pjb/

2. 符合java调脚本标准的调php示例:http://php-java-bridge.sourceforge.net/pjb/examples/source.php?source=PhpThreads.java


ps:2013年1月18日我在CU的博客

 

 

 

 

你可能感兴趣的:(PHP/Java Bridge的使用)