[工作小结]PHP和其他编程语言联合开发网站的一种方法

本文介绍PHP和其他编程语言联合开发网站的一种方法,文档和源码可以到这里下载:下载页面

我们使用多种语言联合开发网站时,通常的做法是由一种语言负责输出HTML页面,再由其他语言处理业务逻辑。比如我们用PHP来输出HTML页面,业务逻辑用JAVA或C#等来编写,把业务逻辑放在WEBSERVICE中,由PHP调用这些WEBSERVICE。

这里我们介绍另外一种方法,利用共享session,不需要WEBSERVICE,让PHP和其他语言都可以输出HTML页面。我们以JAVA为例,演示PHP和JAVA联合开发网站。

第一节:一个简单例子

先从一个简单的例子开始,这个例子有三个页面:

1、 登录页面


2、 登录成功页面


3、 查看个人信息页面


代码如下,为了使代码简捷易懂,只列出最基本的代码,不做任何错误处理,另外所有文件全部保存为UTF8格式,以防中文乱码(如果大家怎么都搞不定乱码的话,咱们就掩耳盗铃一回,把所有中文全改成英文算了微笑

1、 登录页面,文件名:1.html

<html>

<head>

<metahttp-equiv="Content-Type" content="text/html;charset=utf-8" />

</head>

<body>

<formaction="2.php" method="post" accept-charset="utf-8"onsubmit="document.charset='utf-8';">

用户:<inputtype="text" name="user" value="myname"><br/>

密码:<inputtype="password" name="password"value="mypwd"><br/>

邮箱:<inputtype="text" name="email"value="[email protected]"><br />

<inputtype="submit"  value="登录"/>

</form>

</body> 

</html>

2、 登录成功页面,文件名2.php

<html>

<head>

<metahttp-equiv="Content-Type" content="text/html;charset=utf-8" />

</head>

<body>

登录成功<br/>

<ahref="3.php">查看个人信息</a>

<?php

session_start();

//把用户名和邮箱写入session

$_SESSION['user']=$_POST["user"];

$_SESSION['email']=$_POST["email"];

?>

</body>

</html>

3、 查看个人信息页面,文件名3.php

<html>

<head>

<metahttp-equiv="Content-Type" content="text/html;charset=utf-8" />

</head>

<body>

用户:

<?php

session_start();

//从session中读取用户名

echo$_SESSION['user'];

?>

<br/>

邮箱:

<?php

//从session中读出邮箱

echo$_SESSION['email'];

?>

</form>

</body>

</html>

代码很简单,相信大家都看得懂,现在我们要把3.php文件改成用java语言,改成3.jsp。如何着手呢?我们先看3.php中的代码,用户名和邮箱都是从session中读出来的,我们要改用java语言,就要想个办法让java能读取PHP的session信息。解决这个问题的方法分为两步:

1、  把php的session信息放到数据库或分布式缓存中,让java共享

2、  让浏览器访问3.jsp页面时,在cookie中带上php的session id。关于session和cookie的原理,以及二者之间的联系,大家可以自行查阅相关资料。

我先做第一步:由于熟悉mysql的同学比熟悉redis的多,我们就以mysql为例,把PHP的session放到数据库中。

第二节:把php的session放到mysql中

介绍一下我的开发环境:

操作系统:windows 7

php、mysql、apache:wampserver2.5-Apache-2.4.9-Mysql-5.6.17-php5.5.12-32b

java:jdk1.8.0_40

tomcat:apache-tomcat-8.0.30-windows-x86

1、 在mysql中建立数据库,存放session,脚本如下:

CREATE DATABASEdb_session DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

Usedb_session;

CREATETABLE IF NOT EXISTS `tb_session` (

  `session_key` char(32) NOT NULL,

  `session_data` char(255) DEFAULT NULL,

  `session_time` bigint(20) unsigned DEFAULTNULL,

  PRIMARY KEY (`session_key`),

  KEY `index_session_time` (`session_time`)USING BTREE

) ENGINE=MyISAM DEFAULT CHARSET=utf8;

2、 建立一个文件session_mysql.php内容如下:

<?php

error_reporting(E_ALL^ E_DEPRECATED);

function_session_open($save_path,$session_name)

{

   global $handle;

   // 连接MYSQL数据库,记得把帐号、密码改成你自己的mysql帐号密码

   $handle =mysql_connect('localhost','root','') or die('数据库连接失败');

   mysql_query("SET NAMES 'utf8'");

   // 找到数据库      

   mysql_select_db('db_session',$handle) ordie('数据库中没有此库名');  

          

   return(true);

}

function_session_close()

{

   global $handle;

   mysql_close($handle);

   return(true);

}

function_session_read($key)

{

  

   global $handle;

   // 当前时间

   $time = time();                                                            

   $sql = "select session_data fromtb_session where session_key = '$key' and session_time > $time";

   $result = mysql_query($sql,$handle);

   $row = mysql_fetch_array($result);

   if ($row)

   {

           return($row['session_data']);

   }else

   {

           return(false);

   }

}

function_session_write($key,$data)

{

   global $handle;

   $time = ini_get('session.gc_maxlifetime');// 设置失效时间

  

   // 得到Unix时间戳

   $lapse_time = time() + $time;                                                   

   $sql = "select session_data fromtb_session where session_key = '$key' ";

   $result = mysql_query($sql,$handle);

   if (mysql_num_rows($result) == 0 )// 没有结果

   {

           // 插入数据库

           $sql = "insert into tb_sessionvalues('$key','$data',$lapse_time)";             

           $result = mysql_query($sql,$handle);

   }else

   {

           // 修改数据库

           $sql = "update tb_session setsession_key = '$key',session_data = '$data',session_time = $lapse_time wheresession_key = '$key'";

           $result = mysql_query($sql,$handle);

   }

   return($result);

}

function_session_destroy($key)

{

   global $handle;

   $sql = "delete from tb_session wheresession_key = '$key'";                                   

   $result = mysql_query($sql,$handle);

   return($result);

}

function_session_gc($expiry_time)

{

   global $handle;

  

   $lapse_time = time();                                                                          

   $sql = "delete from tb_session whereexpiry_time < $lapse_time";

   $result = mysql_query($sql,$handle);

   return($result);

}

session_set_save_handler('_session_open','_session_close','_session_read','_session_write','_session_destroy','_session_gc');

session_start();

?>

这个文件的功能就是把php的session存放到mysql中,数据库名db_session,表名tb_session。

其中这一句:$handle= mysql_connect('localhost','root','') or die('数据库连接失败');        mysql_connect的三个参数分别是mysql的服务器、用户名、密码,大家要根据自己的情况修改,如果你是使用新安装的wampserver2.5,可以不用修改,因为这就是缺省的用户名密码。

3、 修改文件2.php,内容如下:

<?php  require 'session_mysql.php';  ?>

<html>

<head>

<metahttp-equiv="Content-Type" content="text/html;charset=utf-8" />

</head>

<body>

登录成功<br/>

<ahref="3.php">查看个人信息</a>

<?php

//把用户名和邮箱写入session

$_SESSION['user']=$_POST["user"];

$_SESSION['email']=$_POST["email"];

?>

</body>

</html>

其中<?php  require 'session_mysql.php';  ?>要放在第一句

4、修改文件3.php,内容如下:

<?php  require 'session_mysql.php';  ?>

<html>

<head>

<metahttp-equiv="Content-Type" content="text/html;charset=utf-8" />

</head>

<body>

用户:

<?php

//从session中读取用户名

echo$_SESSION['user'];

?>

<br/>

邮箱:

<?php

//从session中读出邮箱

echo$_SESSION['email'];

?>

</form>

</body>

</html>

其中<?php  require 'session_mysql.php';  ?>要放在第一句

5、 现在我们有四个文件,分别是1.html、2.php、3.php、session_mysql.php,把这四个文件放到wampserver2.5,打开浏览器,输入http://127.0.0.1/1.html,点击“登录”,再点击“查看个人信息”就会看到第一节的三个页面。

6、 接下来我们到mysql中看看,表tb_session中有一条记录。

 

这条记录就是session的内容,我们来解释一下它的三个字段

session_time是session的有效期,它的值1452598497,这是UNIX时间戳,是一种时间表示方式,定义为从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。1452598497就是指从格林威治时间1970年01月01日00时00分00秒往后数1452598497秒,也就是2016-01-12 19:34:57。

session_data是session的内容。我们在文件2.php中写入两个session变量:

$_SESSION['user']=$_POST["user"];

$_SESSION['email']=$_POST["email"];

在数据库中变成:user|s:6:"myname";email|s:12:"[email protected]"; 每个session用分号分隔,session名和值用竖线分隔,s代表字符串,6是字符串myname的长度,12是字符串[email protected]的长度。

 session_key是session id,它的值是:9ico641ooeoc1ntln6iokuiil6,服务器在创建了session的同时,会为该session生成唯一的sessionid,这个session id会被放在cookie中,传送给浏览器。浏览器会把这个session id保存下来,以后每次发送请求,浏览器都会把这个session id放在cookie中,传送给服务器。服务器取到浏览器传送来的session id,就可以根据这个session id找到对应的session。

7、 好了,php的session已经保存到mysql中了,现在进行下一步

第三节:整合apache和tomcat

这一节的目的是让浏览器访问java写的3.jsp页面时,在cookie中带上php的session id。

1、在apache的配置文件httpd.conf里面,取消下面四行的注释:

LoadModule proxy_modulemodules/mod_proxy.so

LoadModule proxy_connect_modulemodules/mod_proxy_connect.so

LoadModule proxy_http_modulemodules/mod_proxy_http.so

LoadModule proxy_ftp_modulemodules/mod_proxy_ftp.so

2、在apache的配置文件httpd.conf最后增加两行:

ProxyPass /java/ http://localhost:8080/

ProxyPassReverse /java/ http://localhost:8080/

这两行的作用是设置代理,把用户对http://127.0.0.1/java/的访问转发给tomcat。如果你使用了VirtualHost,上面两行就要放在VirtualHost里面。

3、重启apache,启动tomcat,在浏览器中输入地址http://127.0.0.1/java/index.jsp,就可以看到tomcat的首页,如下图:



第四节:3.jsp获取浏览器传送的session id

1、tomcat新建一个文件3.jsp,内容如下:

<%@ page session="false"language="java" import="java.util.*,java.sql.*" pageEncoding="utf-8"%>

<%@ pagecontentType="text/html;charset=utf-8"%>

<html>

<head>

<metahttp-equiv="Content-Type" content="text/html;charset=utf-8" />

</head>

<body>

<%

//将所有的Cookie放到一个cookie对象数组里面

Cookie cookies[]=request.getCookies();

String svalue=null;

String sname=null;

if(cookies == null) {

   out.print("no Cookie"); //没有cookie

} else {

         out.print("cookiecount:"+cookies.length+"<br/>");

         //用一个循环语句遍历刚才建立的Cookie对象数组

         for(CookiesCookie : cookies){

                  sname=sCookie.getName();//取得这个Cookie的名字

                  svalue=sCookie.getValue();//取得这个Cookie的内容

                  out.print("Cookie_name:"+sname+"&nbsp; Cookie_value:"+svalue+"<br>");

         }

}

%>

 2、修改php的2.php文件

把<a href="3.php">查看个人信息</a>

改为<a href="/java/3.jsp">查看个人信息</a>

3、打开浏览器,输入http://127.0.0.1/1.html,点击“登录”,再点击“查看个人信息”就会看到如下页面:

 

我们可以看到一个cookie,它的名字是PHPSESSID,值是9ico641ooeoc1ntln6iokuiil6。我们到mysql数据库db_session中查看表tb_session,会看到表中存在一行数据,它的session_key值也是9ico641ooeoc1ntln6iokuiil6。大家可以对照第二节的图。

这说明java写的3.jsp文件已经成功取到php的session id。接下来,3.jsp就用这个php的session id去数据表中取session内容。


第五节:3.jsp获取php的session内容

1、修改tomcat里的3.jsp文件,内容如下:

<%@ page session="false"language="java" import="java.util.*,java.sql.*"pageEncoding="utf-8"%>

<%@ pagecontentType="text/html;charset=utf-8"%>

<html>

<head>

<metahttp-equiv="Content-Type" content="text/html;charset=utf-8" />

</head>

<body>

<% 

//将所有的Cookie放到一个cookie对象数组里面

Cookie cookies[]=request.getCookies();

String svalue=null;

String sname=null;

if(cookies == null) {

   out.print("no Cookie"); //没有cookie

} else {

         //用一个循环语句遍历刚才建立的Cookie对象数组

         for(CookiesCookie : cookies){

                  if(sCookie.getName().equals("PHPSESSID")){

                          svalue=sCookie.getValue();  //取得这个Cookie的内容

                          break;

                  }

         }

}

Connection con=null;

//db_session是数据库名,user是帐号,password是密码,请根据实际情况修改

Stringurl="jdbc:mysql://localhost/db_session?user=root&password=&useUnicode=true&characterEncoding=UTF-8";

Class.forName("com.mysql.jdbc.Driver").newInstance();

Connection conn=DriverManager.getConnection(url);

//查找session id 对应的session内容

Statement stmt=conn.createStatement();

String sql="select * from tb_sessionwhere session_key='"+svalue+"' and unix_timestamp(now())<session_time";

ResultSet rs=stmt.executeQuery(sql);

String phpSession=null;

while(rs.next()) {

         phpSession=rs.getString("session_data");

         break;

}

if(phpSession==null){

         out.print("nosession");//找不到session内容

}else{

        

         Stringsessions[]=phpSession.split(";");//拆分session字符串

         if(sessions!=null){

                  for(String s : sessions){

                         

                          if(s.startsWith("user|")){//用户名

                                   inti=s.indexOf("\"");

                                   if(i!=-1){

                                            Stringuser=s.substring(i+1,s.length()-1);

                                            out.print("用户:"+user+"<br/>");

                                   }

                          }elseif(s.startsWith("email|")){//邮箱

                                   inti=s.indexOf("\"");

                                   if(i!=-1){

                                            Stringemail=s.substring(i+1,s.length()-1);

                                            out.print("邮箱:"+email+"<br/>");

                                   }

                          }

                  }

         }

        

}

rs.close();

stmt.close();

conn.close();

%>

  

2、打开浏览器,输入http://127.0.0.1/1.html,点击“登录”,再点击“查看个人信息”就会看到如下页面:



第六节:后续改进工作

1、这种方法的缺点是java要放弃自己的session。通过filter机制拦截HttpServletReques,可以解决这个问题。

2、我们只实现了java读取php session的功能,写入功能还没实现,大家可以自己实现。

3、我们在session_mysql.php文件里使用的mysql扩展已经不被推荐使用,最好改用PDO来替代。

4、有时session内容会比较多,那么session_data字段要改成text类型。

5、为了提高效率可以把session放到redis中。

6、在我们的例子中,存入session的都是字符串,如果你要把数组或对象存入session,java的代码要修改,以处理这种情况。

7、在第三节《整合apache和tomcat》中,可以把tomcat映射为二级域名,同时要修改PHP代码,把cookie PHPSESSID设置为顶级域名

8、如果php和java代码放在不同域名中,可以采用JS跨域的 JSONP 解决方案来传递cookie PHPSESSID

9、如果你用一种语言写了一个公共模块,想在其它语言中调用这个模块。这种情况下,webservice是一种很好的解决方案。我们可以把cookiePHPSESSID作为参数传给webservice,然后webservice就可以到数据库中读取session内容。




 

猜你喜欢

转载自blog.csdn.net/dengxiaodai/article/details/50510745
今日推荐