PHP 检查文件大小

定义和用法

filesize() 函数返回指定文件的大小。

若成功,则返回文件大小的字节数。若失败,则返回 false 并生成一条 E_WARNING 级的错误。

语法

filesize(filename)
参数 描述
filename 必需。规定要检查的文件。

提示和注释

提示:本函数的结果会被缓存。请使用 clearstatcache() 来清除缓存。

例子

<?php
echo filesize("test.txt");
?>

PHP 清除文件状态缓存

1.定义和用法

clearstatcache() 函数清除文件状态缓存。

有时函数会缓存某些函数的返回信息,以便提供更高的性能。但是有时候,比如在一个脚本中多次检查同一个文件,而该文件在此脚本执行期间有被删除或修改的危险时,你需要清除文件状态缓存,以便获得正确的结果。要做到这一点,就需要使用 clearstatcache() 函数。

会进行缓存的函数,即受 clearstatcache() 函数影响的函数:

  • stat()
  • lstat()
  • file_exists()
  • is_writable()
  • is_readable()
  • is_executable()
  • is_file()
  • is_dir()
  • is_link()
  • filectime()
  • fileatime()
  • filemtime()
  • fileinode()
  • filegroup()
  • fileowner()
  • filesize()
  • filetype()
  • fileperms()

语法

clearstatcache()

PHP 获取文件最后修改时间

1.定义和用法

filemtime() 函数返回文件内容上次的修改时间。

若成功,则时间以 Unix 时间戳的方式返回。若失败,则返回 false。

语法

filemtime(filename)
参数 描述
filename 必需。规定要检查的文件。

说明

本函数返回文件中的数据块上次被写入的时间,也就是说,文件的内容上次被修改的时间。

2.提示和注释

提示:本函数的结果会被缓存。请使用 clearstatcache() 来清除缓存。

3.实例

$a=filemtime("log.txt");
echo "修改时间:".date("Y-m-d H:i:s",$a).";

PHP 解决mysql结果集转json后中文乱码

做了一个ajax的站,php后台处理完了数据库后,需要把结果以json数据的方式发到前端由js使用,编程这东西,编码总是会莫名其妙造成影响…

//$result是一个mysql查询的结果集
while($row = mysql_fetch_array($result)){
	foreach ( $row as $key => $value ) {  
		$row[$key] = urlencode ( $value );
	}  
	$urlencode_result[$i++]=$row;
}
$json = urldecode(json_encode($urlencode_result));

以上代码,首先把结果集中的每个值都urlencode来解决可能出现的编码问题,然后json_encode,把已经urlencode处理过的转成json数据,最后把json数据中被urlencode的数据恢复.

原理就是PHP的json_encode会把中文转成乱码,但是在json_encode前先urlencode,这样就没有中文了,转为json后没有问题,转换完,要用的时候在urldecode恢复中文数据.

你可能还需要看看PHP读取MYSQL数据后中文乱码的解决方法

PHP 直接POST数据

做模拟登陆或者后台任务的时候,可能会需要php在后台直接post数据到其他页面,并且获取返回结果来进行下一步处理.可能比较常用的是curl,不过在一些简单的地方使用,感觉有些麻烦,一个post要一大堆代码…

善用搜索引擎,发现了一个比较简单的post数据的方式,封装成一个函数方便调用.

function do_post_request($url, $data, $optional_headers = null)
  {
     $params = array('http' => array(
                  'method' => 'POST',
                  'content' => $data
               ));
     if ($optional_headers !== null) {
        $params['http']['header'] = $optional_headers;
     }
     $ctx = stream_context_create($params);
     $fp = @fopen($url, 'rb', false, $ctx);
     if (!$fp) {
        throw new Exception("Problem with $url, $php_errormsg");
     }
     $response = @stream_get_contents($fp);
     if ($response === false) {
        throw new Exception("Problem reading data from $url, $php_errormsg");
     }
     return $response;
  }

调用方法:

