分类目录归档:php

PHP __destruct函数

PHP引擎会在脚本执行完成后进行垃圾回收,那么是否还需要destruct呢?在stackoverflow上看到的一个很好的答复

析构函数本身跟内存释放没有任何直接的关系,它只是当一个对象被回收时执行自定义代码的“钩子”。它的作用跟构造函数刚好相反-构造函数本身也不申请内存(内存的申请和释放都是GC的事)。
GC能够很好的管理PHP原生的资源(比如对象),但是对于外部资源却必须手动处理。比如,一个文件管理的类,析构函数的作用就是保证如果文件被打开了,就应该被关闭。虽然“最好”在一个对象上要求去调用一个关闭或处理操作,这时析构函数就作为一种援助机制。
我本身反对将析构函数与GC一起使用。有许多微妙的问题他们可以引入如明显的非确定性和意外的能力保持对象存活——甚至在像PHP这种使用引用计数的语言里面。(Java/JVM和.net使用终结器更为挑剔。)

继续阅读

PHP strtotime计算月份

今天同事发现了一个php的月份bug,说月份列表里怎么出现了两个3月份,代码是大概是这样的:

$month[]=date('Y年m月',strtotime('today'));
$month[]=date('Y年m月',strtotime('-1 month'));
$month[]=date('Y年m月',strtotime('-2 month'));
$month[]=date('Y年m月',strtotime('-3 month'));
$month[]=date('Y年m月',strtotime('-4 month'));
$month[]=date('Y年m月',strtotime('-5 month'));

利用strtotime来计算最近了六个月份,这个bug之前没有被发现因为只有在每月的29,30,31号才会发作:因为php默认取当前时间来做计算,比如今天7月29号减去5个月应该是2月29号,因为今年的2月份没有29号,所以就到了3月份了。 继续阅读

PHP base64_decode 空格问题

php对一个base64_encode编码后的字符串通过url传递后进行base64_decode发现返回值是false。尝试将url传递后的值打印出来发现+都被换成了空格。上网查了下发现,对于通过application/x-www-form-urlencoded的HTTP传递值,+会被自动替换为空格。所以也有各种对base64编码进行扩充的,比如对+,/等符号进行替换的,以便HTTP传输。在php中需要将+号或空格做退还,比如简单的str_replace(‘ ‘,’+’,$str)或者在传输前做urlencode。
继续阅读

PHP安全问题

乌云漏洞平台上发现很多开源PHP程序存在漏洞。大部分漏洞都是因为对PHP中的变量过滤不够严格和未转义造成,直接使用了$_GET,$_PUT,$_COOKIE传过来的值,造成了sql注入(sql injection)和跨站攻击(xss)。事实上这些漏洞完全可以避免的。
先说sql注入。通常注入情况发生在参数过滤不严谨和拼接sql,所以尽量不要用sql拼接,尽量使用PDO或Mysqli。 继续阅读

PHP 自动加载类

老的项目很多不规范,到处都是require/include_once。为了不再到处写require/include(_once)了,应该给项目写个自动加载器了,避免重复加载和建立规范。个人觉得require_once和require之间的性能差异不大,特别是开启了APC缓存后,手动加载和自动加载之间的差异也不大。关于APC缓存类文件有争议,建议阅读参考链接和相关评论。

function autoloader($class){
	if (class_exists($class, false) || interface_exists($class, false)) {//如果已存在就不需要了
            return;
    }
	$directorys = array(
            MVC_PATH.'/'.'library'.'/',
            MVC_PATH.'/'
    );
    $file = str_replace('_', '/', $class) . '.php';//对类命名进行文件路径解析映射
    foreach($directorys as $directory){
    	if(file_exists($directory.$file)){
    		require_once($directory.$file);
    		return;
    	}
    }
}
spl_autoload_register(autoloader);

继续阅读