|
早先在做PHP时就觉得有个地方不太爽,还发表文章表示不满。
jsp中用system.out.print如果是在eclipse中调试的话,eclipse会自动拦截系统输出流,
然后输出在控制台中,而http输出流则不受影响,php好像无此功能,
有一个syslog()函数,在windows下要到事件管理器里查看,实在用处不大。
所以只好输出到文件查看bug,也是除了debug模式,单元测试之外的最常用调试手段
然后构思了一个解决方案,共享之。
思路:建一个java程序并使之运行,其监听本地机器的某个端口。只要有输入就直接输出,
java程序的关闭,最好是改一下程序,让特别的请求正常关闭。
但现在简单的办法就是 点击控制台的红色按钮(表示jvm在启动)
点击控制台的clear按钮可以清空控制台。注意还可能有多个控制台。
只要程序开着,就可以接受调试信息,赶快试一试吧。
浏览器是外部的还是eclipse内部的无所谓。
条件,使用eclipse,打开php的socket扩展,
编写一个java程序
//: c15:MultiJabberServer.java
// From 'Thinking in Java, 2nd ed.' by Bruce Eckel
// www.BruceEckel.com. See copyright notice in CopyRight.txt.
// A server that uses multithreading
// to handle any number of clients.
import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 该文件来源:《java编程思想(第2版)》,作者Bruce Eckel
* 被修改了输出的几句话。,还有编码等 现成的php 的 eclipse 的控制台,
*
* 使php 在pdt环境下 本机调试更加方便 发表评论,请http://xieye.iteye.com/
* xieye 20081122
*/
class ServeOneJabber extends Thread {
private Socket socket;
private BufferedReader in;
private PrintWriter out;
public ServeOneJabber(Socket s) throws IOException {
socket = s;
in = new BufferedReader(new InputStreamReader(socket.getInputStream(),
"UTF-8")); // 重要啊
// Enable auto-flush:
out = new PrintWriter( // 其实out没有用到
new BufferedWriter(new OutputStreamWriter(socket
.getOutputStream())), true);
// If any of the above calls throw an
// exception, the caller is responsible for
// closing the socket. Otherwise the thread
// will close it.
start(); // Calls run()
}
public void run() {
try {
synchronized (MultiJabberServer.lock1) { // lock1 是公用同步锁
// ,如果这个锁不加更糟
// 可以自己修改格式字符串
SimpleDateFormat sdf = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
System.out.print(sdf.format(new Date()) + " [debug] ");
while (true) {
String str = in.readLine();
if (str.equals(MultiJabberServer.S_EOF))
break;
System.out.println(str);
}
}
} catch (IOException e) {
System.err.println("== 客户端强行关闭 ==");
} finally {
try {
// System.err.println("==");
socket.close();
} catch (IOException e) {
System.err.println("Socket not closed");
}
}
}
}
public class MultiJabberServer {
static final int PORT = 8080; // 这就是端口,请保持与php代码一致
static final String S_EOF = "END"; // 这是停止字符串,要和php一致
public static final Object lock1 = new Object(); // 增加同步机制
public static void main(String[] args) throws IOException {
ServerSocket s = new ServerSocket(PORT);
System.out.println("PHP控制台启动。");
try {
while (true) {
// Blocks until a connection occurs:
Socket socket = s.accept();
try {
// synchronized(lock1){ // lock1 是公用同步锁
// 需要同步,但我不会
new ServeOneJabber(socket);
// }
} catch (IOException e) {
// If it fails, close the socket,
// otherwise the thread will close it:
socket.close();
}
}
} finally {
System.out.println("PHP控制台关闭。"); // 怎样才能让这句话执行呢?
s.close();
}
}
} // /:~
在eclipse里建一个java工程,然后放进去,文件名为MultiJabberServer.java
右键,Run_as --> Java Application, 视图是php还是java都无所谓
于是下方控制台打开,显示php控制台启动
新建一个php项目或者直接拷贝到原有的php项目里,把一个php文件
<?php
/**
* 该文件包含了一个输出到php控制台的函数, 并演示了如何使用该函数
* 需要有一个java程序MultiJabberServer.java配合
* 需要eclipse开发环境pdt
* 需要把php.ini 大约648行 的;extension=php_sockets.dll 前分号去掉
* php文件需要utf-8编码,或者使用utf8_encode 函数
* java文件编码应该是不限制的
* 唯一的遗憾是输出顺序不能控制,java高手快来改啊
*
* 操作系统:我目前是windowsXP,其实linux应该一样用
* 我的php当前版本是php5.2.6,其实只要能用socket扩展即可
* java版本随便,只要eclipse能开即可
* eclipse版本随便,只要是pdt
*
* xieye 20081122
*/
header('Content-Type:text/html; charset=utf-8');
/**
* 加一个换行符
*
* @param string $s
*/
function echobr($s)
{
echo $s."<br/>";
}
/**
* 输出到eclipse控制台的函数,使用前提见文件说明
*
* 另外,想要输出的字符串不要有单独的一行是“END”,因为被保留用来判断,
* 也可以自己修改,但要同时改java类
*
* 我用java多线程,只是为了防止服务端的socket自动关闭
*
* @param string $s 想要显示在eclipse控制台的字符
*/
function s($s)
{
/* 指定调试输出的端口, 可以换掉 */
$service_port = '8080';
/* 指定本机IP */
$address = '127.0.0.1';
/* 停止字符串设置 */
$s_eof = "END";
/* 创建一个 TCP/IP socket对象.还是静态的 */
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
echobr( "socket创建失败: 原因: " . socket_strerror(socket_last_error()) );
return false;
} else {
echobr( " socket创建 OK.");
}
/* socket连接 */
$result = socket_connect($socket, $address, $service_port);
if ($result === false) {
echobr( "socket连接失败。 <br/> 原因: ($result) " . socket_strerror(socket_last_error($socket)) );
return false;
} else {
echobr( "socket 连接 OK.");
}
//把停止字符串附加上去
$in = $s . "\n" . $s_eof;
socket_write($socket, $in, strlen($in));
//关闭socket;
socket_close($socket);
// sleep(1);
}
// 以下是演示,应该会在eclipse的console输出,注意:在控制台的顺序可能颠倒,要改java,不会
// 或者把上面的sleep(1)注释取消。
s('你好!');
$temp = var_export(array(1 => '红色', 2 => '蓝色'), true);
s($temp);
?>
文件名随意,然后到浏览器里访问该php文件,会发现eclipse的console里的调试信息。
很不错吧,
有java高手请一定指教,如何确保显示的顺序和php里顺序相同。
非常感激!
xieye
20081123 |
|
|