do_post_request($url,$data,$headers);
//第一个参数写post的对象,需要写绝对地址,例如"http://www.devsk.com"
//第二个参数写要post的数据,例如"a=1&b=2",目标页面$_POST['a']的值就是1,$_POST['b']的值就是2
//第三个参数可以不填,如果需要设置header,则可以在第三个参数输入,比如要传递cookie,可以写"Cookie:ID=123"
//函数返回值就是目标页面的输出
//完整的调用实例:
$result = do_post_request("http://www.devsk.com","a=1&b=2","Cookie:ID=123");
//向http://www.devsk.com页面post数据,包含两个变量(a=1 b=2)和一个cookie (ID=123).最后http://www.devsk.com页面的输出赋值给变量$result.

PHP 文件保护系统部分代码

上篇文章说的PHP文件保护系统,感觉挺高大上,其实真做起来没什么难度,本文大致上把需要用到的知识和函数说一下,附上部分代码.

为了简单起见,就做了一个简单的例子,仅仅只检测当前脚本目录下的文件.

一.数据库

表名:
protection

字段:
文件名:file  varchar(64),
最后修改时间:  time int(64) ,
初始sha1: sha1 text(32),
当前sha1: now_sha1 text(32),

二.关键代码

1.初始化

if ($handle = opendir('./')) {
	mysql_query('TRUNCATE TABLE protection');
	while (false !== ($file = readdir($handle))) {
		if ($file != "." && $file != "..") {
			if(!mysql_query('insert into protection (file,time,sha1)value(\''.$file.'\',\''.time().'\',\''.sha1_file($file).'\')'))
				die(mysql_error());
			}
		}
	}

2.再次检测文件

if ($handle = opendir('./')) {
	mysql_query('update protection set now_sha1=\'\'');
	while (false !== ($file = readdir($handle))) {
		if ($file != "." && $file != "..") {
			mysql_query('update protection set now_sha1=\''.sha1_file($file).'\' where file =\''.$file.'\'');
			mysql_query('insert into protection (file,now_sha1) value (\''.$file.'\',\''.sha1_file($file).'\')');
			}
		}
	}

3.文件状态判断条件

//首先读取数据库
$result = mysql_query('select * from protection');

//然后依次检测每条数据:
while($row = mysql_fetch_array($result)){
  //检测代码
}

//以下是检测过程中对文件状态的判断条件,具体判断过程可根据自己需要来写.

//新增文件:
$row['sha1']==null && $row['now_sha1'] != null

//删除文件:
$row['sha1']!=null && $row['now_sha1'] == null

//正常文件:
$row['sha1']==$row['now_sha1'] && $row['sha1'] && $row['now_sha1']

//初始化时没有的文件,之前检测存在而现在检测不存在的文件(可能是上传的后门,利用好了后被攻击者删除了)
!$row['sha1'] && !$row['now_sha1']

//其他情况就是被修改过的文件了.

由于我的保护系统对接了其他程序,里面有一些乱七八糟的接口,检测结果的输出方式也很混乱,不方便直接全部贴出来,而且直接贴出来这么凌乱的代码估计新手也看不大明白,要是有空,我把代码整理一下在上传好了,要是有什么疑问,可以留言.

PHP 文件保护系统

近期虚拟主机莫名其妙被攻击,持续每秒几十次访问搞了几天,后台错误日志又发现wordpress程序似乎有代码进入了死循环,最后不出预料的服务器被主机提供商暂停了,原因自然是大量占用服务器资源.

外部攻击除了屏蔽ip,也没有太好的方法,不过内部问题倒是要想办法做做,出了这么大问题,也怕是有人发现了wordpress漏洞攻击了,总担心站点文件被修改,怕上传了后门,干脆清空了主机,重新安装了wordpress.真是逼死强迫症…

然后就想,以后再出事怎么搞,总不能出问题就重装wordpress,于是考虑做一个文件保护系统,基本原理就是记录文件修改时间和文件md5值来检测服务器文件有没有被修改.

