在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时候怎么办呢?不用担心,mysql已经为我们提供了这样一个功能。
SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset
LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数。LIMIT 接受一个或两个数字参数。参数必须是一个整数常量。如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。初始记录行的偏移量是 0(而不是 1): 为了与 PostgreSQL 兼容,MySQL 也支持句法: LIMIT # OFFSET #。
mysql> SELECT * FROM table LIMIT 5,10; // 检索记录行 6-15
//为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1:
mysql> SELECT * FROM table LIMIT 95,-1; // 检索记录行 96-last.
//如果只给定一个参数,它表示返回最大的记录行数目:
mysql> SELECT * FROM table LIMIT 5; //检索前 5 个记录行
//换句话说,LIMIT n 等价于 LIMIT 0,n。
mysql> SELECT * FROM table LIMIT 95,-1; // 检索记录行 96-last.
$start = $offset * ($page-1);
$limit = $start.','.$offset;
$sql = 'SELECT * FROM record '.$where.' ORDER BY ctime DESC LIMIT '.$limit;
SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset
LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数。LIMIT 接受一个或两个数字参数。参数必须是一个整数常量。如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。初始记录行的偏移量是 0(而不是 1): 为了与 PostgreSQL 兼容,MySQL 也支持句法: LIMIT # OFFSET #。
mysql> SELECT * FROM table LIMIT 5,10; // 检索记录行 6-15
//为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1:
mysql> SELECT * FROM table LIMIT 95,-1; // 检索记录行 96-last.
//如果只给定一个参数,它表示返回最大的记录行数目:
mysql> SELECT * FROM table LIMIT 5; //检索前 5 个记录行
//换句话说,LIMIT n 等价于 LIMIT 0,n。
mysql> SELECT * FROM table LIMIT 95,-1; // 检索记录行 96-last.
$start = $offset * ($page-1);
$limit = $start.','.$offset;
$sql = 'SELECT * FROM record '.$where.' ORDER BY ctime DESC LIMIT '.$limit;
这个版本改进了不少地方,例如对ZF的良好支持。官方目前只提供法语、德语、意大利语三个语言包的下载,中文的还没有看到,再期待一下吧!
下载地址如下:
http://downloads.zend.com/studio-eclipse/6.0.1/ZendStudioForEclipse-6_0_1.exe (for windows)
http://downloads.zend.com/studio-eclipse/6.0.1/ZendStudioForEclipse-6_0_1.tar.gz (for linux)
http://downloads.zend.com/studio-eclipse/6.0.1/ZendStudioForEclipse-6.0.1.dmg (for mac,不好意思,一直不知道这个是MAC下的安装程序)
之前的注册机还可以继续使用,本人已测,呵呵~
KeyGen:http://www.niuc.net/attachment.php?fid=203
用户名:Faceker.com
注册码:02251FE3126660400000
用户名:PHPER
注册码:4784D9D0086669570000
可以到 Zend 官方网站下载 Zend Studio For Eclipse:[url=http://downloads.zend.com/studio-eclipse/6.0.0/ZendStudioForEclipse-6_0_0.zip]直接下载地址[/url]
我一直在寻找一个理想的 PHP 开发环境。之前一直用 Dreamweaver,但他只是一个完美的代码和 HTML 编辑器,在 PHP 开发方面,他连基本的自定义函数的参数都无法提示;有人推荐 EditPlus,不过他也只是个编辑器,离“开发环境”还差得远;再者就是 Zend Studio,他是公认的很好很强大的 PHP 开发环境,不过看到他那丑陋的界面,我就知道那不是我想要的。
后来知道了有个 PDT,基于 Eclipse 的 PHP 开发环境,用了一下,着实不错,界面也很美观,基本的 PHP 开发功能也够用,下定决心,从此就用他来搞 PHP 了。
过年期间,看到一条新闻,新版的 Zend Studio 发布了,该版本是基于 Eclipse 的开发环境,是在 PDT 的基础之上开发的,迫不及待地下载安装试用,WOW,一切都是那么的完美,毫无疑问,Zend Studio For Eclipse 将是以后 PHP 开发的不二选择了!
下载地址如下:
http://downloads.zend.com/studio-eclipse/6.0.1/ZendStudioForEclipse-6_0_1.exe (for windows)
http://downloads.zend.com/studio-eclipse/6.0.1/ZendStudioForEclipse-6_0_1.tar.gz (for linux)
http://downloads.zend.com/studio-eclipse/6.0.1/ZendStudioForEclipse-6.0.1.dmg (for mac,不好意思,一直不知道这个是MAC下的安装程序)
之前的注册机还可以继续使用,本人已测,呵呵~
KeyGen:http://www.niuc.net/attachment.php?fid=203
用户名:Faceker.com
注册码:02251FE3126660400000
用户名:PHPER
注册码:4784D9D0086669570000
可以到 Zend 官方网站下载 Zend Studio For Eclipse:[url=http://downloads.zend.com/studio-eclipse/6.0.0/ZendStudioForEclipse-6_0_0.zip]直接下载地址[/url]
我一直在寻找一个理想的 PHP 开发环境。之前一直用 Dreamweaver,但他只是一个完美的代码和 HTML 编辑器,在 PHP 开发方面,他连基本的自定义函数的参数都无法提示;有人推荐 EditPlus,不过他也只是个编辑器,离“开发环境”还差得远;再者就是 Zend Studio,他是公认的很好很强大的 PHP 开发环境,不过看到他那丑陋的界面,我就知道那不是我想要的。
后来知道了有个 PDT,基于 Eclipse 的 PHP 开发环境,用了一下,着实不错,界面也很美观,基本的 PHP 开发功能也够用,下定决心,从此就用他来搞 PHP 了。
过年期间,看到一条新闻,新版的 Zend Studio 发布了,该版本是基于 Eclipse 的开发环境,是在 PDT 的基础之上开发的,迫不及待地下载安装试用,WOW,一切都是那么的完美,毫无疑问,Zend Studio For Eclipse 将是以后 PHP 开发的不二选择了!
server.php:(UTF8编码)
<?php
// server
// 设置错误处理
error_reporting (e_all);
// 设置运行时间
set_time_limit (0);
// 起用缓冲
ob_implicit_flush ();
$ip = "127.0.0.1"; // ip地址
$port = 8848; // 端口号
$socket = socket_create (AF_INET, SOCK_STREAM, SOL_TCP); // 创建一个socket
if ($socket)
echo "socket_create() successed!\n";
else {
echo "socket_create() failed:".socket_strerror ($socket)."\n";
exit(0);
}
$bind = socket_bind ($socket, $ip, $port); // 绑定一个socket
if ($bind) {
echo "socket_bind() successed!\n";
}else{
echo "socket_bind() failed:".socket_strerror ($bind)."\n";
return 0;
}
$listen = socket_listen ($socket); // 间听socket
if ($listen)
echo "socket_listen() successed!\n";
else
echo "socket_listen() failed:".socket_strerror ($listen)."\n";
while (true)
{
$msg = socket_accept ($socket); // 接受一个socket
if (!$msg)
{
echo "socket_accept() failed:".socket_strerror ($msg)."\n";
break;
}
$welcome0 = "welcome to php server!向东\n";
$welcome = iconv("utf-8","gbk",$welcome0);//显示gb的中文,否则在windows cmd 终端显示乱码
socket_write ($msg, $welcome, strlen ($welcome));
while (true)
{
$command = strtoupper (trim (socket_read ($msg, 1024)));
if (!$command)
break;
echo $command."\n";
switch ($command)
{
case "HELLO":
$writer = "hello everybody!";
break;
case "BYE":
$writer = "bye-bye";
break;
case "HELP":
$writer = "hello\tquit\thelp";
break;
default:
$writer = "error command!\n";
}
socket_write ($msg, $writer, strlen ($writer));
if ($command == "QUIT")
break;
}
socket_close ($msg);
}
socket_close ($socket); // 关闭socket
?>
client.php(UTF8编码)
<?php
// Client
// 设置错误处理
error_reporting (E_ALL);
// 设置处理时间
set_time_limit (0);
$ip = "127.0.0.1"; // IP 地址
$port = 8848; // 端口号
$socket = socket_create (AF_INET, SOCK_STREAM, SOL_TCP); // 创建一个SOCKET
if ($socket)
echo "socket_create() successed!/n";
else
echo "socket_create() failed:".socket_strerror ($socket)."/n";
$conn = socket_connect ($socket, $ip, $port); // 建立SOCKET的连接
if ($conn)
echo "Success to connection![".$ip.":".$port."]/n";
else
echo "socket_connect() failed:".socket_strerror ($conn)."/n";
echo socket_read ($socket, 1024);
$stdin = fopen ('php://stdin', 'r');
while (true)
{
$command = trim (fgets ($stdin, 1024));
socket_write ($socket, $command, strlen ($command));
$msg = trim (socket_read ($socket, 1024));
echo $msg."\n";
if ($msg == "Bye-Bye")
break;
}
fclose ($stdin);
socket_close ($socket);
?>
<?php
// server
// 设置错误处理
error_reporting (e_all);
// 设置运行时间
set_time_limit (0);
// 起用缓冲
ob_implicit_flush ();
$ip = "127.0.0.1"; // ip地址
$port = 8848; // 端口号
$socket = socket_create (AF_INET, SOCK_STREAM, SOL_TCP); // 创建一个socket
if ($socket)
echo "socket_create() successed!\n";
else {
echo "socket_create() failed:".socket_strerror ($socket)."\n";
exit(0);
}
$bind = socket_bind ($socket, $ip, $port); // 绑定一个socket
if ($bind) {
echo "socket_bind() successed!\n";
}else{
echo "socket_bind() failed:".socket_strerror ($bind)."\n";
return 0;
}
$listen = socket_listen ($socket); // 间听socket
if ($listen)
echo "socket_listen() successed!\n";
else
echo "socket_listen() failed:".socket_strerror ($listen)."\n";
while (true)
{
$msg = socket_accept ($socket); // 接受一个socket
if (!$msg)
{
echo "socket_accept() failed:".socket_strerror ($msg)."\n";
break;
}
$welcome0 = "welcome to php server!向东\n";
$welcome = iconv("utf-8","gbk",$welcome0);//显示gb的中文,否则在windows cmd 终端显示乱码
socket_write ($msg, $welcome, strlen ($welcome));
while (true)
{
$command = strtoupper (trim (socket_read ($msg, 1024)));
if (!$command)
break;
echo $command."\n";
switch ($command)
{
case "HELLO":
$writer = "hello everybody!";
break;
case "BYE":
$writer = "bye-bye";
break;
case "HELP":
$writer = "hello\tquit\thelp";
break;
default:
$writer = "error command!\n";
}
socket_write ($msg, $writer, strlen ($writer));
if ($command == "QUIT")
break;
}
socket_close ($msg);
}
socket_close ($socket); // 关闭socket
?>
client.php(UTF8编码)
<?php
// Client
// 设置错误处理
error_reporting (E_ALL);
// 设置处理时间
set_time_limit (0);
$ip = "127.0.0.1"; // IP 地址
$port = 8848; // 端口号
$socket = socket_create (AF_INET, SOCK_STREAM, SOL_TCP); // 创建一个SOCKET
if ($socket)
echo "socket_create() successed!/n";
else
echo "socket_create() failed:".socket_strerror ($socket)."/n";
$conn = socket_connect ($socket, $ip, $port); // 建立SOCKET的连接
if ($conn)
echo "Success to connection![".$ip.":".$port."]/n";
else
echo "socket_connect() failed:".socket_strerror ($conn)."/n";
echo socket_read ($socket, 1024);
$stdin = fopen ('php://stdin', 'r');
while (true)
{
$command = trim (fgets ($stdin, 1024));
socket_write ($socket, $command, strlen ($command));
$msg = trim (socket_read ($socket, 1024));
echo $msg."\n";
if ($msg == "Bye-Bye")
break;
}
fclose ($stdin);
socket_close ($socket);
?>
[实践OK]PHP mail 模拟socket下的smtp mail类调试成功发邮件信socket 方式,其就是相当于命令行...
Php/Js/Shell/Go jackxiang 2008-5-29 16:09
1.由于50上的qmail不需要验证就可以发信,有了验证反而出现错误,最后在133那台机器就可以了,auth login afeng133@afeng133.sina.net 123qwe(Base64),然后给126(xxx108@126.com)发了信可以收到,不错不错,以下文件存为utf8 格式:
如果有获取whoami之类的,修改配置文件 php.ini 把exec的执行权限放开!
smtp.class.php:
<?php
set_time_limit(120);
class smtp_mail
{
var $host=""; //主机
var $port="25"; //端口 一般为25
var $user=""; //SMTP认证的帐号
var $pass=""; //认证密码
var $debug = false; //是否显示和服务器会话信息?
var $conn;
var $socket="";
var $result_str; //结果
var $in; //客户机发送的命令
var $from_r; //真实的源信箱,一般与smtp服务器的用户名一样,否则可能由于smtp服务器的设置而发送不成功
var $mailformat=0; //邮件格式 0=普通文本 1=html邮件
function smtp_mail($host,$port,$user,$pass,$debug=false)
{
$this->host = $host;
$this->port = $port;
$this->user = base64_encode($user);
$this->pass = base64_encode($pass);
$this->debug = $debug;
$this->socket = socket_create (AF_INET, SOCK_STREAM, SOL_TCP); //具体用法请参考手册
if($this->socket)
{
//$this->result_str = "创建SOCKET:".socket_strerror(socket_last_error());
$this->result_str = "创建SOCKET:".iconv("GBK","UTF-8//TRANSLIT//IGNORE", socket_strerror(socket_last_error()));
$this->debug_show($this->result_str);
}
else
{
exit("初始化失败,请检查您的网络连接和参数");
}
$this->conn = socket_connect($this->socket,$this->host,$this->port);
if($this->conn)
{
$this->result_str = "创建SOCKET连接:".iconv("GBK","UTF-8//TRANSLIT//IGNORE",socket_strerror(socket_last_error()));
$this->debug_show($this->result_str);
}
else
{
exit("初始化失败,请检查您的网络连接和参数");
}
$this->result_str = "服务器应答:<font color=#cc0000>".socket_read ($this->socket, 1024)."</font>";
$this->debug_show($this->result_str);
}
function debug_show($str)
{
if($this->debug)
{
echo $str."<p>\r\n";
}
}
function send($from,$to,$subject,$body)
{
if($from == "" || $to == "")
{
exit("请输入信箱地址");
}
if($subject == "") $sebject = "无标题";
if($body == "") $body = "无内容";
$All = "From:".$from."\r\n";
$All .= "To:".$to."\r\n";
$All .= "Subject:".$subject."\r\n";
if($this->mailformat==1) $All.= "Content-Type: text/html;\r\n";
else $All .= "Content-Type: text/plain;\r\n";
$All .= "charset=gb2312\r\n\r\n";
$All .= $body;
/*
如果把$All的内容再加处理,就可以实现发送MIME邮件了
不过还需要加很多程序
*/
//以下是和服务器会话
$this->in = "EHLO HELO\r\n";
$this->docommand();
$this->in = "AUTH LOGIN\r\n";
$this->docommand();
$this->in = $this->user."\r\n";
$this->docommand();
$this->in = $this->pass."\r\n";
$this->docommand();
if(!eregi("235",$this->result_str)){
$this->result_str = "smtp 认证失败";
$this->debug_show($this->result_str);
return 0;
}
$this->in = "MAIL FROM:<".$from.">\r\n";
$this->docommand();
$this->in = "RCPT TO:<".$to.">\r\n";
$this->docommand();
$this->in = "DATA\r\n";
$this->docommand();
$this->in = $All."\r\n.\r\n";
$this->docommand();
if(!eregi("250",$this->result_str)){
$this->result_str = "邮件发送失败";
$this->debug_show($this->result_str);
return 0;
}
$this->in = "QUIT\r\n";
$this->docommand();
//结束,关闭连接
return 1;
}
function docommand()
{
socket_write ($this->socket, $this->in, strlen ($this->in));
//$this->debug_show("客户机命令:".iconv("GBK","UTF-8", $this->in));
$this->debug_show("客户机命令:".iconv("GBK","utf-8//TRANSLIT//IGNORE", $this->in)); //防止报错:Notice: iconv(): Unknown error (84)
$this->result_str = "服务器应答:<font color=#cc0000>".iconv("GBK","UTF-8//TRANSLIT//IGNORE", socket_read ($this->socket, 1024))."</font>";
$this->debug_show($this->result_str);
}
} //end class
?>
sendmail.php:
<?php
header("Content-type: text/html; charset=utf-8");
?>
<?php
include("smtp.class.php");
//$mails=new smtp_mail("220.181.15.111","25","xxx108@126.com","********");
$mails=new smtp_mail("220.181.15.111","25","xxx108@126.com","********",true);
$date = date("Y-m-d H:i:s");
if($mails->send("xxx108@126.com","xxx108@126.com","有人于".$date."登录服务器","请注意是否自己在该时间登录。","登录时间。"))
{
echo "发送成功!";
}else{
echo "邮件服务器忙,请稍候再试试";
}
?>
如果有获取谁的exec函数加上(修改配置文件 php.ini 把exec的执行权限放开!):
这个程序的实质是模仿如下终端操作:
telnet smtp.sina.net 25
Trying 202.108.37.33...
Connected to smtp.sina.net.
Escape character is '^]'.
220 sina3-197.sina.net ESMTP - qmail-1.04
helo sina.net
250 sina3-197.sina.net
AUTH LOGIN
334 VXNlcm5hbWU6
ZWFzdHN1bkBlYXN0c3VuLnNpbmEubmV0
334 UGFzc3dvcmQ6
MTIzcXdl
235 验证通过- authentication successfully
data
503 请先用 RCPT - RCPT first (#5.5.1)
mail from:<xxx108@126.com>
250 Mail OK
rcpt to:<xxx108@126.com>
rcpt to:<372647693@qq.com> //第二个抄送人
250 Mail OK
data
354 End data with <CR><LF>.<CR><LF>
From: Mail test <372647693@qq.com>
Sender: jackxiang <xxx108@126.com>
To: xxx108@126.com
Cc: 372647693@qq.com
Subject: mail testing mail title
This is mail content...
.
250 Mail OK queued as smtp1,C8mowEDpO0uNr0dUwfhiAA--.1433S3 1413984769
(最后这个小数点一定要加上)
此时,372647693@qq.com也会收到,这个cc:就是抄送人,在邮件标题里体现,真正发还是在rcpt to:<372647693@qq.com> //第二个抄送人。
邮件标题:
mail testing mail title
发件人:Mail test<372647693@qq.com> (由 xxx108@126.com 代发)
收件人:我<xxx108@126.com>
抄送人:372647693<372647693@qq.com>
This is mail content...
QQ邮箱:
发件人:我自己的邮箱 <372647693@qq.com>(由 xxx108@126.com 代发)
时 间:2014年10月22日(星期三) 晚上9:46
收件人:xdy108 <xxx108@126.com>
抄 送:回忆未来-向东-Jàck <372647693@qq.com>
This is mail content...
————————————————————————————————————————————————————————
以下如果打开$mails=new smtp_mail("smtp.sina.net","25","eastsun@eastsun.sina.net","123qwe","false"); //false
可以看见其到底是如何进行会话的,如下:
创建SOCKET:您的主机中的软件放弃了一个已建立的连接。
创建SOCKET连接:您的主机中的软件放弃了一个已建立的连接。
服务器应答:220 smtp-5-32.sina.net ESMTP - qmail-1.04
客户机命令:EHLO HELO
服务器应答:250-smtp-5-32.sina.net 250-AUTH=LOGIN 250-AUTH LOGIN 250-PIPELININGJH 250 8BITMIME
客户机命令:AUTH LOGIN
服务器应答:334 VXNlcm5hbWU6
客户机命令:ZWFzdHN1bkBlYXN0c3VuLnNpbmEubmV0
服务器应答:334 UGFzc3dvcmQ6
客户机命令:MTIzcXdl
服务器应答:235 验证通过 - authentication successfully
客户机命令:MAIL FROM:xiaoqian@staff.sina.com.cn
服务器应答:250 eastsun@eastsun.sina.netok
客户机命令:RCPT TO:xiangdong2@staff.sina.com.cn
服务器应答:250 ok
客户机命令:DATA
服务器应答:354 请继续 - go ahead
客户机命令:From:xiaoqian@staff.sina.com.cn To:xiangdong2@staff.sina.com.cn Subject:我来个中文测试一下,怎么就不正常了呢,哈哈。。向东 Content-Type: text/plain; charset=gb2312 我来个中文测试一下,这里是信的内容!!! .
服务器应答:250 ok 1212053255 qp 74366
客户机命令:QUIT
服务器应答:221 smtp-5-32.sina.net
发送成功!
对用户名和密码的Base64编码方法:
<?php
$user="xiangdong2@staff.sina.com.cn";
$pass="xiangdong";
$user = base64_encode($user);
$pass = base64_encode($pass);
echo $user."\n";
echo $pass."\n";
?>
[root@vm0000055 ~]# telnet staff.sina.com.cn 110
Trying 10.210.98.10...
Connected to staff.sina.com.cn (10.210.98.10).
Escape character is '^]'.
+OK staff-jes1.sina.com.cn POP3 service (Sun Java(tm) System Messaging Server 6.2-3.04 (built Jul 15 2005))
xiangdong2
-ERR Unrecognized command
xiangdong2@staff.sina.com.cn
-ERR Unrecognized command
USER xiangdong2
+OK Name is a valid mailbox
pass xiangdong
+OK Maildrop ready
AUTH
-ERR Unrecognized command
LIST
+OK scan listing follows
1 1675
2 8490
3 3004
4 625
5 650
6 1877
7 1928
8 1939
9 2131
.
RETR 1
+OK 1675 octets
Return-path: <jinsong@staff.sina.com.cn>
Received: from sina123123123 ([10.218.26.58]) by staff-jes1.sina.com.cn
(Sun Java System Messaging Server 6.2-3.04 (built Jul 15 2005))
id <0KLS00I01MFE7V00@staff-jes1.sina.com.cn>
(original mail from jinsong@staff.sina.com.cn); Thu,
25 Jun 2009 20:01:15 +0800 (CST)
Received: from sina123123123 ([10.218.26.58]) by staff-jes1.sina.com.cn
(Sun Java System Messaging Server 6.2-3.04 (built Jul 15 2005))
with ESMTPA id <0KLS00OCGMQ2Q1B0@staff-jes1.sina.com.cn>; Thu,
25 Jun 2009 20:01:14 +0800 (CST)
Date: Thu, 25 Jun 2009 20:01:34 +0800
From: =?GB2312?B?wbq+osvJ?= <jinsong@staff.sina.com.cn>
Subject:
=?gb2312?B?vfHM7M/Czuc2o7owMLnHuMnN+LnK1c+jrNbQtefQxbPGueO2q7P2yqHCt9PJxvez9rnK1c8g1OyzybulwarN+NO1yPs=?=
To: cpyw <cpyw@staff.sina.com.cn>, sinamail <sinamail@staff.sina.com.cn>,
platform <platform@staff.sina.com.cn>
Message-id: <200906252001339840407@staff.sina.com.cn>
MIME-version: 1.0
X-Mailer: Foxmail 6, 9, 201, 16 [cn]
Content-type: text/plain; charset=gb2312
Content-transfer-encoding: base64
vfHM7M/Czuc2o7owMLnHuMnN+LnK1c+jrNbQtefQxbPGueO2q7P2yqHCt9PJxvez9rnK1c8g1Oyz
ybulwarN+NO1yPsNCmh0dHA6Ly90ZWNoLnNpbmEuY29tLmNuL3QvMjAwOS0wNi0yNS8xOTMyMzIx
MjIyNS5zaHRtbA0KaHR0cDovL3RlY2guc2luYS5jb20uY24vdC8yMDA5LTA2LTI1LzE5MTYzMjEy
MjEzLnNodG1sDQpodHRwOi8vdGVjaC5zaW5hLmNvbS5jbi9pLzIwMDktMDYtMjUvMTkyNTMyMTIy
MTguc2h0bWwNCiAJCQkJDQotLS0tLS0tLS0tLS0tLQ0Kwbq+osvJDQoNCnNpbmG7pbavyefH+NTL
06rWp7PW1+kNCg0Ktee7sKO6MDEwo602MjY3NjgxMQ0KDQrK1rv6o7oxMzcxNzkwMzMxOQ0KDQrT
ys/ko7pqaW5zb25nQHN0YWZmLnNpbmEuY29tLmNuIA0KDQpNU046cm9zZWxpYW5nanNAaG90bWFp
bC5jb20NCg0KUVE6NjQyNzkyMjI0DQoyMDA5LTA2LTI1DQo=
PHP通过Socket来发送网页Post请求和Get请求Ok代码:
如果没有Host在里面[fwrite($sock, "Host: upload.com\r\n");],则会出现:
51 [Mon Jun 20 18:12:19 2011] [error] [client 172.25.38.70] client sent HTTP/1.1 request without hostname (see RFC2616
section 14.23): /upload/upload.cgi
判断refer啥的,这块涉及到php的curl传refer,请参考:
伪造refer: https://jackxiang.com/post/4022/
伪造Host绑定来源:https://jackxiang.com/post/4423/
如果有获取whoami之类的,修改配置文件 php.ini 把exec的执行权限放开!
smtp.class.php:
<?php
set_time_limit(120);
class smtp_mail
{
var $host=""; //主机
var $port="25"; //端口 一般为25
var $user=""; //SMTP认证的帐号
var $pass=""; //认证密码
var $debug = false; //是否显示和服务器会话信息?
var $conn;
var $socket="";
var $result_str; //结果
var $in; //客户机发送的命令
var $from_r; //真实的源信箱,一般与smtp服务器的用户名一样,否则可能由于smtp服务器的设置而发送不成功
var $mailformat=0; //邮件格式 0=普通文本 1=html邮件
function smtp_mail($host,$port,$user,$pass,$debug=false)
{
$this->host = $host;
$this->port = $port;
$this->user = base64_encode($user);
$this->pass = base64_encode($pass);
$this->debug = $debug;
$this->socket = socket_create (AF_INET, SOCK_STREAM, SOL_TCP); //具体用法请参考手册
if($this->socket)
{
//$this->result_str = "创建SOCKET:".socket_strerror(socket_last_error());
$this->result_str = "创建SOCKET:".iconv("GBK","UTF-8//TRANSLIT//IGNORE", socket_strerror(socket_last_error()));
$this->debug_show($this->result_str);
}
else
{
exit("初始化失败,请检查您的网络连接和参数");
}
$this->conn = socket_connect($this->socket,$this->host,$this->port);
if($this->conn)
{
$this->result_str = "创建SOCKET连接:".iconv("GBK","UTF-8//TRANSLIT//IGNORE",socket_strerror(socket_last_error()));
$this->debug_show($this->result_str);
}
else
{
exit("初始化失败,请检查您的网络连接和参数");
}
$this->result_str = "服务器应答:<font color=#cc0000>".socket_read ($this->socket, 1024)."</font>";
$this->debug_show($this->result_str);
}
function debug_show($str)
{
if($this->debug)
{
echo $str."<p>\r\n";
}
}
function send($from,$to,$subject,$body)
{
if($from == "" || $to == "")
{
exit("请输入信箱地址");
}
if($subject == "") $sebject = "无标题";
if($body == "") $body = "无内容";
$All = "From:".$from."\r\n";
$All .= "To:".$to."\r\n";
$All .= "Subject:".$subject."\r\n";
if($this->mailformat==1) $All.= "Content-Type: text/html;\r\n";
else $All .= "Content-Type: text/plain;\r\n";
$All .= "charset=gb2312\r\n\r\n";
$All .= $body;
/*
如果把$All的内容再加处理,就可以实现发送MIME邮件了
不过还需要加很多程序
*/
//以下是和服务器会话
$this->in = "EHLO HELO\r\n";
$this->docommand();
$this->in = "AUTH LOGIN\r\n";
$this->docommand();
$this->in = $this->user."\r\n";
$this->docommand();
$this->in = $this->pass."\r\n";
$this->docommand();
if(!eregi("235",$this->result_str)){
$this->result_str = "smtp 认证失败";
$this->debug_show($this->result_str);
return 0;
}
$this->in = "MAIL FROM:<".$from.">\r\n";
$this->docommand();
$this->in = "RCPT TO:<".$to.">\r\n";
$this->docommand();
$this->in = "DATA\r\n";
$this->docommand();
$this->in = $All."\r\n.\r\n";
$this->docommand();
if(!eregi("250",$this->result_str)){
$this->result_str = "邮件发送失败";
$this->debug_show($this->result_str);
return 0;
}
$this->in = "QUIT\r\n";
$this->docommand();
//结束,关闭连接
return 1;
}
function docommand()
{
socket_write ($this->socket, $this->in, strlen ($this->in));
//$this->debug_show("客户机命令:".iconv("GBK","UTF-8", $this->in));
$this->debug_show("客户机命令:".iconv("GBK","utf-8//TRANSLIT//IGNORE", $this->in)); //防止报错:Notice: iconv(): Unknown error (84)
$this->result_str = "服务器应答:<font color=#cc0000>".iconv("GBK","UTF-8//TRANSLIT//IGNORE", socket_read ($this->socket, 1024))."</font>";
$this->debug_show($this->result_str);
}
} //end class
?>
sendmail.php:
<?php
header("Content-type: text/html; charset=utf-8");
?>
<?php
include("smtp.class.php");
//$mails=new smtp_mail("220.181.15.111","25","xxx108@126.com","********");
$mails=new smtp_mail("220.181.15.111","25","xxx108@126.com","********",true);
$date = date("Y-m-d H:i:s");
if($mails->send("xxx108@126.com","xxx108@126.com","有人于".$date."登录服务器","请注意是否自己在该时间登录。","登录时间。"))
{
echo "发送成功!";
}else{
echo "邮件服务器忙,请稍候再试试";
}
?>
如果有获取谁的exec函数加上(修改配置文件 php.ini 把exec的执行权限放开!):
这个程序的实质是模仿如下终端操作:
telnet smtp.sina.net 25
Trying 202.108.37.33...
Connected to smtp.sina.net.
Escape character is '^]'.
220 sina3-197.sina.net ESMTP - qmail-1.04
helo sina.net
250 sina3-197.sina.net
AUTH LOGIN
334 VXNlcm5hbWU6
ZWFzdHN1bkBlYXN0c3VuLnNpbmEubmV0
334 UGFzc3dvcmQ6
MTIzcXdl
235 验证通过- authentication successfully
data
503 请先用 RCPT - RCPT first (#5.5.1)
mail from:<xxx108@126.com>
250 Mail OK
rcpt to:<xxx108@126.com>
rcpt to:<372647693@qq.com> //第二个抄送人
250 Mail OK
data
354 End data with <CR><LF>.<CR><LF>
From: Mail test <372647693@qq.com>
Sender: jackxiang <xxx108@126.com>
To: xxx108@126.com
Cc: 372647693@qq.com
Subject: mail testing mail title
This is mail content...
.
250 Mail OK queued as smtp1,C8mowEDpO0uNr0dUwfhiAA--.1433S3 1413984769
(最后这个小数点一定要加上)
此时,372647693@qq.com也会收到,这个cc:就是抄送人,在邮件标题里体现,真正发还是在rcpt to:<372647693@qq.com> //第二个抄送人。
邮件标题:
mail testing mail title
发件人:Mail test<372647693@qq.com> (由 xxx108@126.com 代发)
收件人:我<xxx108@126.com>
抄送人:372647693<372647693@qq.com>
This is mail content...
QQ邮箱:
发件人:我自己的邮箱 <372647693@qq.com>(由 xxx108@126.com 代发)
时 间:2014年10月22日(星期三) 晚上9:46
收件人:xdy108 <xxx108@126.com>
抄 送:回忆未来-向东-Jàck <372647693@qq.com>
This is mail content...
————————————————————————————————————————————————————————
以下如果打开$mails=new smtp_mail("smtp.sina.net","25","eastsun@eastsun.sina.net","123qwe","false"); //false
可以看见其到底是如何进行会话的,如下:
创建SOCKET:您的主机中的软件放弃了一个已建立的连接。
创建SOCKET连接:您的主机中的软件放弃了一个已建立的连接。
服务器应答:220 smtp-5-32.sina.net ESMTP - qmail-1.04
客户机命令:EHLO HELO
服务器应答:250-smtp-5-32.sina.net 250-AUTH=LOGIN 250-AUTH LOGIN 250-PIPELININGJH 250 8BITMIME
客户机命令:AUTH LOGIN
服务器应答:334 VXNlcm5hbWU6
客户机命令:ZWFzdHN1bkBlYXN0c3VuLnNpbmEubmV0
服务器应答:334 UGFzc3dvcmQ6
客户机命令:MTIzcXdl
服务器应答:235 验证通过 - authentication successfully
客户机命令:MAIL FROM:xiaoqian@staff.sina.com.cn
服务器应答:250 eastsun@eastsun.sina.netok
客户机命令:RCPT TO:xiangdong2@staff.sina.com.cn
服务器应答:250 ok
客户机命令:DATA
服务器应答:354 请继续 - go ahead
客户机命令:From:xiaoqian@staff.sina.com.cn To:xiangdong2@staff.sina.com.cn Subject:我来个中文测试一下,怎么就不正常了呢,哈哈。。向东 Content-Type: text/plain; charset=gb2312 我来个中文测试一下,这里是信的内容!!! .
服务器应答:250 ok 1212053255 qp 74366
客户机命令:QUIT
服务器应答:221 smtp-5-32.sina.net
发送成功!
对用户名和密码的Base64编码方法:
<?php
$user="xiangdong2@staff.sina.com.cn";
$pass="xiangdong";
$user = base64_encode($user);
$pass = base64_encode($pass);
echo $user."\n";
echo $pass."\n";
?>
[root@vm0000055 ~]# telnet staff.sina.com.cn 110
Trying 10.210.98.10...
Connected to staff.sina.com.cn (10.210.98.10).
Escape character is '^]'.
+OK staff-jes1.sina.com.cn POP3 service (Sun Java(tm) System Messaging Server 6.2-3.04 (built Jul 15 2005))
xiangdong2
-ERR Unrecognized command
xiangdong2@staff.sina.com.cn
-ERR Unrecognized command
USER xiangdong2
+OK Name is a valid mailbox
pass xiangdong
+OK Maildrop ready
AUTH
-ERR Unrecognized command
LIST
+OK scan listing follows
1 1675
2 8490
3 3004
4 625
5 650
6 1877
7 1928
8 1939
9 2131
.
RETR 1
+OK 1675 octets
Return-path: <jinsong@staff.sina.com.cn>
Received: from sina123123123 ([10.218.26.58]) by staff-jes1.sina.com.cn
(Sun Java System Messaging Server 6.2-3.04 (built Jul 15 2005))
id <0KLS00I01MFE7V00@staff-jes1.sina.com.cn>
(original mail from jinsong@staff.sina.com.cn); Thu,
25 Jun 2009 20:01:15 +0800 (CST)
Received: from sina123123123 ([10.218.26.58]) by staff-jes1.sina.com.cn
(Sun Java System Messaging Server 6.2-3.04 (built Jul 15 2005))
with ESMTPA id <0KLS00OCGMQ2Q1B0@staff-jes1.sina.com.cn>; Thu,
25 Jun 2009 20:01:14 +0800 (CST)
Date: Thu, 25 Jun 2009 20:01:34 +0800
From: =?GB2312?B?wbq+osvJ?= <jinsong@staff.sina.com.cn>
Subject:
=?gb2312?B?vfHM7M/Czuc2o7owMLnHuMnN+LnK1c+jrNbQtefQxbPGueO2q7P2yqHCt9PJxvez9rnK1c8g1OyzybulwarN+NO1yPs=?=
To: cpyw <cpyw@staff.sina.com.cn>, sinamail <sinamail@staff.sina.com.cn>,
platform <platform@staff.sina.com.cn>
Message-id: <200906252001339840407@staff.sina.com.cn>
MIME-version: 1.0
X-Mailer: Foxmail 6, 9, 201, 16 [cn]
Content-type: text/plain; charset=gb2312
Content-transfer-encoding: base64
vfHM7M/Czuc2o7owMLnHuMnN+LnK1c+jrNbQtefQxbPGueO2q7P2yqHCt9PJxvez9rnK1c8g1Oyz
ybulwarN+NO1yPsNCmh0dHA6Ly90ZWNoLnNpbmEuY29tLmNuL3QvMjAwOS0wNi0yNS8xOTMyMzIx
MjIyNS5zaHRtbA0KaHR0cDovL3RlY2guc2luYS5jb20uY24vdC8yMDA5LTA2LTI1LzE5MTYzMjEy
MjEzLnNodG1sDQpodHRwOi8vdGVjaC5zaW5hLmNvbS5jbi9pLzIwMDktMDYtMjUvMTkyNTMyMTIy
MTguc2h0bWwNCiAJCQkJDQotLS0tLS0tLS0tLS0tLQ0Kwbq+osvJDQoNCnNpbmG7pbavyefH+NTL
06rWp7PW1+kNCg0Ktee7sKO6MDEwo602MjY3NjgxMQ0KDQrK1rv6o7oxMzcxNzkwMzMxOQ0KDQrT
ys/ko7pqaW5zb25nQHN0YWZmLnNpbmEuY29tLmNuIA0KDQpNU046cm9zZWxpYW5nanNAaG90bWFp
bC5jb20NCg0KUVE6NjQyNzkyMjI0DQoyMDA5LTA2LTI1DQo=
PHP通过Socket来发送网页Post请求和Get请求Ok代码:
如果没有Host在里面[fwrite($sock, "Host: upload.com\r\n");],则会出现:
51 [Mon Jun 20 18:12:19 2011] [error] [client 172.25.38.70] client sent HTTP/1.1 request without hostname (see RFC2616
section 14.23): /upload/upload.cgi
判断refer啥的,这块涉及到php的curl传refer,请参考:
伪造refer: https://jackxiang.com/post/4022/
伪造Host绑定来源:https://jackxiang.com/post/4423/
function set_upload_data($arr_upload)
{
$this->attachment=$arr_upload[files];
$this->upload_dir=$arr_upload["upload_dir"];
}
function uploadfile()
{
$fileName = mb_convert_encoding($this->attachment['name'],'GBK','UTF-8');//这一行开始转码,否则出现乱码
//$fileName = iconv("UTF-8","GBK", $this->attachment['name']); //这样也行,由UTF-8转到GBK,和上面的函数有区别
if(move_uploaded_file($this->attachment['tmp_name'],$this->upload_dir.$fileName))
{
return 1;//上传成功
}else{
return 0;//上传失败
}
}
参考如下文章:
mb_convert_encoding这个函数是用来转换编码的。原来一直对程序编码这一概念不理解,不过现在好像有点开窍了。
不过英文一般不会存在编码问题,只有中文数据才会有这个问题。比如你用Zend Studio或Editplus写程序时,用的是gbk编码,如果数据需要入数据库,而数据库的编码为utf8时,这时就要把数据进行编码转换,不然进到数据库就会变成乱码。
mb_convert_encoding的用法见官方:
http://cn.php.net/manual/zh/function.mb-convert-encoding.php
做一个GBK To UTF-8
< ?php
header("content-Type: text/html; charset=Utf-8");
echo mb_convert_encoding("妳係我的友仔", "UTF-8", "GBK");
?>
再来个GB2312 To Big5
< ?php
header("content-Type: text/html; charset=big5");
echo mb_convert_encoding("你是我的朋友", "big5", "GB2312");
?>
不过要使用上面的函数需要安装但是需要先enable mbstring 扩展库。
PHP中的另外一个函数iconv也是用来转换字符串编码的,与上函数功能相似。
下面还有一些详细的例子:
iconv — Convert string to requested character encoding
(PHP 4 >= 4.0.5, PHP 5)
mb_convert_encoding — Convert character encoding
(PHP 4 >= 4.0.6, PHP 5)
用法:
string mb_convert_encoding ( string str, string to_encoding [, mixed from_encoding] )
需要先enable mbstring 扩展库,在 php.ini里将; extension=php_mbstring.dll 前面的 ; 去掉
mb_convert_encoding 可以指定多种输入编码,它会根据内容自动识别,但是执行效率比iconv差太多;
string iconv ( string in_charset, string out_charset, string str )
注意:第二个参数,除了可以指定要转化到的编码以外,还可以增加两个后缀://TRANSLIT 和 //IGNORE,其中 //TRANSLIT 会自动将不能直接转化的字符变成一个或多个近似的字符,//IGNORE 会忽略掉不能转化的字符,而默认效果是从第一个非法字符截断。
Returns the converted string or FALSE on failure.
使用:
发现iconv在转换字符”—”到gb2312时会出错,如果没有ignore参数,所有该字符后面的字符串都无法被保存。不管怎么样,这个”—”都无法转换成功,无法输出。 另外mb_convert_encoding没有这个bug.
一般情况下用 iconv,只有当遇到无法确定原编码是何种编码,或者iconv转化后无法正常显示时才用mb_convert_encoding 函数.
from_encoding is specified by character code name before conversion. it can be array or string - comma separated enumerated list. If it is not specified, the internal encoding will be used.
/* Auto detect encoding from JIS, eucjp-win, sjis-win, then convert str to UCS-2LE */
$str = mb_convert_encoding($str, “UCS-2LE”, “JIS, eucjp-win, sjis-win”);
/* “auto” is expanded to “ASCII,JIS,UTF-8,EUC-JP,SJIS” */
$str = mb_convert_encoding($str, “EUC-JP”, “auto”);
例子:
$content = iconv(”GBK”, “UTF-8″, $content);
$content = mb_convert_encoding($content, “UTF-8″, “GBK”);
如果前端是GBK,而在生成Json时需要做转换才能中文正常显示,如下(把GBK转为Utf8):
最后:Ajax走的都是Utf8,所以得从GBK转为Utf8.
{
$this->attachment=$arr_upload[files];
$this->upload_dir=$arr_upload["upload_dir"];
}
function uploadfile()
{
$fileName = mb_convert_encoding($this->attachment['name'],'GBK','UTF-8');//这一行开始转码,否则出现乱码
//$fileName = iconv("UTF-8","GBK", $this->attachment['name']); //这样也行,由UTF-8转到GBK,和上面的函数有区别
if(move_uploaded_file($this->attachment['tmp_name'],$this->upload_dir.$fileName))
{
return 1;//上传成功
}else{
return 0;//上传失败
}
}
参考如下文章:
mb_convert_encoding这个函数是用来转换编码的。原来一直对程序编码这一概念不理解,不过现在好像有点开窍了。
不过英文一般不会存在编码问题,只有中文数据才会有这个问题。比如你用Zend Studio或Editplus写程序时,用的是gbk编码,如果数据需要入数据库,而数据库的编码为utf8时,这时就要把数据进行编码转换,不然进到数据库就会变成乱码。
mb_convert_encoding的用法见官方:
http://cn.php.net/manual/zh/function.mb-convert-encoding.php
做一个GBK To UTF-8
< ?php
header("content-Type: text/html; charset=Utf-8");
echo mb_convert_encoding("妳係我的友仔", "UTF-8", "GBK");
?>
再来个GB2312 To Big5
< ?php
header("content-Type: text/html; charset=big5");
echo mb_convert_encoding("你是我的朋友", "big5", "GB2312");
?>
不过要使用上面的函数需要安装但是需要先enable mbstring 扩展库。
PHP中的另外一个函数iconv也是用来转换字符串编码的,与上函数功能相似。
下面还有一些详细的例子:
iconv — Convert string to requested character encoding
(PHP 4 >= 4.0.5, PHP 5)
mb_convert_encoding — Convert character encoding
(PHP 4 >= 4.0.6, PHP 5)
用法:
string mb_convert_encoding ( string str, string to_encoding [, mixed from_encoding] )
需要先enable mbstring 扩展库,在 php.ini里将; extension=php_mbstring.dll 前面的 ; 去掉
mb_convert_encoding 可以指定多种输入编码,它会根据内容自动识别,但是执行效率比iconv差太多;
string iconv ( string in_charset, string out_charset, string str )
注意:第二个参数,除了可以指定要转化到的编码以外,还可以增加两个后缀://TRANSLIT 和 //IGNORE,其中 //TRANSLIT 会自动将不能直接转化的字符变成一个或多个近似的字符,//IGNORE 会忽略掉不能转化的字符,而默认效果是从第一个非法字符截断。
Returns the converted string or FALSE on failure.
使用:
发现iconv在转换字符”—”到gb2312时会出错,如果没有ignore参数,所有该字符后面的字符串都无法被保存。不管怎么样,这个”—”都无法转换成功,无法输出。 另外mb_convert_encoding没有这个bug.
一般情况下用 iconv,只有当遇到无法确定原编码是何种编码,或者iconv转化后无法正常显示时才用mb_convert_encoding 函数.
from_encoding is specified by character code name before conversion. it can be array or string - comma separated enumerated list. If it is not specified, the internal encoding will be used.
/* Auto detect encoding from JIS, eucjp-win, sjis-win, then convert str to UCS-2LE */
$str = mb_convert_encoding($str, “UCS-2LE”, “JIS, eucjp-win, sjis-win”);
/* “auto” is expanded to “ASCII,JIS,UTF-8,EUC-JP,SJIS” */
$str = mb_convert_encoding($str, “EUC-JP”, “auto”);
例子:
$content = iconv(”GBK”, “UTF-8″, $content);
$content = mb_convert_encoding($content, “UTF-8″, “GBK”);
如果前端是GBK,而在生成Json时需要做转换才能中文正常显示,如下(把GBK转为Utf8):
最后:Ajax走的都是Utf8,所以得从GBK转为Utf8.
PHP的主要语言开发者之一、Zend公司的创始人之一Andi Gutmans最近在blog中直言不讳地批评了Java语言。他指出,目前Java厂商试图在JVM上提供动态语言实现的路子根本不对,Java已经输掉了Web开发语言的战争,PHP是事实上的标准和胜利者。
Gutmans的这篇文章在技术界引发了强烈争议,很对人对此有不同的意见,我在这里就阐述一下我对PHP和Java两种语言的看法。
我早先曾经在《Perl、PHP、ASP、JSP技术比较》一文中对比过PHP和Java的异同,简而言之,PHP是一种解释执行的脚本语言,语法和C语言类似,易学易用,不懂电脑的非专业人员稍经学习也能使用PHP.而Java要先编译成Class文件,然后在Java虚拟机上执行,Java开发需要熟悉Java语法以及一些核心的架构,从而实现一种可复用的、跨平台的软件,Java比PHP要难学的多。
实际上,从技术架构来说,Java语言相比PHP有明显的优势,Java使用的是面向对象的系统设计方法,而PHP还是采用面向过程的开发方法。PHP只能实现简单的分布式两层或三层的架构,而JAVA可以实现多层架构。数据库层(持久化层)、应用(业务)逻辑层、表示逻辑层彼此分开,而且现在不同的层都已经有一些成熟的开发框架的支持。例如Struts就是利用Java的web开发技术实现了MVC的设计模式,而在业务逻辑层也有Spring框架,数据库持久化层有Hibernate等框架。这些框架可以方便开发者高效、合理、科学得架构多层的商业应用。从数学运算和数据库访问速度来讲,Java的性能也优于PHP.实际上,对于跨平台的大型的企业应用系统来讲,Java几乎已经成为唯一的选择(微软.NET不支持跨平台),但是在于Web网站应用开发来讲,Java却面临着被PHP边缘化的危险,几乎所有的虚拟主机都支持PHP+MySQL,而支持Java的却少之又少,在资源上,网上有不计其数的PHP资源,很多著名的大型网站(例如Facebook、Mediawiki等)都是基于PHP的,而成功的Java网站却寥寥无几,这又是什么原因呢?
Java的理念是“一次编写,到处运行”,Java在应用框架底下的架构是无与伦比的,远胜过其他任何语言,Java的框架利于大型的协同编程开发,系统易维护、可复用性较好。而PHP很容易自学,让热备能快速简洁地编写代码,适合于快速开发,中小型应用系统,开发成本低。在调试、发布上,PHP也较Java简单。
理念上的不同导致了Java和PHP在Web应用开发上显示了不同的结果,尽管Java的数学计算和数据库访问都有优势,架构也相当完美,但是PHP却可以简单轻松地支持高强度Web访问,能够快速开发应用,支持PHP的虚拟主机多如牛毛,使得用PHP开发一个网站比用Java开发一个网站要快得多,容易的多。Java所拥有的优点只适合传统的以软件项目为核心的开发模式,而PHP更适合于以客户为核心的SaaS的开发模式,因此,PHP目前在Web网站开发的优势完全是因为Web网站开发的特殊性而导致的,并非编程语言特性所决定。
因此,PHP在Web网站开发语言的战争中已经慢慢将Java抛在了后面,Java要想在Web网站开发上奋起直追,的确应该多听听Andi Gutmans的意见,彻底改变一下思路才行,否则两者的差距只能是越来越远。
另外,虽然在国际上LAMP(Linux+Apache+Mysql+Php)架构已经占领了统治地位,但是在中国国内还有一个怪胎,就是基于微软的Windows Server+IIS+SqlServer+ASP/ASP.NET的架构,从理论上说,微软的这一套架构也能实现不错的性能,只可惜Windows和SqlServer价格不菲,整个架构在性能上比起LAMP不仅没有什么优势,反而还有不少劣势,因此微软的这一套家伙在国际市场上吃不开。而国内使用微软盗版则可以忽略成本,而ASP的易学易用性不逊于PHP,甚至连IT外行都能够使用,因此在国内也有不小的市场。但是随着中国在保护知识产权方面的日趋完善,免费的LAMP依旧是未来的趋势。
Gutmans的这篇文章在技术界引发了强烈争议,很对人对此有不同的意见,我在这里就阐述一下我对PHP和Java两种语言的看法。
我早先曾经在《Perl、PHP、ASP、JSP技术比较》一文中对比过PHP和Java的异同,简而言之,PHP是一种解释执行的脚本语言,语法和C语言类似,易学易用,不懂电脑的非专业人员稍经学习也能使用PHP.而Java要先编译成Class文件,然后在Java虚拟机上执行,Java开发需要熟悉Java语法以及一些核心的架构,从而实现一种可复用的、跨平台的软件,Java比PHP要难学的多。
实际上,从技术架构来说,Java语言相比PHP有明显的优势,Java使用的是面向对象的系统设计方法,而PHP还是采用面向过程的开发方法。PHP只能实现简单的分布式两层或三层的架构,而JAVA可以实现多层架构。数据库层(持久化层)、应用(业务)逻辑层、表示逻辑层彼此分开,而且现在不同的层都已经有一些成熟的开发框架的支持。例如Struts就是利用Java的web开发技术实现了MVC的设计模式,而在业务逻辑层也有Spring框架,数据库持久化层有Hibernate等框架。这些框架可以方便开发者高效、合理、科学得架构多层的商业应用。从数学运算和数据库访问速度来讲,Java的性能也优于PHP.实际上,对于跨平台的大型的企业应用系统来讲,Java几乎已经成为唯一的选择(微软.NET不支持跨平台),但是在于Web网站应用开发来讲,Java却面临着被PHP边缘化的危险,几乎所有的虚拟主机都支持PHP+MySQL,而支持Java的却少之又少,在资源上,网上有不计其数的PHP资源,很多著名的大型网站(例如Facebook、Mediawiki等)都是基于PHP的,而成功的Java网站却寥寥无几,这又是什么原因呢?
Java的理念是“一次编写,到处运行”,Java在应用框架底下的架构是无与伦比的,远胜过其他任何语言,Java的框架利于大型的协同编程开发,系统易维护、可复用性较好。而PHP很容易自学,让热备能快速简洁地编写代码,适合于快速开发,中小型应用系统,开发成本低。在调试、发布上,PHP也较Java简单。
理念上的不同导致了Java和PHP在Web应用开发上显示了不同的结果,尽管Java的数学计算和数据库访问都有优势,架构也相当完美,但是PHP却可以简单轻松地支持高强度Web访问,能够快速开发应用,支持PHP的虚拟主机多如牛毛,使得用PHP开发一个网站比用Java开发一个网站要快得多,容易的多。Java所拥有的优点只适合传统的以软件项目为核心的开发模式,而PHP更适合于以客户为核心的SaaS的开发模式,因此,PHP目前在Web网站开发的优势完全是因为Web网站开发的特殊性而导致的,并非编程语言特性所决定。
因此,PHP在Web网站开发语言的战争中已经慢慢将Java抛在了后面,Java要想在Web网站开发上奋起直追,的确应该多听听Andi Gutmans的意见,彻底改变一下思路才行,否则两者的差距只能是越来越远。
另外,虽然在国际上LAMP(Linux+Apache+Mysql+Php)架构已经占领了统治地位,但是在中国国内还有一个怪胎,就是基于微软的Windows Server+IIS+SqlServer+ASP/ASP.NET的架构,从理论上说,微软的这一套架构也能实现不错的性能,只可惜Windows和SqlServer价格不菲,整个架构在性能上比起LAMP不仅没有什么优势,反而还有不少劣势,因此微软的这一套家伙在国际市场上吃不开。而国内使用微软盗版则可以忽略成本,而ASP的易学易用性不逊于PHP,甚至连IT外行都能够使用,因此在国内也有不小的市场。但是随着中国在保护知识产权方面的日趋完善,免费的LAMP依旧是未来的趋势。
http协议是一种无状态的连接,要想跟踪用户的行为就必须有一个能工作于不同于页面的变量,在PHP中可以用cookie和session两种办法实现。
cookie大家比较熟悉了,就是在把变量存为客户端上的一个文件而已,但是如果客户禁止cookie就没办法了。这就需要session了,在PHP4 中,session可以有两种办法实现,一是用cookie,即把sessionID保存在cookie文件中;二是把sessionID附带在URL上进行传递。
虽有这两种办法实现,但至于使用哪种方法是不用程序员操心的,PHP会自动检查客户cookie的设置的(指linux/unix平台,Win32未知),并且默认的是优先使用cookie(你可以修改php.ini文件中的[session]一节的session.use_cookies的值来改变)。当然你也可以强制使用URL来传递SessionID,如下:
<a href="submit.php<?=sessionID;?>">提交表单</a>
仅在链接中加一句<?=sessionID;?>就行了,简单吧?在php.ini中还有许多关于Session的设置,如 session.cookie_lifetime是session的有效时间等,都在[session]一节中,若看看的话会对PHP中的session 有更多的理解的。
具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。同时我们也看到,由于采用服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的,但实际上它还有其他选择。
cookie机制。正统的cookie分发是通过扩展HTTP协议来实现的,服务器通过在HTTP的响应头中加上一行特殊的指示以提示浏览器按照指示生成相应的cookie。然而纯粹的客户端脚本如JavaScript或者VBScript也可以生成cookie。而cookie的使用是由浏览器按照一定的原则在后台自动发送给服务器的。浏览器检查所有存储的cookie,如果某个cookie所声明的作用范围大于等于将要请求的资源所在的位置,则把该 cookie附在请求资源的HTTP请求头上发送给服务器。
cookie的内容主要包括:名字,值,过期时间,路径和域。路径与域一起构成cookie的作用范围。若不设置过期时间,则表示这个cookie的生命期为浏览器会话期间,关闭浏览器窗口,cookie就消失。这种生命期为浏览器会话期的cookie被称为会话cookie。会话cookie一般不存储在硬盘上而是保存在内存里,当然这种行为并不是规范规定的。若设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些 cookie仍然有效直到超过设定的过期时间。存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存里的 cookie,不同的浏览器有不同的处理方式
session机制。session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。
当程序需要为某个客户端的请求创建一个session时,服务器首先检查这个客户端的请求里是否已包含了一个session标识(称为session id),如果已包含则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用(检索不到,会新建一个),如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。
保存这个session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发挥给服务器。一般这个cookie的名字都是类似于 SEEESIONID。但cookie可以被人为的禁止,则必须有其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。
经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL路径的后面。还有一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。比如:
<form name="testform" action="/xxx">
<input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
<input type="text">
</form>
实际上这种技术可以简单的用对action应用URL重写来代替。
在一个页面设置一个cookie时,必须刷新或到下一个页面才可以用 $_COOKIE 得到变量的值.
原因是因为当页面第一次被浏览器访问载入时,页面中的 cookie 会被设置,将其发送存储到客户端指定的
存储位置,所以$_COOKIE没有接收到客户端发送过来的 cookie 变量的值,当刷新或到下一个页面时,客户
端会在页面程序在服务器端运行之前,发送与该地址相对应的 cookie到服务器端,所以 $_COOKIE 可以得
到的值!
说白了就是当每一个页面被访问时,如果客户端找到了与访问地址相对应的 cookie 时,会在程序在服务器
端运行之前发送这个 cookie 到服务器端. (个人对此的看法)
本人表达能力不强,如有不明,还请抱歉!
php中设置cookie数组的时候,不可以用像php中的那个添加数据的方法:
<?php
setcookie('my_cookie[]', 1);
setcookie('my_cookie[]', 2);
print_r($_COOKIE); // Array ( [my_cookie] => Array ( [0] => 1 ))
// 数组的值添加是添加成功了,不过索引没有变,后面的数据将前的数据覆盖了!
由此得到
my_cookie[],默认指向数据的第一元素的位置,即索引为
0 的位置. 注意与php中的不一样! 以后用cookie数据记住要指定数组元素索引哦!
$my_cookie[] = 1;
$my_cookie[] = 2;
print_r($my_cookie); //Array ( [0] => 1 [1] => 2)
?>
删除 cookie 变量的两个方法:
1.php
<?php
setcookie('user_name_1', 'zhaofei299', time()+3600); // 生存期为 1 个小时
setcookie('user_name_2', 'ZHAOFEI299', time()+3600); // 生存期为 1 个小时
?>
2.php
<?php
setcookie('user_name_1'); // 第一种
setcookie('user_name_2', "", time()-1); // 第二种
print_r($_COOKIE); // 刷新页面2下以上会输出 Array ( [user_name_1] => )
/*为什么超级全局变量 $_COOKIE 中的 user_name_1 没有被删除(变量为空并不代表不存在),而
user_name_2被删除了? 那是因为两个删除变量的方式不同!
第一种: 是设置了 cookie 的生存期, 只不过是将它的值默认设置为空,生存期为与浏览器一样,浏览器
关闭时,cookie才会删除!所以当重新打开一个浏览器,输出地址时,才会发现 cookie 变量全部被删除了!
将2.php 中两个 setcookie() 函数部分注释掉看看(重新输出了地址)!
第二种: 也是设置了 cookie 的生存期,是使 cookie 的生存期一定过期, cookie 也就被删除,所以刷
新页面,客户端向服务器端发送 cookie 时, $_COOKIE 并没有能够得到该cookie变量的值!
*/
?>
会话id默认储放在客户端Cookie中!
<?php
session_start();
print_r($_COOKIE);
?>
cookie的设置有两种方法
header('set-cookie:user=zhaofei299');
setcookie('user', 'zhaofei299');
会话变量不能被GET数据或POST数据重载!
使用session变量传递数组,对象时无需序列化!
使用session变量传递对象时,在调用session_start()之前,必须包含该对类对象的定义,反序列化
(serialize)也是如此!
删除单个会话变量可以使用unset($_SESSION['***']) 直接删除!
删除所有的会话变量不可以用unset($_SESSION),因为这样会将所有的会话信息删除,包含存储在COOKIE
中的PHPSESSID,也就是破坏了两个页面之间的会话联系,应该使用$_SESSION = array();
消除会话id,使页面之间失去联系!
session_destroy();
程序清单1.1
<?php
session_start();
header('content-type:text/html;charset=utf-8');
$_SESSION['a'] = 'a';
$_SESSION['b'] = 'b';
unset($_SESSION); //测试后,再注释下看看
$_SESSION['user'] = 'zhaofei299';
echo 'SESSION_ID: '.session_id().'<br />';
echo '<a href="3.php" target="_blank">测试下</a>';
?>
<?php
session_start();
echo $_SESSION['user'];
echo session_id(); //会话变量改变了
?>
会话id(session_id)的两种方式传递:
1.cookie
2.url
因为默认session是基于cookie的,而cookie又是跟随http协议发送的,所以与cookie一样,在
session_start()之前不能有任何输出!
现在主要说一说第二种,通过 url 传递会话id
php中已经定义SID这个常量来得到 会话的id
sesssin_id 的使用!
<?php
session_start();
echo defined('SID')?'true':'false'; // true
echo SID; //什么也没有?
?>
为什么SID的值会是null 呢?是它哪里有问题了?
原因是因为 session 默认是基于 cookie 的,而 SID 只有 session_id 通过 url
传递数据时才会被赋值!
在浏览器中将 cookie 禁用,你就会发现 SID 有了输出,而不是 null!
删除session
要三步实现.
<?php
session_destroy(); // 第一步: 删除服务器端session文件,这使用
setcookie(session_name(),'',time()-3600); // 第二步: 删除实际的session:
$_SESSION = array(); // 第三步: 删除$_SESSION全局变量数组
?>
大家都知道session变量是保存在服务器端的,也就是说session的变量会保存在服务器中一个目录中,我
们可以在php.ini中的session.save_path 那里可以找到session文件中保存的地址.
默认的session的生存期是浏览的关闭就结束,但要知道会话过期结束后,当打开页面session_start()会
判断会话id 是否存在,如果不存在就创建一个,否则将该会话id 的变量载入页面!因为过期session_id会
被创建一个新的,但它保存在服务器端的session文件并没有被删除(关闭浏览器,打开session文件保存
地看看),所以要用session_destory()函数清除会话id,并同时清除相应的会话文件,这样的话才能做到最
彻底的清除!
session_id 使用 url 传递session 变量数据时,因为session_start()开启会话时会判断会话id 是否存
在,如果不存在就创建一个,否则将该会话id 的变量载入页面!
而现在是使用url 来传递session_id,然而每一次 刷新/进入页面 都会生成一个会话id,所以页面之间就
不能得到在另一页面设置过的session_id 的变量,那么使用 session也就没什么意义了!
解决方法:在session_start()之前,手动设置页面的session_id,这样页面的就可以得到前一页中所设置的
session变量的,也就实现了会话的传递,如下代码可以说明!
//已禁用 cookie
1.php
<?php
session_start();
$_SESSION['user'] = 'zhaofei299';
echo '<a href="2.php?'.SID.'">下一页</a>';
?>
1.php的第4行代码也可以写成:echo '<a href="2.php">下一页</a>';
可以设置php.ini 中的 session.use_trans_sid 为1,这样当使用 url 传递会话 id 时,
浏览器会自动将 session_id 追加到 url 的后面!
就好像 在浏览器中 输入: www.baidu.com 一样,浏览器会自动将其更换成 http://www.baidu.com/
2.php
<?php
session_id($_GET['PHPSESSID']); // 手动设置session_id,这种就可以使用前一个页面的
session_id 的变量了,也就实现了会话!
session_start();
print_r($_SESSION);
?>
常用session函数:
bool session_start(void); 初始化session
bool session_destroy(void): 删除服务器端session关联文件。
string session_id() 当前session的id
string session_name() 当前存取的session名称,也就是客户端保存session ID的cookie名称.默认
PHPSESSID。
array session_get_cookie_params() 与这个session相关联的session的细节.
string session_cache_limiter() 控制使用session的页面的客户端缓存
ini session_cache_expire() 控制客户端缓存时间
bool session_destroy() 删除服务器端保存session信息的文件
void session_set_cookie_params ( int lifetime [, string path [, string domain [, bool
secure [, bool httponly]]]] )设置与这个session相关联的session的细节
bool session_set_save_handler ( callback open, callback close, callback read, callback
write, callback destroy, callback gc )定义处理session的函数,(不是使用默认的方式)
bool session_regenerate_id([bool delete_old_session]) 分配新的session id
cookie大家比较熟悉了,就是在把变量存为客户端上的一个文件而已,但是如果客户禁止cookie就没办法了。这就需要session了,在PHP4 中,session可以有两种办法实现,一是用cookie,即把sessionID保存在cookie文件中;二是把sessionID附带在URL上进行传递。
虽有这两种办法实现,但至于使用哪种方法是不用程序员操心的,PHP会自动检查客户cookie的设置的(指linux/unix平台,Win32未知),并且默认的是优先使用cookie(你可以修改php.ini文件中的[session]一节的session.use_cookies的值来改变)。当然你也可以强制使用URL来传递SessionID,如下:
<a href="submit.php<?=sessionID;?>">提交表单</a>
仅在链接中加一句<?=sessionID;?>就行了,简单吧?在php.ini中还有许多关于Session的设置,如 session.cookie_lifetime是session的有效时间等,都在[session]一节中,若看看的话会对PHP中的session 有更多的理解的。
具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。同时我们也看到,由于采用服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的,但实际上它还有其他选择。
cookie机制。正统的cookie分发是通过扩展HTTP协议来实现的,服务器通过在HTTP的响应头中加上一行特殊的指示以提示浏览器按照指示生成相应的cookie。然而纯粹的客户端脚本如JavaScript或者VBScript也可以生成cookie。而cookie的使用是由浏览器按照一定的原则在后台自动发送给服务器的。浏览器检查所有存储的cookie,如果某个cookie所声明的作用范围大于等于将要请求的资源所在的位置,则把该 cookie附在请求资源的HTTP请求头上发送给服务器。
cookie的内容主要包括:名字,值,过期时间,路径和域。路径与域一起构成cookie的作用范围。若不设置过期时间,则表示这个cookie的生命期为浏览器会话期间,关闭浏览器窗口,cookie就消失。这种生命期为浏览器会话期的cookie被称为会话cookie。会话cookie一般不存储在硬盘上而是保存在内存里,当然这种行为并不是规范规定的。若设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些 cookie仍然有效直到超过设定的过期时间。存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存里的 cookie,不同的浏览器有不同的处理方式
session机制。session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。
当程序需要为某个客户端的请求创建一个session时,服务器首先检查这个客户端的请求里是否已包含了一个session标识(称为session id),如果已包含则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用(检索不到,会新建一个),如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。
保存这个session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发挥给服务器。一般这个cookie的名字都是类似于 SEEESIONID。但cookie可以被人为的禁止,则必须有其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。
经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL路径的后面。还有一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。比如:
<form name="testform" action="/xxx">
<input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
<input type="text">
</form>
实际上这种技术可以简单的用对action应用URL重写来代替。
在一个页面设置一个cookie时,必须刷新或到下一个页面才可以用 $_COOKIE 得到变量的值.
原因是因为当页面第一次被浏览器访问载入时,页面中的 cookie 会被设置,将其发送存储到客户端指定的
存储位置,所以$_COOKIE没有接收到客户端发送过来的 cookie 变量的值,当刷新或到下一个页面时,客户
端会在页面程序在服务器端运行之前,发送与该地址相对应的 cookie到服务器端,所以 $_COOKIE 可以得
到的值!
说白了就是当每一个页面被访问时,如果客户端找到了与访问地址相对应的 cookie 时,会在程序在服务器
端运行之前发送这个 cookie 到服务器端. (个人对此的看法)
本人表达能力不强,如有不明,还请抱歉!
php中设置cookie数组的时候,不可以用像php中的那个添加数据的方法:
<?php
setcookie('my_cookie[]', 1);
setcookie('my_cookie[]', 2);
print_r($_COOKIE); // Array ( [my_cookie] => Array ( [0] => 1 ))
// 数组的值添加是添加成功了,不过索引没有变,后面的数据将前的数据覆盖了!
由此得到
my_cookie[],默认指向数据的第一元素的位置,即索引为
0 的位置. 注意与php中的不一样! 以后用cookie数据记住要指定数组元素索引哦!
$my_cookie[] = 1;
$my_cookie[] = 2;
print_r($my_cookie); //Array ( [0] => 1 [1] => 2)
?>
删除 cookie 变量的两个方法:
1.php
<?php
setcookie('user_name_1', 'zhaofei299', time()+3600); // 生存期为 1 个小时
setcookie('user_name_2', 'ZHAOFEI299', time()+3600); // 生存期为 1 个小时
?>
2.php
<?php
setcookie('user_name_1'); // 第一种
setcookie('user_name_2', "", time()-1); // 第二种
print_r($_COOKIE); // 刷新页面2下以上会输出 Array ( [user_name_1] => )
/*为什么超级全局变量 $_COOKIE 中的 user_name_1 没有被删除(变量为空并不代表不存在),而
user_name_2被删除了? 那是因为两个删除变量的方式不同!
第一种: 是设置了 cookie 的生存期, 只不过是将它的值默认设置为空,生存期为与浏览器一样,浏览器
关闭时,cookie才会删除!所以当重新打开一个浏览器,输出地址时,才会发现 cookie 变量全部被删除了!
将2.php 中两个 setcookie() 函数部分注释掉看看(重新输出了地址)!
第二种: 也是设置了 cookie 的生存期,是使 cookie 的生存期一定过期, cookie 也就被删除,所以刷
新页面,客户端向服务器端发送 cookie 时, $_COOKIE 并没有能够得到该cookie变量的值!
*/
?>
会话id默认储放在客户端Cookie中!
<?php
session_start();
print_r($_COOKIE);
?>
cookie的设置有两种方法
header('set-cookie:user=zhaofei299');
setcookie('user', 'zhaofei299');
会话变量不能被GET数据或POST数据重载!
使用session变量传递数组,对象时无需序列化!
使用session变量传递对象时,在调用session_start()之前,必须包含该对类对象的定义,反序列化
(serialize)也是如此!
删除单个会话变量可以使用unset($_SESSION['***']) 直接删除!
删除所有的会话变量不可以用unset($_SESSION),因为这样会将所有的会话信息删除,包含存储在COOKIE
中的PHPSESSID,也就是破坏了两个页面之间的会话联系,应该使用$_SESSION = array();
消除会话id,使页面之间失去联系!
session_destroy();
程序清单1.1
<?php
session_start();
header('content-type:text/html;charset=utf-8');
$_SESSION['a'] = 'a';
$_SESSION['b'] = 'b';
unset($_SESSION); //测试后,再注释下看看
$_SESSION['user'] = 'zhaofei299';
echo 'SESSION_ID: '.session_id().'<br />';
echo '<a href="3.php" target="_blank">测试下</a>';
?>
<?php
session_start();
echo $_SESSION['user'];
echo session_id(); //会话变量改变了
?>
会话id(session_id)的两种方式传递:
1.cookie
2.url
因为默认session是基于cookie的,而cookie又是跟随http协议发送的,所以与cookie一样,在
session_start()之前不能有任何输出!
现在主要说一说第二种,通过 url 传递会话id
php中已经定义SID这个常量来得到 会话的id
sesssin_id 的使用!
<?php
session_start();
echo defined('SID')?'true':'false'; // true
echo SID; //什么也没有?
?>
为什么SID的值会是null 呢?是它哪里有问题了?
原因是因为 session 默认是基于 cookie 的,而 SID 只有 session_id 通过 url
传递数据时才会被赋值!
在浏览器中将 cookie 禁用,你就会发现 SID 有了输出,而不是 null!
删除session
要三步实现.
<?php
session_destroy(); // 第一步: 删除服务器端session文件,这使用
setcookie(session_name(),'',time()-3600); // 第二步: 删除实际的session:
$_SESSION = array(); // 第三步: 删除$_SESSION全局变量数组
?>
大家都知道session变量是保存在服务器端的,也就是说session的变量会保存在服务器中一个目录中,我
们可以在php.ini中的session.save_path 那里可以找到session文件中保存的地址.
默认的session的生存期是浏览的关闭就结束,但要知道会话过期结束后,当打开页面session_start()会
判断会话id 是否存在,如果不存在就创建一个,否则将该会话id 的变量载入页面!因为过期session_id会
被创建一个新的,但它保存在服务器端的session文件并没有被删除(关闭浏览器,打开session文件保存
地看看),所以要用session_destory()函数清除会话id,并同时清除相应的会话文件,这样的话才能做到最
彻底的清除!
session_id 使用 url 传递session 变量数据时,因为session_start()开启会话时会判断会话id 是否存
在,如果不存在就创建一个,否则将该会话id 的变量载入页面!
而现在是使用url 来传递session_id,然而每一次 刷新/进入页面 都会生成一个会话id,所以页面之间就
不能得到在另一页面设置过的session_id 的变量,那么使用 session也就没什么意义了!
解决方法:在session_start()之前,手动设置页面的session_id,这样页面的就可以得到前一页中所设置的
session变量的,也就实现了会话的传递,如下代码可以说明!
//已禁用 cookie
1.php
<?php
session_start();
$_SESSION['user'] = 'zhaofei299';
echo '<a href="2.php?'.SID.'">下一页</a>';
?>
1.php的第4行代码也可以写成:echo '<a href="2.php">下一页</a>';
可以设置php.ini 中的 session.use_trans_sid 为1,这样当使用 url 传递会话 id 时,
浏览器会自动将 session_id 追加到 url 的后面!
就好像 在浏览器中 输入: www.baidu.com 一样,浏览器会自动将其更换成 http://www.baidu.com/
2.php
<?php
session_id($_GET['PHPSESSID']); // 手动设置session_id,这种就可以使用前一个页面的
session_id 的变量了,也就实现了会话!
session_start();
print_r($_SESSION);
?>
常用session函数:
bool session_start(void); 初始化session
bool session_destroy(void): 删除服务器端session关联文件。
string session_id() 当前session的id
string session_name() 当前存取的session名称,也就是客户端保存session ID的cookie名称.默认
PHPSESSID。
array session_get_cookie_params() 与这个session相关联的session的细节.
string session_cache_limiter() 控制使用session的页面的客户端缓存
ini session_cache_expire() 控制客户端缓存时间
bool session_destroy() 删除服务器端保存session信息的文件
void session_set_cookie_params ( int lifetime [, string path [, string domain [, bool
secure [, bool httponly]]]] )设置与这个session相关联的session的细节
bool session_set_save_handler ( callback open, callback close, callback read, callback
write, callback destroy, callback gc )定义处理session的函数,(不是使用默认的方式)
bool session_regenerate_id([bool delete_old_session]) 分配新的session id
同宿舍的哥们打电话过来,邀请一起参加大学毕业十年的同学聚会,才猛然意识到毕业十年了,心里莫名地一动,似有所感,似有所悟,人生能有几个十年?十年了,我们做了些什么?我们在做什么?我们还要做什么?我们成功了吗?什么是成功?…….太多太多的问号,刹那间涌现心头,无法阻挡,无处躲藏,确确实实,那么多年了,无论在学校里、家里、公司里,还是在朋友圈里,我们总无法逃避这些问题,周围的人总喜欢将我们比来比去,于是我们感觉好累好压抑,我们好象都不是在为自已活着, 我们一而再再而三地彷徨、奋斗、思考……
毕业十年,我都是做软件技术的,从软件开发到软件管理到软件销售到软件企业管理,我的十年都与软件有关,甚至我的老婆也是搞软件测试的,我的整个世界都充满了软件,我的创业也是从软件开始,第一次失败了,第二次重来,还是软件,就是现在的FasterSoft,它在稳定发展着,我不知道它能走到什么地方,但我知道自已会一直坚持下去,因为除了软件,我一无所有,除了技术,我一无所长……
毕业十年,我是一个从农村里爬出来的幸运儿,现在我能用软件技术在这座城市里立足,我已经非常知足了,我从不苛求人们眼中的成功,相比我那些还在农村里垦田种地放牛养猪的小学同学们,我觉得自已在某些方面已经成功了,因此在我抚摸着键盘,敲出一行一行代码的时候,我的心里充满了喜悦与幸福,我深爱着这些代码,深爱着这些代码编译成的软件,并相信一句话:“落后并不可怕,可怕的是不再追赶,失败并不可怕,可怕的是不再奋起,别人睢不起自已并不可怕,可怕的是自已瞧不起自已”……
毕业十年,我需要总结一下,为了能留下点什么,也为了让未来的路更加好走。
一.做人第一,做事第二
这是阿蒙的一贯原则,实际上很多人也都知道这么一个原则,但最重要的是我们能否一直坚持下去。在这个物欲横流的社会,能真正做到这一点的人似乎越来越少了,有的人为了达到目标而不择手段,有的人压根不知如何做人,一切以自我为中心,自私自大自狂,我们有时不得不面对这种人,我们能做的是保护好自已,同时避免污染自已。另一方面,我也将这个原则应用到FasterSoft的管理当中,一个员工即使是技术再厉害,能力再强,业绩再突出,但如果在做人方面出了问题,比如勾心斗角,调拔离间,没有责任感,同事关系紧张,以自我为中心等,那么我也会痛下决心,将其清除。
二.孜孜不倦,坚持不懈
这一点讲的是一种精神,这种精神在我的很多BLOG文章里都反复提起,它对我而言非常地重要,我自认为自已从来都不是那种聪明伶俐的家伙,我所就读的大学院校也毫不起眼,也没有什么人看好过我的未来,我自已其实也不知道我未来能做什么以及做到什么程度,但我有两点是可以看得到并做得到的,即勤奋刻苦和持之以恒,我相信“勤能补拙”、“业精于勤”,“坚持就是胜利”,我将这些当作自已的座右铭,在艰难困苦、失败挫折时,我总坚信能冲破一切,我觉得只要拥有这两种精神,即使我无法达到人们认为的成功,我也无怨无悔,实际上从我本人的性格来说,我也极少奢望成功,也较少去想象成功的模样,我一直以来的追求就是寻找一份自已喜欢的工作,然后用“勤奋+坚持”将它做好,其他的就顺其自然。
三.目标明确,行动迅速
这些字眼有点象政府官员的腔调,如果你有兴趣,你可以去阅读一些政府官员的讲话稿,我想类似的字眼会很多,呵呵,并不是说这些字眼不好,而是它们太空洞,太虚假,你可以不停地说,但说后你做不做得到,那又是另一回事。在我们的一生中,我们在不同的阶段不同的场合会制定很多很多的目标,小学时的目标是考上重点初中,初中时的目标是考上重点高中,高中时的目标是考上重点大学,大学时的目标是毕业后在重点企业找个重点工作,工作后的目标就变得越来越多,比如想找个女朋友恋一下爱,想学好某一门技术,想升官发财,想创业,想结婚,想有个宝宝,想孝顺父母,想报效祖国……无可置疑,这是常人的目标与道路,我们中的大部分人可能都是这么想这么做的,天才偏才庸才毕竟是少数,更多的人都是平平淡淡的,更多的生活都是平平稳稳的,阿蒙也一样,毕业十年,再回想过往的这些目标,已经实现了70%左右,就非常地知足与快乐,我想最重要的一点就是行动迅速,目标的设定是简单与快速的,但关键是你的行动是否迅速与持续,我们不能做“语言的巨人行动的矮子”,我们需要围绕着我们的目标踏踏实实地奋斗到底,尽管达到目标的道路是多么地曲折与艰辛,尽管我们努力了但不一定成功,但我们永不放弃坚持到底。
四.虚心学习,厚道做人
每一个人都有自已的优点缺点,因此每一个人都可以成为别人学习的对象,谦虚是一种美德,无论面对什么样的人,我们都能保持一种虚心学习的态度,想方设法从对方那里学到好的东西,我一直以来都非常佩服我的母亲,她虽然目不识丁,但她在农村里可以将一头又瘦又弱的小猪养成一头又胖又壮的大猪,这是一件非常了不起的事情,在这期间她所付出的心血与所倾注的爱是漫长与巨大的,每到开学时,那头可爱的猪就成了我学费的重要来源,看着猪被卖掉或宰杀,母亲都很伤感地流泪,我也能感受到母亲对我的爱是远远超过对那头猪的爱,因此我会更加地努力学习……同时,从小到大,母亲的纯朴、善良、坚强、勤劳也深深地影响着我,我想一个人最大的财富并不是你现在拥有什么样的资产,而是你拥有什么样的性格与品质。
五.学会感恩,善待苦痛
感恩是一种生活态度,是一份铭心之谢。我们都应该学会“感恩”。当我们呱呱坠地来到这个世界,什么都还没来得及做的时候,他就已经开始享受前人赋予的一切成果了。生活中,我们每天享受阳光、蓝天、白云以及清洁的环境清新的空气,我们要感谢自然界,感谢那些辛勤工作的清洁工作者;工作中,我们每天坐在明窗净几的办公室里,敲打着键盘,编着代码,我们要感谢公司,感谢同事……所有这些,我们都应感谢。学会感恩,就会懂得尊重他人,发现自我价值。人生漫长,我们难免失败,难免挫折,有时甚至天灾人祸,面对苦痛,面对苦难,我们需要坚强不屈,需要克服困难,需要勇往直前,我们要从苦痛中奋起,从苦难中重生,我们会变得更加坚强更加不可战胜!
毕业十年,回忆过去的点点滴滴,无论喜怒哀乐酸甜苦辣,都是那么地令人感动,因为那是自已亲自走过的道路,辉煌也好,平淡也好,顺利也好,曲折也好,都是真实的、生动的、坚定的……
毕业十年,我们学会珍惜,珍惜亲情,珍惜友情,珍惜工作,珍惜现在所拥有的一切,我们学会了感恩,感恩社会,感恩父母,感恩老师,感恩公司,感恩所有与自已相关的人与事……
毕业十年,正值祖国多事之秋,一月的雪灾,三月的暴乱,四月的列车相撞,五月的地震,但我们看到了中国人的团结、坚强与友爱,看到了社会各界的互助与互爱,是的,面对灾难,我们的眼里充满了泪水,但透过泪光,我们看到了希望,中国人永远都不会被打倒,面对各种各样的艰难险阻,我们总能坚持不懈勇往直前。
毕业十年,我都是做软件技术的,从软件开发到软件管理到软件销售到软件企业管理,我的十年都与软件有关,甚至我的老婆也是搞软件测试的,我的整个世界都充满了软件,我的创业也是从软件开始,第一次失败了,第二次重来,还是软件,就是现在的FasterSoft,它在稳定发展着,我不知道它能走到什么地方,但我知道自已会一直坚持下去,因为除了软件,我一无所有,除了技术,我一无所长……
毕业十年,我是一个从农村里爬出来的幸运儿,现在我能用软件技术在这座城市里立足,我已经非常知足了,我从不苛求人们眼中的成功,相比我那些还在农村里垦田种地放牛养猪的小学同学们,我觉得自已在某些方面已经成功了,因此在我抚摸着键盘,敲出一行一行代码的时候,我的心里充满了喜悦与幸福,我深爱着这些代码,深爱着这些代码编译成的软件,并相信一句话:“落后并不可怕,可怕的是不再追赶,失败并不可怕,可怕的是不再奋起,别人睢不起自已并不可怕,可怕的是自已瞧不起自已”……
毕业十年,我需要总结一下,为了能留下点什么,也为了让未来的路更加好走。
一.做人第一,做事第二
这是阿蒙的一贯原则,实际上很多人也都知道这么一个原则,但最重要的是我们能否一直坚持下去。在这个物欲横流的社会,能真正做到这一点的人似乎越来越少了,有的人为了达到目标而不择手段,有的人压根不知如何做人,一切以自我为中心,自私自大自狂,我们有时不得不面对这种人,我们能做的是保护好自已,同时避免污染自已。另一方面,我也将这个原则应用到FasterSoft的管理当中,一个员工即使是技术再厉害,能力再强,业绩再突出,但如果在做人方面出了问题,比如勾心斗角,调拔离间,没有责任感,同事关系紧张,以自我为中心等,那么我也会痛下决心,将其清除。
二.孜孜不倦,坚持不懈
这一点讲的是一种精神,这种精神在我的很多BLOG文章里都反复提起,它对我而言非常地重要,我自认为自已从来都不是那种聪明伶俐的家伙,我所就读的大学院校也毫不起眼,也没有什么人看好过我的未来,我自已其实也不知道我未来能做什么以及做到什么程度,但我有两点是可以看得到并做得到的,即勤奋刻苦和持之以恒,我相信“勤能补拙”、“业精于勤”,“坚持就是胜利”,我将这些当作自已的座右铭,在艰难困苦、失败挫折时,我总坚信能冲破一切,我觉得只要拥有这两种精神,即使我无法达到人们认为的成功,我也无怨无悔,实际上从我本人的性格来说,我也极少奢望成功,也较少去想象成功的模样,我一直以来的追求就是寻找一份自已喜欢的工作,然后用“勤奋+坚持”将它做好,其他的就顺其自然。
三.目标明确,行动迅速
这些字眼有点象政府官员的腔调,如果你有兴趣,你可以去阅读一些政府官员的讲话稿,我想类似的字眼会很多,呵呵,并不是说这些字眼不好,而是它们太空洞,太虚假,你可以不停地说,但说后你做不做得到,那又是另一回事。在我们的一生中,我们在不同的阶段不同的场合会制定很多很多的目标,小学时的目标是考上重点初中,初中时的目标是考上重点高中,高中时的目标是考上重点大学,大学时的目标是毕业后在重点企业找个重点工作,工作后的目标就变得越来越多,比如想找个女朋友恋一下爱,想学好某一门技术,想升官发财,想创业,想结婚,想有个宝宝,想孝顺父母,想报效祖国……无可置疑,这是常人的目标与道路,我们中的大部分人可能都是这么想这么做的,天才偏才庸才毕竟是少数,更多的人都是平平淡淡的,更多的生活都是平平稳稳的,阿蒙也一样,毕业十年,再回想过往的这些目标,已经实现了70%左右,就非常地知足与快乐,我想最重要的一点就是行动迅速,目标的设定是简单与快速的,但关键是你的行动是否迅速与持续,我们不能做“语言的巨人行动的矮子”,我们需要围绕着我们的目标踏踏实实地奋斗到底,尽管达到目标的道路是多么地曲折与艰辛,尽管我们努力了但不一定成功,但我们永不放弃坚持到底。
四.虚心学习,厚道做人
每一个人都有自已的优点缺点,因此每一个人都可以成为别人学习的对象,谦虚是一种美德,无论面对什么样的人,我们都能保持一种虚心学习的态度,想方设法从对方那里学到好的东西,我一直以来都非常佩服我的母亲,她虽然目不识丁,但她在农村里可以将一头又瘦又弱的小猪养成一头又胖又壮的大猪,这是一件非常了不起的事情,在这期间她所付出的心血与所倾注的爱是漫长与巨大的,每到开学时,那头可爱的猪就成了我学费的重要来源,看着猪被卖掉或宰杀,母亲都很伤感地流泪,我也能感受到母亲对我的爱是远远超过对那头猪的爱,因此我会更加地努力学习……同时,从小到大,母亲的纯朴、善良、坚强、勤劳也深深地影响着我,我想一个人最大的财富并不是你现在拥有什么样的资产,而是你拥有什么样的性格与品质。
五.学会感恩,善待苦痛
感恩是一种生活态度,是一份铭心之谢。我们都应该学会“感恩”。当我们呱呱坠地来到这个世界,什么都还没来得及做的时候,他就已经开始享受前人赋予的一切成果了。生活中,我们每天享受阳光、蓝天、白云以及清洁的环境清新的空气,我们要感谢自然界,感谢那些辛勤工作的清洁工作者;工作中,我们每天坐在明窗净几的办公室里,敲打着键盘,编着代码,我们要感谢公司,感谢同事……所有这些,我们都应感谢。学会感恩,就会懂得尊重他人,发现自我价值。人生漫长,我们难免失败,难免挫折,有时甚至天灾人祸,面对苦痛,面对苦难,我们需要坚强不屈,需要克服困难,需要勇往直前,我们要从苦痛中奋起,从苦难中重生,我们会变得更加坚强更加不可战胜!
毕业十年,回忆过去的点点滴滴,无论喜怒哀乐酸甜苦辣,都是那么地令人感动,因为那是自已亲自走过的道路,辉煌也好,平淡也好,顺利也好,曲折也好,都是真实的、生动的、坚定的……
毕业十年,我们学会珍惜,珍惜亲情,珍惜友情,珍惜工作,珍惜现在所拥有的一切,我们学会了感恩,感恩社会,感恩父母,感恩老师,感恩公司,感恩所有与自已相关的人与事……
毕业十年,正值祖国多事之秋,一月的雪灾,三月的暴乱,四月的列车相撞,五月的地震,但我们看到了中国人的团结、坚强与友爱,看到了社会各界的互助与互爱,是的,面对灾难,我们的眼里充满了泪水,但透过泪光,我们看到了希望,中国人永远都不会被打倒,面对各种各样的艰难险阻,我们总能坚持不懈勇往直前。
姜宇 说:
http://www.ietf.org/rfc/rfc2109.txt
姜宇 说:
http://www.faqs.org/rfcs/rfc2965.html
姜宇 说:
http://blog.csdn.net/xymyeah/archive/2007/09/04/1772206.aspx
姜宇 说:
解释了2109和2965的区别
http://support.microsoft.com/kb/306070
IETF 是 **Internet Engineering Task Force** 的缩写,即互联网工程任务组。IETF 是一个开放的国际标准组织,主要负责制定和推广互联网的技术标准,特别是在协议、架构和其他网络相关技术方面。
还有一个叫做国际电工委员会I。那么iso和IEC,其实有一个共同合作的小组叫做iso IECSC27,那么这个小组发布我们的一系列信息安全标准。ISO组织的信息安全标准按ISO组织的标准都是以ISO为开头的。后面跟上它的标准号就是一个数字,比如说ISO9000。Iso9000这就是一个标准,这也是ido组织的一个特点,接下来。还有一个标准化组织,叫做internet工程任务组I ETF。那么他们所发布的标准叫做RFC文档?它们的标准号,一般是前面是RFC,后面跟上一个数字,代表你的这标准是。
在 IETF 中,Force 的确不是指军队,而是指一种协作的**“力量”或“组织”**。在英文中,"force" 可以表示一种具有行动力的团体或组织,例如“task force”通常指为了完成特定任务而组建的工作组或特别小组。
因此,Internet Engineering Task Force 可以理解为专注于互联网技术工程的工作小组或任务组织。
http://www.ietf.org/rfc/rfc2109.txt
姜宇 说:
http://www.faqs.org/rfcs/rfc2965.html
姜宇 说:
http://blog.csdn.net/xymyeah/archive/2007/09/04/1772206.aspx
姜宇 说:
解释了2109和2965的区别
http://support.microsoft.com/kb/306070
IETF 是 **Internet Engineering Task Force** 的缩写,即互联网工程任务组。IETF 是一个开放的国际标准组织,主要负责制定和推广互联网的技术标准,特别是在协议、架构和其他网络相关技术方面。
还有一个叫做国际电工委员会I。那么iso和IEC,其实有一个共同合作的小组叫做iso IECSC27,那么这个小组发布我们的一系列信息安全标准。ISO组织的信息安全标准按ISO组织的标准都是以ISO为开头的。后面跟上它的标准号就是一个数字,比如说ISO9000。Iso9000这就是一个标准,这也是ido组织的一个特点,接下来。还有一个标准化组织,叫做internet工程任务组I ETF。那么他们所发布的标准叫做RFC文档?它们的标准号,一般是前面是RFC,后面跟上一个数字,代表你的这标准是。
在 IETF 中,Force 的确不是指军队,而是指一种协作的**“力量”或“组织”**。在英文中,"force" 可以表示一种具有行动力的团体或组织,例如“task force”通常指为了完成特定任务而组建的工作组或特别小组。
因此,Internet Engineering Task Force 可以理解为专注于互联网技术工程的工作小组或任务组织。
d:
cd D:\Program Files\tomcat-5.0.24\bin
java -jar bootstrap.jar
把:Java\jdk1.6.0_02\lib\拷贝到: tomcat-5.0.24\common\lib\tools.jar
cd D:\Program Files\tomcat-5.0.24\bin
java -jar bootstrap.jar
把:Java\jdk1.6.0_02\lib\拷贝到: tomcat-5.0.24\common\lib\tools.jar
小七(249904837) 14:52:57
aaaa.php 中的一个链接<a href=ddd.php>链接</a>,进入到ddd.php页面,怎么才能在ddd.php中获取上级页面的路径呢,就是获取aaaa.php这个路径呢?
$lailu=$_SERVER['HTTP_REFERER'];//来路的完整网址;
aaaa.php 中的一个链接<a href=ddd.php>链接</a>,进入到ddd.php页面,怎么才能在ddd.php中获取上级页面的路径呢,就是获取aaaa.php这个路径呢?
$lailu=$_SERVER['HTTP_REFERER'];//来路的完整网址;
http://blog.chinaunix.net/u1/33803/showart_357352.html
English:http://www.w3.org/Protocols/rfc2616/rfc2616.html
小无 22:13:27
看完这个你英语比六级还好了,学什么大学英语啊~~应该大一就看
English:http://www.w3.org/Protocols/rfc2616/rfc2616.html
小无 22:13:27
看完这个你英语比六级还好了,学什么大学英语啊~~应该大一就看
操作系统中进程概念的理解
提起进程这个概念,让很多经常使用计算机的人感到陌生,其实我们经常和它打交道,只要在计算机上运行一个程序,相应的一个进程就诞生了,而且它伴随着整个操作过程,直到程序终止。进程在操作系统中是一个非常抽象、非常重要、非常难以理解的概念。对进程概念的深入透彻的理解,有助于理解操作系统中的各种机制原理。
为什么要引入进程概念
提起程序这个概念,大家再也熟悉不过了,程序与进程概念是不可分的。程序是为了完成某项任务编排的语句序列,它告诉计算机如何执行,因此程序是需要运行的。程序运行过程中需要占有计算机的各种资源才能运行下去。如果任一时刻,系统中只有一道程序,即单道程序系统,程序则在整个运行过程中独占计算机全部资源,整个程序运行的过程就非常简单了,管理起来也非常容易。就象整个一套房子住了一个人,他想看电视就看电视,想去卫生间就去卫生间,没人和他抢占资源。但为了提高资源利用率和系统处理能力,现代计算机系统都是多道程序系统,即多道程序并发执行。程序的并发执行带来了一些新的问题,如资源的共享与竞争,它会改变程序的执行速度。就象多个人同时住一套房子,当你想去卫生间的时候,如果此时卫生间里有人,你就得等待,影响了你的生活节奏。如果程序执行速度不当,就会导致程序的执行结果失去封闭性和可再现性,这是我们不希望看到的。因此应该采取措施来制约、控制各并发程序段的执行速度。由于程序是静态的,我们看到的程序是存储在存储介质上的,它无法反映出程序执行过程中的动态特性,而且程序在执行过程中是不断申请资源,程序作为共享资源的基本单位是不合适的,所以需要引入一个概念,它能描述程序的执行过程而且可以作为共享资源的基本单位,这个概念就是进程。
进程的生命周期
进程和人一样是有生命的,从诞生到死亡要经历若干个阶段。一般说来进程有三种状态:就绪、执行、等待。由多种原因可以导致创建一个进程,例如一个程序从外存调入内存开始执行,操作系统就要为其创建进程,当然还可以有其它原因,如一个应用进程为完成一个特殊的任务,可以自己创建一个子进程。进程被创建后就是在内存中,处于就绪状态,所谓就绪状态就是具备除了CPU之外的所有资源,万事具备,只欠东风,一旦占有了CPU,就变成了执行状态,执行中如果需要等待外围设备输入数据,则进程就沦落为等待状态,操作系统又会从就绪状态队列中调度一个进程占有CPU。等到数据到来后,等待状态的进程又被唤醒成为就绪状态。这些状态的转换是通过进程控制原语实现的。程序的运行是通过进程体现的,操作系统对进程进行管理和控制,那么操作系统怎么了解到进程的状态呢,怎么把资源分配给进程呢,而且进程做状态转换时CPU现场保存在那呢?这要说到PCB(进程控制快)。PCB是进程的唯一标志,在其中记录了进程的全部信息,它是一种记录型的数据结构,相当于进程的档案。操作系统就通过PCB感知进程的存在,通过PCB了解进程和控制进程的运行。PCB也是放在内存中的,如果PCB太大,有些系统把PCB中一些不重要的信息放在外存中。
进程执行速度的制约
并发进程由于共享系统内部资源,因此导致进程执行速度上的制约,这种制约分为:间接制约与直接制约。间接制约引起进程之间的互斥执行,直接制约引起进程间的同步执行。例如一个家里如果只有一个卫生间,卫生间这个公有资源使得每个人只能互斥使用它,这就是间接制约。而直接制约是指并发进程各自执行的结果互为对方的执行条件,例如司机与售票员的关系,当司机到站停车后,售票员才能开门,而只有售票员关门后,司机才能开车,他们之间是同步的。进程的互斥与同步可以很好的通过信号量和PV原语来实现。通过读一些同步与互斥的例子,你会体会到PV原语的精妙,也会感到一种乐趣。并发进程的资源竞争不当还会导致死锁现象。
http://www.usbuse.com/html/ittxmcsy/140743404.html
提起进程这个概念,让很多经常使用计算机的人感到陌生,其实我们经常和它打交道,只要在计算机上运行一个程序,相应的一个进程就诞生了,而且它伴随着整个操作过程,直到程序终止。进程在操作系统中是一个非常抽象、非常重要、非常难以理解的概念。对进程概念的深入透彻的理解,有助于理解操作系统中的各种机制原理。
为什么要引入进程概念
提起程序这个概念,大家再也熟悉不过了,程序与进程概念是不可分的。程序是为了完成某项任务编排的语句序列,它告诉计算机如何执行,因此程序是需要运行的。程序运行过程中需要占有计算机的各种资源才能运行下去。如果任一时刻,系统中只有一道程序,即单道程序系统,程序则在整个运行过程中独占计算机全部资源,整个程序运行的过程就非常简单了,管理起来也非常容易。就象整个一套房子住了一个人,他想看电视就看电视,想去卫生间就去卫生间,没人和他抢占资源。但为了提高资源利用率和系统处理能力,现代计算机系统都是多道程序系统,即多道程序并发执行。程序的并发执行带来了一些新的问题,如资源的共享与竞争,它会改变程序的执行速度。就象多个人同时住一套房子,当你想去卫生间的时候,如果此时卫生间里有人,你就得等待,影响了你的生活节奏。如果程序执行速度不当,就会导致程序的执行结果失去封闭性和可再现性,这是我们不希望看到的。因此应该采取措施来制约、控制各并发程序段的执行速度。由于程序是静态的,我们看到的程序是存储在存储介质上的,它无法反映出程序执行过程中的动态特性,而且程序在执行过程中是不断申请资源,程序作为共享资源的基本单位是不合适的,所以需要引入一个概念,它能描述程序的执行过程而且可以作为共享资源的基本单位,这个概念就是进程。
进程的生命周期
进程和人一样是有生命的,从诞生到死亡要经历若干个阶段。一般说来进程有三种状态:就绪、执行、等待。由多种原因可以导致创建一个进程,例如一个程序从外存调入内存开始执行,操作系统就要为其创建进程,当然还可以有其它原因,如一个应用进程为完成一个特殊的任务,可以自己创建一个子进程。进程被创建后就是在内存中,处于就绪状态,所谓就绪状态就是具备除了CPU之外的所有资源,万事具备,只欠东风,一旦占有了CPU,就变成了执行状态,执行中如果需要等待外围设备输入数据,则进程就沦落为等待状态,操作系统又会从就绪状态队列中调度一个进程占有CPU。等到数据到来后,等待状态的进程又被唤醒成为就绪状态。这些状态的转换是通过进程控制原语实现的。程序的运行是通过进程体现的,操作系统对进程进行管理和控制,那么操作系统怎么了解到进程的状态呢,怎么把资源分配给进程呢,而且进程做状态转换时CPU现场保存在那呢?这要说到PCB(进程控制快)。PCB是进程的唯一标志,在其中记录了进程的全部信息,它是一种记录型的数据结构,相当于进程的档案。操作系统就通过PCB感知进程的存在,通过PCB了解进程和控制进程的运行。PCB也是放在内存中的,如果PCB太大,有些系统把PCB中一些不重要的信息放在外存中。
进程执行速度的制约
并发进程由于共享系统内部资源,因此导致进程执行速度上的制约,这种制约分为:间接制约与直接制约。间接制约引起进程之间的互斥执行,直接制约引起进程间的同步执行。例如一个家里如果只有一个卫生间,卫生间这个公有资源使得每个人只能互斥使用它,这就是间接制约。而直接制约是指并发进程各自执行的结果互为对方的执行条件,例如司机与售票员的关系,当司机到站停车后,售票员才能开门,而只有售票员关门后,司机才能开车,他们之间是同步的。进程的互斥与同步可以很好的通过信号量和PV原语来实现。通过读一些同步与互斥的例子,你会体会到PV原语的精妙,也会感到一种乐趣。并发进程的资源竞争不当还会导致死锁现象。
http://www.usbuse.com/html/ittxmcsy/140743404.html
前言:
PHP中对各类数据库的操作有着支持,对文件的操作也同样有着很丰富的操作方法,很多朋友现在的操作还是基于文件操作
可是有的时候在操作文件的时候还存在不少的困惑和疑点,以下是我在日常编写过程中碰到的以及坛上朋友所碰到的关于文件操
作的一些问题收藏吧。
问:如何新建一个文件?
答:1、使用fopen("要建立的文件名","参数"),参数可选 w,w+,a,a+
2、使用exec("echo '' > 要建立的文件名");这样是使用系统方式建立这个文件,你还可以使用touch这个linux命令来建立
问:为什么我无法建立文件?
答:1、如果你使用了fopen建立文件,是否正确的使用了参数
2、系统权限问题,请询问你的WEBMASTER你的FTP目录是否有写的权限
3、FTP权限问题,你要确认你的PHP文件所要写文件所在目录要有写的权限,也就是你的FTP软件登陆后other组要有写这个权限,
如果没有请修改权限后尝试
问:如何将文件读入数组?
答:使用file
问:如何将文件全部读出?
答:1、使用fread($fp);
2、如果你的PHP版本>=4.3.0的话可以使用file_get_contents();
问:如何判断文件是否存在?
答:使用file_exists();为什么不使用fopen()来判断呢?原因是有时候是因为权限问题导致fopen返回的数据引导我们错误的判断
问:为什么当我读取一个WEB页面的时候出错?
答:1、可能是你的传递参数错,当读取WEB页面的时候你只可以使用r方式读取页面
2、确保你要读取的WEB页面可以访问
问:我如何才能获得文件的相关属性?
答:PHP提供了一组获得文件属性的方法,例如 filemtime(),fileowner(),filegroup(),filectime(),fileatime()...详细的使用
请参阅手册。
问:PHP打开文件后是否可以象C一样进行文件“游标”的定位呢?
答:可以的,使用fseek();
问:我想在访问文件的时候不允许其他人也访问此文件,怎么办?
答:1、你可以采用其他方面程序限制用户接入文件操作的页面
2、使用flock();详细的参数以及使用方法请参阅手册
问:如何删除文件内第一行,或指定一行数据?
答:PHP并没有提供这样的操作方法,不过我们可以通过组合使用,以下代码演示我们将删除文件"test.dat"中的第三行数据(test.datw
文件中数据不止三行)
<?php
$filename="test.dat";//定义操作文件
$delline=3; //要删除的行数
if(!file_exsits($filename)){
die("指定文件未发现!操作中断!");
}
$farray=file($filename);//读取文件数据到数组中
for($tmpa=0;$Tmpa<count($farray);$Tmpa++){
if(strcmp($Tmpa+1,$delline)==0){
//判断删除的行
continue;
}
//重新整理后的数据
$newfp.=$farray[$Tmpa]."\r\n";
}
$fp=@fopen($filename,"a") or die("写方式打开文件 $filename 失败");//我们以写的方式打开文件
@fputs($fp,$newfp) or die("文件写入失败");
@fclose($fp);
?>
以上代码演示的是删除一行文件,不过你如果仔细的看的话,其实也给你提供了其他的文件操作的相关提醒~
问:当我试图打开一个不存在的文件的时候,我如何不让错误显示出来以避免我的路径泄露!!
答:在你要打开文件的方法前增加@符号用来屏蔽错误,@是PHP提供的错误信息屏蔽的专用符号
或您可以在这个要操作的步骤前增加(通常是在页首)error_reporting(0);用来屏蔽页面内所有错误信息的显示
一个不推荐的方法就是去修改php.ini(ISP除外)
问:我使用的是虚拟主机,我如何防止其他用户窃取我的数据?
答:建议ISP修改php.ini中的open_basedir进行限制,
不推荐的ISP设置是将fopen,file等文件操作加入disable_function中。
问:为什么我用PHP建立文件后我FTP登陆要删除这些文件无法删除??
答:主要是因为PHP建立的文件归属WEB用户组,也就是建立的文件,并非是你FTP用户的!!!
这个问题的解决就是,使用PHP程序的chmod,unlink等方式进行处理,建议用户在使用PHP建立文件的时候
记得chmod文件权限,建议为777
问:如何使用文本文件作为数据仓库?有的留言本,论坛之类的都是使用这个的啊!
答:其实这个主要还是使用了file,结合explode进行数据读取与分割的典型范例而已。
问:如何更改文件名?
答:rename();
问:如何删除文件?
答:unlink(); exec("del(rm -vf) filename");注:rm -vf为linux下使用
问:如何清空文件?
答:使用fopen(filename,"w");或exec("echo '' > filename");
问:如何编辑文件内容?
答:我记得我以前回答过一个删除文件内容的,其实编辑内容在删除内容的基础上,进行变量替换就可以了。
希望你可以向上找找,将我上面的continue修改为替换变量数据就可以了:)
----------------------------------------------------
以上是我个人对文件操作的相关总结
说明:本篇文章我觉得对初学PHP文件操作方面应该有点帮助,作者:杨宗威 首发地:CSDN 作者转发地:DEV-CLUB
看这里没就再发一次(毕竟写出来就希望能对大家有点帮助)
PHP中对各类数据库的操作有着支持,对文件的操作也同样有着很丰富的操作方法,很多朋友现在的操作还是基于文件操作
可是有的时候在操作文件的时候还存在不少的困惑和疑点,以下是我在日常编写过程中碰到的以及坛上朋友所碰到的关于文件操
作的一些问题收藏吧。
问:如何新建一个文件?
答:1、使用fopen("要建立的文件名","参数"),参数可选 w,w+,a,a+
2、使用exec("echo '' > 要建立的文件名");这样是使用系统方式建立这个文件,你还可以使用touch这个linux命令来建立
问:为什么我无法建立文件?
答:1、如果你使用了fopen建立文件,是否正确的使用了参数
2、系统权限问题,请询问你的WEBMASTER你的FTP目录是否有写的权限
3、FTP权限问题,你要确认你的PHP文件所要写文件所在目录要有写的权限,也就是你的FTP软件登陆后other组要有写这个权限,
如果没有请修改权限后尝试
问:如何将文件读入数组?
答:使用file
问:如何将文件全部读出?
答:1、使用fread($fp);
2、如果你的PHP版本>=4.3.0的话可以使用file_get_contents();
问:如何判断文件是否存在?
答:使用file_exists();为什么不使用fopen()来判断呢?原因是有时候是因为权限问题导致fopen返回的数据引导我们错误的判断
问:为什么当我读取一个WEB页面的时候出错?
答:1、可能是你的传递参数错,当读取WEB页面的时候你只可以使用r方式读取页面
2、确保你要读取的WEB页面可以访问
问:我如何才能获得文件的相关属性?
答:PHP提供了一组获得文件属性的方法,例如 filemtime(),fileowner(),filegroup(),filectime(),fileatime()...详细的使用
请参阅手册。
问:PHP打开文件后是否可以象C一样进行文件“游标”的定位呢?
答:可以的,使用fseek();
问:我想在访问文件的时候不允许其他人也访问此文件,怎么办?
答:1、你可以采用其他方面程序限制用户接入文件操作的页面
2、使用flock();详细的参数以及使用方法请参阅手册
问:如何删除文件内第一行,或指定一行数据?
答:PHP并没有提供这样的操作方法,不过我们可以通过组合使用,以下代码演示我们将删除文件"test.dat"中的第三行数据(test.datw
文件中数据不止三行)
<?php
$filename="test.dat";//定义操作文件
$delline=3; //要删除的行数
if(!file_exsits($filename)){
die("指定文件未发现!操作中断!");
}
$farray=file($filename);//读取文件数据到数组中
for($tmpa=0;$Tmpa<count($farray);$Tmpa++){
if(strcmp($Tmpa+1,$delline)==0){
//判断删除的行
continue;
}
//重新整理后的数据
$newfp.=$farray[$Tmpa]."\r\n";
}
$fp=@fopen($filename,"a") or die("写方式打开文件 $filename 失败");//我们以写的方式打开文件
@fputs($fp,$newfp) or die("文件写入失败");
@fclose($fp);
?>
以上代码演示的是删除一行文件,不过你如果仔细的看的话,其实也给你提供了其他的文件操作的相关提醒~
问:当我试图打开一个不存在的文件的时候,我如何不让错误显示出来以避免我的路径泄露!!
答:在你要打开文件的方法前增加@符号用来屏蔽错误,@是PHP提供的错误信息屏蔽的专用符号
或您可以在这个要操作的步骤前增加(通常是在页首)error_reporting(0);用来屏蔽页面内所有错误信息的显示
一个不推荐的方法就是去修改php.ini(ISP除外)
问:我使用的是虚拟主机,我如何防止其他用户窃取我的数据?
答:建议ISP修改php.ini中的open_basedir进行限制,
不推荐的ISP设置是将fopen,file等文件操作加入disable_function中。
问:为什么我用PHP建立文件后我FTP登陆要删除这些文件无法删除??
答:主要是因为PHP建立的文件归属WEB用户组,也就是建立的文件,并非是你FTP用户的!!!
这个问题的解决就是,使用PHP程序的chmod,unlink等方式进行处理,建议用户在使用PHP建立文件的时候
记得chmod文件权限,建议为777
问:如何使用文本文件作为数据仓库?有的留言本,论坛之类的都是使用这个的啊!
答:其实这个主要还是使用了file,结合explode进行数据读取与分割的典型范例而已。
问:如何更改文件名?
答:rename();
问:如何删除文件?
答:unlink(); exec("del(rm -vf) filename");注:rm -vf为linux下使用
问:如何清空文件?
答:使用fopen(filename,"w");或exec("echo '' > filename");
问:如何编辑文件内容?
答:我记得我以前回答过一个删除文件内容的,其实编辑内容在删除内容的基础上,进行变量替换就可以了。
希望你可以向上找找,将我上面的continue修改为替换变量数据就可以了:)
----------------------------------------------------
以上是我个人对文件操作的相关总结
说明:本篇文章我觉得对初学PHP文件操作方面应该有点帮助,作者:杨宗威 首发地:CSDN 作者转发地:DEV-CLUB
看这里没就再发一次(毕竟写出来就希望能对大家有点帮助)
int name_order_size = book.m_MemberCount > 0 ? (book.m_GroupCount > book.m_MemberCount ? book.m_GroupCount : book.m_MemberCount):book.m_GroupCount > 0 ? book.m_GroupCount : 0;
showgrouplist.cpp 80行!
showgrouplist.cpp 80行!
ret5 = code_convert(MAIL_CODE_FROM, MAIL_CODE_TO, (char*)(LPCSTR)txtbody, strlen((LPCSTR)txtbody), body_dest, blen);
int code_convert(char *from_charset, char *to_charset,
char *input, int inlen,
char *output,int outlen)
{
if(!input || !(*input))
{
return -3;
}
size_t len_in = inlen;
size_t len_out = outlen;
const char *p_in = input;
char *p_out = output;
iconv_t cd;
cd = iconv_open(to_charset,from_charset);
if (cd==0) return -2;
memset(output,0,outlen);
if (iconv(cd, &p_in, &len_in, &p_out, &len_out)==-1) return -1;
iconv_close(cd);
return 0;
}
void CSinaMail::DirectReadMsg(LPCSTR para,LPCSTR cgi_url,CStr& msg,CStr& from,CStr& to,CStr& date,CStr& cc,CStr& subject,CStr& txtbody,CStr& msgbody,CStr& reply, int msgbody_inc_attach) {
CStr abmsg,charset,body,mime,tmp,htmlbody,base,link;
int charsetLen = 0;
//get mail file absolute path
AbMsg(abmsg,(LPCSTR)msg);
if(!IsDir(m_mimedir)) mkdir(m_mimedir,0700);
CMimeMail mimeMail;
LPCSTR lpFileName=mimeMail.OpenFile((LPCSTR)abmsg);
CAttachmentList attachmentList;
mimeMail.ReadMail((LPSTR)lpFileName, body, attachmentList);
HandleAttachmenList(attachmentList,para,cgi_url,m_mimedir);
if(!body.IsEmpty()) {
charset.MidStr((LPCSTR)body,0,"\n");
txtbody.MidStr((LPCSTR)body,"\n",0);
charsetLen = strlen((LPCSTR)charset);
MsgTxtContentToHtml(cgi_url,para,(LPCSTR)txtbody,msgbody);
}
if(!msgbody.IsEmpty())
{
msgbody.ReplaceAll("<", "<");
msgbody.ReplaceAll(">", ">");
}
CAttachment* pAtt;
int num=attachmentList.GetCount();
for(int i=0;i<num;i++) {
pAtt=attachmentList.GetItem(i);
if (pAtt->m_nDisplayOrNot==0) continue; //if not need display
if (pAtt->m_nDisplayOrNot==2 && msgbody=="") { //if is html content
mime.Format("%s/%s",(LPCSTR)m_mimedir,(LPCSTR)pAtt->m_cstrFileName);
CTmpl htmlfile((LPCSTR)mime);
htmlbody="<pre>";
htmlbody=htmlbody + (CStr)htmlfile;
htmlbody=htmlbody + "</pre>";
base.MidStrI((LPCSTR)htmlbody,"<BASE",">",1);
LPCSTR body=htmlbody.FindI("<HTML");
if(body) body=strchr(body,'>');
if(body) htmlbody=body+1;
htmlbody.ReplaceI("<body","<xbody");
htmlbody.ReplaceIAll("</BODY>","</xbody>");
htmlbody.ReplaceIAll("</HTML>","");
htmlbody.ReplaceIAll("<SCRIPT","<COMMENT");
htmlbody.ReplaceIAll("</SCRIPT>","</COMMENT>");
if(pAtt->m_nCharSet==HZ_CODE) CheckForHZString(htmlbody);
if (txtbody.IsEmpty())
{
txtbody=htmlbody;
char* des=(char*)calloc(1,txtbody.GetLength());
parsetext(des,(char*)(LPCSTR)txtbody);
txtbody=des;
free(des);
}
// 4. add div
//add by liulei, output base_mark in mail content
msgbody+="<DIV>";
if(!base.IsEmpty()) { // include base
msgbody+="<base";
msgbody+=base;
msgbody+=">";
msgbody+=htmlbody;
msgbody+="</DIV>";
msgbody+="<BASE href=";
msgbody+=cgi_url;
msgbody+=">";
} else {
msgbody+=htmlbody;
msgbody+="</DIV>";
}
//add end
continue;
}
CStr strFujian;
strFujian = "附件";
toLink((LPCSTR)pAtt->m_cstrFileName,link);
CStr fit_displayName(pAtt->m_lpszDisplayName);
repBadchar(fit_displayName);
CStr displayName;
toLink(fit_displayName, displayName);
//2005-11-5 add by zhirui 过滤无效的类型
CStr tmpStr1;
CStrList tmpList1;
if(pAtt->m_lpszType.FindI("application/") && pAtt->m_lpszType.FindI("name="))
{
pAtt->m_lpszType.ReplaceAll(" ", "");
pAtt->m_lpszType.Split("name=", tmpList1);
if(tmpList1.GetCount() == 2)
{
pAtt->m_lpszType.Format("%s", (LPCSTR)*tmpList1.GetItem(0));
//
//pAtt->m_lpszType.ReplaceAll((LPCSTR)pAtt->m_lpszType, "application/vnd.ms-excel");
}
else
{
if(pAtt->m_lpszType.FindI("vnd.ms-excelname="))
{
pAtt->m_lpszType.ReplaceAll((LPCSTR)pAtt->m_lpszType, "application/vnd.ms-excel");
}
else if(pAtt->m_lpszType.FindI("x-excelname="))
{
pAtt->m_lpszType.ReplaceAll((LPCSTR)pAtt->m_lpszType, "application/x-excel");
}
else if(pAtt->m_lpszType.FindI("mswordname="))
{
pAtt->m_lpszType.ReplaceAll((LPCSTR)pAtt->m_lpszType, "application/msword");
}
}
}
//changed by zhirui 2005-10-11
if(msgbody_inc_attach == 1)
{
tmp.Format("<BR><BR>\n--------------------------------------------------<BR>\n%s:<a href='/cgi-bin/email/webmailbox/attachment.cgi/%s/%s/%s/%s/%s'>%s</a>(%s, %ld bytes) <BR>\n--------------------------------------------------<BR>\n", (LPCSTR)strFujian, para, (LPCSTR)pAtt->m_lpszType, (LPCSTR)link, (LPCSTR)displayName, (LPCSTR)displayName, (LPCSTR)pAtt->m_lpszDisplayName, (LPCSTR)pAtt->m_lpszType,pAtt->m_nFileSize);
}
msgbody += tmp;
}
if(charsetLen > 30)
{
charset.Empty();
charset.Format("%s", "gb2312");
}
//+20080124 add get msgId from mail head
mimeMail.GetHeader("Message-ID", this->msgIdStr,(LPCSTR)charset);
mimeMail.GetHeader("X-Mailer", this->xMailerStr,(LPCSTR)charset);
mimeMail.GetHeader("from",from,(LPCSTR)charset);
mimeMail.GetHeader("to",to,(LPCSTR)charset);
mimeMail.GetHeader("subject",subject,(LPCSTR)charset);
mimeMail.GetHeader("cc",cc,(LPCSTR)charset);
mimeMail.GetHeader("date",date,(LPCSTR)charset);
GetStandardTime(8,date);
mimeMail.GetHeader("disposition-notification-to",reply,(LPCSTR)charset);
if(reply.IsEmpty())
mimeMail.GetHeader("Return-Receipt-To",reply,(LPCSTR)charset);
}
int code_convert(char *from_charset, char *to_charset,
char *input, int inlen,
char *output,int outlen)
{
if(!input || !(*input))
{
return -3;
}
size_t len_in = inlen;
size_t len_out = outlen;
const char *p_in = input;
char *p_out = output;
iconv_t cd;
cd = iconv_open(to_charset,from_charset);
if (cd==0) return -2;
memset(output,0,outlen);
if (iconv(cd, &p_in, &len_in, &p_out, &len_out)==-1) return -1;
iconv_close(cd);
return 0;
}
void CSinaMail::DirectReadMsg(LPCSTR para,LPCSTR cgi_url,CStr& msg,CStr& from,CStr& to,CStr& date,CStr& cc,CStr& subject,CStr& txtbody,CStr& msgbody,CStr& reply, int msgbody_inc_attach) {
CStr abmsg,charset,body,mime,tmp,htmlbody,base,link;
int charsetLen = 0;
//get mail file absolute path
AbMsg(abmsg,(LPCSTR)msg);
if(!IsDir(m_mimedir)) mkdir(m_mimedir,0700);
CMimeMail mimeMail;
LPCSTR lpFileName=mimeMail.OpenFile((LPCSTR)abmsg);
CAttachmentList attachmentList;
mimeMail.ReadMail((LPSTR)lpFileName, body, attachmentList);
HandleAttachmenList(attachmentList,para,cgi_url,m_mimedir);
if(!body.IsEmpty()) {
charset.MidStr((LPCSTR)body,0,"\n");
txtbody.MidStr((LPCSTR)body,"\n",0);
charsetLen = strlen((LPCSTR)charset);
MsgTxtContentToHtml(cgi_url,para,(LPCSTR)txtbody,msgbody);
}
if(!msgbody.IsEmpty())
{
msgbody.ReplaceAll("<", "<");
msgbody.ReplaceAll(">", ">");
}
CAttachment* pAtt;
int num=attachmentList.GetCount();
for(int i=0;i<num;i++) {
pAtt=attachmentList.GetItem(i);
if (pAtt->m_nDisplayOrNot==0) continue; //if not need display
if (pAtt->m_nDisplayOrNot==2 && msgbody=="") { //if is html content
mime.Format("%s/%s",(LPCSTR)m_mimedir,(LPCSTR)pAtt->m_cstrFileName);
CTmpl htmlfile((LPCSTR)mime);
htmlbody="<pre>";
htmlbody=htmlbody + (CStr)htmlfile;
htmlbody=htmlbody + "</pre>";
base.MidStrI((LPCSTR)htmlbody,"<BASE",">",1);
LPCSTR body=htmlbody.FindI("<HTML");
if(body) body=strchr(body,'>');
if(body) htmlbody=body+1;
htmlbody.ReplaceI("<body","<xbody");
htmlbody.ReplaceIAll("</BODY>","</xbody>");
htmlbody.ReplaceIAll("</HTML>","");
htmlbody.ReplaceIAll("<SCRIPT","<COMMENT");
htmlbody.ReplaceIAll("</SCRIPT>","</COMMENT>");
if(pAtt->m_nCharSet==HZ_CODE) CheckForHZString(htmlbody);
if (txtbody.IsEmpty())
{
txtbody=htmlbody;
char* des=(char*)calloc(1,txtbody.GetLength());
parsetext(des,(char*)(LPCSTR)txtbody);
txtbody=des;
free(des);
}
// 4. add div
//add by liulei, output base_mark in mail content
msgbody+="<DIV>";
if(!base.IsEmpty()) { // include base
msgbody+="<base";
msgbody+=base;
msgbody+=">";
msgbody+=htmlbody;
msgbody+="</DIV>";
msgbody+="<BASE href=";
msgbody+=cgi_url;
msgbody+=">";
} else {
msgbody+=htmlbody;
msgbody+="</DIV>";
}
//add end
continue;
}
CStr strFujian;
strFujian = "附件";
toLink((LPCSTR)pAtt->m_cstrFileName,link);
CStr fit_displayName(pAtt->m_lpszDisplayName);
repBadchar(fit_displayName);
CStr displayName;
toLink(fit_displayName, displayName);
//2005-11-5 add by zhirui 过滤无效的类型
CStr tmpStr1;
CStrList tmpList1;
if(pAtt->m_lpszType.FindI("application/") && pAtt->m_lpszType.FindI("name="))
{
pAtt->m_lpszType.ReplaceAll(" ", "");
pAtt->m_lpszType.Split("name=", tmpList1);
if(tmpList1.GetCount() == 2)
{
pAtt->m_lpszType.Format("%s", (LPCSTR)*tmpList1.GetItem(0));
//
//pAtt->m_lpszType.ReplaceAll((LPCSTR)pAtt->m_lpszType, "application/vnd.ms-excel");
}
else
{
if(pAtt->m_lpszType.FindI("vnd.ms-excelname="))
{
pAtt->m_lpszType.ReplaceAll((LPCSTR)pAtt->m_lpszType, "application/vnd.ms-excel");
}
else if(pAtt->m_lpszType.FindI("x-excelname="))
{
pAtt->m_lpszType.ReplaceAll((LPCSTR)pAtt->m_lpszType, "application/x-excel");
}
else if(pAtt->m_lpszType.FindI("mswordname="))
{
pAtt->m_lpszType.ReplaceAll((LPCSTR)pAtt->m_lpszType, "application/msword");
}
}
}
//changed by zhirui 2005-10-11
if(msgbody_inc_attach == 1)
{
tmp.Format("<BR><BR>\n--------------------------------------------------<BR>\n%s:<a href='/cgi-bin/email/webmailbox/attachment.cgi/%s/%s/%s/%s/%s'>%s</a>(%s, %ld bytes) <BR>\n--------------------------------------------------<BR>\n", (LPCSTR)strFujian, para, (LPCSTR)pAtt->m_lpszType, (LPCSTR)link, (LPCSTR)displayName, (LPCSTR)displayName, (LPCSTR)pAtt->m_lpszDisplayName, (LPCSTR)pAtt->m_lpszType,pAtt->m_nFileSize);
}
msgbody += tmp;
}
if(charsetLen > 30)
{
charset.Empty();
charset.Format("%s", "gb2312");
}
//+20080124 add get msgId from mail head
mimeMail.GetHeader("Message-ID", this->msgIdStr,(LPCSTR)charset);
mimeMail.GetHeader("X-Mailer", this->xMailerStr,(LPCSTR)charset);
mimeMail.GetHeader("from",from,(LPCSTR)charset);
mimeMail.GetHeader("to",to,(LPCSTR)charset);
mimeMail.GetHeader("subject",subject,(LPCSTR)charset);
mimeMail.GetHeader("cc",cc,(LPCSTR)charset);
mimeMail.GetHeader("date",date,(LPCSTR)charset);
GetStandardTime(8,date);
mimeMail.GetHeader("disposition-notification-to",reply,(LPCSTR)charset);
if(reply.IsEmpty())
mimeMail.GetHeader("Return-Receipt-To",reply,(LPCSTR)charset);
}
function checkSelectedNum(){
var num = 0;
var items = document.forum_admin.elements;
for(var i = 0, len = items.length; i < len; i++){
if(items[i].type == "checkbox" && items[i].name != "checkall" && items[i].name != "checkall2"){
if(items[i].checked)
num++;
}
}
return num;
}
function deleteitem()
{
if(checkSelectedNum() == 0){
window.alert("请至少选中一个选择框后再点击该功能!");
return;
}
if(confirm('确认删除么'))
{
document.forum_admin.action.value = "delete";
document.forum_admin.submit();
}
}
var img = window.document.getElementById("mylogo");
if(!img){
window.alert("请上传你自己的logo图片,然后再设置此项!");
return;
}
var num = 0;
var items = document.forum_admin.elements;
for(var i = 0, len = items.length; i < len; i++){
if(items[i].type == "checkbox" && items[i].name != "checkall" && items[i].name != "checkall2"){
if(items[i].checked)
num++;
}
}
return num;
}
function deleteitem()
{
if(checkSelectedNum() == 0){
window.alert("请至少选中一个选择框后再点击该功能!");
return;
}
if(confirm('确认删除么'))
{
document.forum_admin.action.value = "delete";
document.forum_admin.submit();
}
}
var img = window.document.getElementById("mylogo");
if(!img){
window.alert("请上传你自己的logo图片,然后再设置此项!");
return;
}