有时为了调试程序,需要查看所有POST过来的数据.
file_get_contents("php://input"); echo file_get_contents("php://input");
有时为了调试程序,需要查看所有POST过来的数据.
file_get_contents("php://input"); echo file_get_contents("php://input");
有些mysql查询返回的结果仅仅是成功或失败.
也许有些查询影响的行数为0,但是这个查询没有错误,那么返回的也是执行成功,然而有的时候是需要知道查询影响了多少条数据的.
PHP有个函数
mysql_affected_rows();
可以取得最近一次 INSERT,UPDATE 或 DELETE 查询所影响的记录行数。
这个函数可以带一个MYSQL连接标识符的参数,如果不加参数,如果没有指定,默认使用最后被 mysql_connect() 打开的连接。
执行成功,则返回受影响的行的数目,如果最近一次查询失败的话,函数返回 -1。
如果最近一次操作是没有任何条件(WHERE)的 DELETE 查询,在表中所有的记录都会被删除,但本函数返回值在 4.1.2 版之前都为 0。
当使用 UPDATE 查询,MySQL 不会将原值与新值一样的列更新。这样使得 mysql_affected_rows() 函数返回值不一定就是查询条件所符合的记录数,只有真正被修改的记录数才会被返回。
REPLACE 语句首先删除具有相同主键的记录,然后插入一个新记录。该函数返回的是被删除的记录数加上被插入的记录数。
有时候写前端界面的时候,有些文字内容比较长,我们希望他能自动换行.
比如一个表格里面的内容,本来设置了表格宽度,但是实际有时内容过长,换行就出了问题,有些情况会自动换行,有些时候不会,这样就可能把布局搞乱.
只要在css里面把要强制换行的元素加上
Word-break: break-all;
属性就可以了,比如设定表格宽度后,加上这个属性,那么不管内容是啥,只要超过了宽度就会换行.
上篇文章说的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'] //其他情况就是被修改过的文件了.
由于我的保护系统对接了其他程序,里面有一些乱七八糟的接口,检测结果的输出方式也很混乱,不方便直接全部贴出来,而且直接贴出来这么凌乱的代码估计新手也看不大明白,要是有空,我把代码整理一下在上传好了,要是有什么疑问,可以留言.
近期虚拟主机莫名其妙被攻击,持续每秒几十次访问搞了几天,后台错误日志又发现wordpress程序似乎有代码进入了死循环,最后不出预料的服务器被主机提供商暂停了,原因自然是大量占用服务器资源.
外部攻击除了屏蔽ip,也没有太好的方法,不过内部问题倒是要想办法做做,出了这么大问题,也怕是有人发现了wordpress漏洞攻击了,总担心站点文件被修改,怕上传了后门,干脆清空了主机,重新安装了wordpress.真是逼死强迫症…
然后就想,以后再出事怎么搞,总不能出问题就重装wordpress,于是考虑做一个文件保护系统,基本原理就是记录文件修改时间和文件md5值来检测服务器文件有没有被修改.
项目详细实现:
1.保护系统初始化时,开始检测所有已存在文件的修改时间和md5值,把文件名-修改时间-md5存到数据库.
2.每次打开网站,指定一个周期,再次检测所有文件,对比数据库,列出被修改,删除,新增的文件.
3.部分缓存文件经常变动,需要单独列出来.
4.检测结果发现异常后,标识出异常文件,确认无威胁或以解决问题后,可以重新初始化系统.
更进一步开发:
5.计划任务,让该系统后台间隔一定时间后自动执行,并把检测结果发送到指定邮箱.
6.每次检测时,备份数据库文件,并发送到邮箱.
7.备份重要文件,这个有点不靠谱,毕竟副本存在服务器上也没什么安全性,发到邮箱每次消耗的流量更惨不忍睹,不过要是重要文件打包压缩存在服务器,给邮箱发下载链接,定期主动下载倒还可以.
有的虚拟主机不让在前台显示错误,这是一种保护措施,避免一些用户使用不安全代码而被攻击,毕竟错误信息有时能暴露出很多问题.然而有时候在调试代码的时候,如果没有直接输出错误信息,就不好确定到底出了什么问题,而每次到控制面板后台去看日志也是一个麻烦的事.
最好的当然是有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虚拟主机,所以那些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里面!