项目详细实现:

1.保护系统初始化时,开始检测所有已存在文件的修改时间和md5值,把文件名-修改时间-md5存到数据库.

2.每次打开网站,指定一个周期,再次检测所有文件,对比数据库,列出被修改,删除,新增的文件.

3.部分缓存文件经常变动,需要单独列出来.

4.检测结果发现异常后,标识出异常文件,确认无威胁或以解决问题后,可以重新初始化系统.

更进一步开发:

5.计划任务,让该系统后台间隔一定时间后自动执行,并把检测结果发送到指定邮箱.

6.每次检测时,备份数据库文件,并发送到邮箱.

7.备份重要文件,这个有点不靠谱,毕竟副本存在服务器上也没什么安全性,发到邮箱每次消耗的流量更惨不忍睹,不过要是重要文件打包压缩存在服务器,给邮箱发下载链接,定期主动下载倒还可以.

PHP输出错误信息

有的虚拟主机不让在前台显示错误,这是一种保护措施,避免一些用户使用不安全代码而被攻击,毕竟错误信息有时能暴露出很多问题.然而有时候在调试代码的时候,如果没有直接输出错误信息,就不好确定到底出了什么问题,而每次到控制面板后台去看日志也是一个麻烦的事.

最好的当然是有php.ini修改权限,这样可以自己开关一些功能,包括错误输出.不过很少虚拟主机支持这个,至少我用过的虚拟主机都不支持…

但是问题总要解决,于是有这样一个函数ini_set(),这个函数可以设置php.ini的一些值,并在代码运行时覆盖原本php.ini的设置.

error_reporting(E_ALL); //输出所有类型的错误
ini_set("display_errors","On");//设置开启错误信息输出
ini_set('error_log', dirname(__FILE__) . '/error_log.txt'); //将出错信息输出到当前代码路径下的一个文本文件 error_log.txt

当然,大多数时候我们不会想要输出所有类型的错误,因为一些输出的信息并没有影响,并不是什么安全问题,但是输出后的错误信息对页面布局造成影响,所以正常情况会屏蔽一些不需要的信息,比如我一般是用

error_reporting(E_ALL & ~E_NOTICE);

这样屏蔽掉NOTICE类型的错误,其他显示出来的问题则都是需要去解决的.

以下是错误分级,可以使用加上 &~错误类型的方式屏蔽指定类型

错误级别分为:

E_ERROR:严重错误。

E_WARNING:最普通的错误类型。

E_PARSE:解析错误在编译的时候发生。

E_STRICT:这个错误级别是唯一不包含在E_ALL常量中的,为了让PHP4到PHP5的迁移更加容易。

E_NOTICE:表示运行的代码可能在操作一些未知的事情。

E_CORE_ERROR:由于扩展启动失败等导致的。

E_COMPILE_WARNING:编译的时候出现的警告,告诉用户一些不推荐使用的语法信息。

E_COMPILE_ERROR:编译错误。

当然,也可以只使用其中一个或几个,例如:

error_reporting(E_WARNING);

PHP 无刷新上传

最近工作需要,写了个上传后二维码分享的小功能,为了界面更友好,考虑使用无刷新上传.

由于主机就是单纯的php虚拟主机,所以那些java,插件什么的用不了,只好曲线救国,使用iframe .

实际就是把post上传文件后跳转的页面指向了iframe,从而实现本页面不需要刷新就可以上传.

下面是一个示例:

<form enctype="multipart/form-data" method="POST" target="upload" action="upload.php" >
<input type="file" name="file" />
<input type="submit" />
</form>
<iframe name="upload" style="display:none"></iframe>

实际上就是上传文件的post表单多了一个属性target,这个指定页面在哪里打开,而下面一个ifarme的name设定为uplaod,就是form表单post打开页面的目标了,然后iframe的css属性设置为不可见,于是上传完成后没有任何提示,当然也可以让上传页面返回上传结果,然后结果就显示在了iframe里面!