nginx php 使用memcached出现页面502错误

2012年7月28日 没有评论

php的版本5.2.17,memcached扩展的版本2.0.1,当使用memcached的cas功能时候出现502错误,而set、get功能正常。开始一直以为是nginx的配置有问题,网上也有人提到过可能跟fast-cgi的一些参数设置有问题,试着修改默认值,问题依旧没有得到解决。后来通过CLI来执行php脚本时候提示了一个错误,按照这个错误搜索,发现原来这是memcached扩展2.0.1跟php 5.2.17不兼容的Bug,具体参看:https://bugs.php.net/bug.php?id=61283。

解决的办法要么是升级php,要么降级memcached扩展到1.0.2,经过测试在php 5.2.17 和 memcached 1.0.2能正常工作。

分类: PHP 标签:

解决 PHPExcel 长数字串显示为科学计数

2012年7月24日 8 条评论

解决 PHPExcel 长数字串显示为科学计数

在excel中如果在一个默认的格中输入或复制超长数字字符串,它会显示为科学计算法,例如身份证号码,解决方法是把表格设置文本格式或在输入前加一个单引号。

使用PHPExcel来生成excel,也会遇到同样的问题,解决方法有三种:
1、设置单元格为文本

$objPHPExcel = new PHPExcel();
$objPHPExcel->setActiveSheetIndex(0);
$objPHPExcel->getActiveSheet()->setTitle('Simple');
//设置A3单元格为文本
$objPHPExcel->getActiveSheet()->getStyle('A3')->getNumberFormat()
	->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_TEXT);
//也可以设置整行或整列的style
/*
//E 列为文本
$objPHPExcel->getActiveSheet()->getStyle('E')->getNumberFormat()
	->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_TEXT);
//第三行为文本
$objPHPExcel->getActiveSheet()->getStyle('3')->getNumberFormat()
	->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_TEXT);
*/

更多的格式可以在PHPExcel/Style/NumberFormat.php中找到。注意:上述的设置对长数字字符串还是以文本方式来显示科学计数法的结果,原因可能php在处理大数字时采用的科学计数法。

2、在设置值的时候显示的指定数据类型

$objPHPExcel = new PHPExcel();
$objPHPExcel->setActiveSheetIndex(0);
$objPHPExcel->getActiveSheet()->setTitle('Simple');

$objPHPExcel->getActiveSheet()->setCellValueExplicit('D1',
                                 123456789033, 
                                 PHPExcel_Cell_DataType::TYPE_STRING);

3、在数字字符串前加一个空格使之成为字符串

$objPHPExcel = new PHPExcel();
$objPHPExcel->setActiveSheetIndex(0);
$objPHPExcel->getActiveSheet()->setTitle('Simple');

$objPHPExcel->getActiveSheet()->setCellValue('D1', ' ' . 123456789033);

推荐使用第二、三种,第一种没有根本解决问题。

分类: PHP 标签:

PHPExcel mac os 下中文乱码问题

2012年7月24日 没有评论

在php中使用PHPExcel来生成Excel表格,内容含有中文,window系统下显示正常,mac os的office打开excel显示不出来中文,现象是表格中看到中文显示为方框,但是焦点放在表格上时,上面的显示的又是中文。程序中使用的编码是GBK,由于PHPExcel只支持UTF8,已经在程序中使用iconv进行了转码,所以可以排除编码的问题。百思不得其解,只好借助万能的Google,在一个链接中发现有人说mac os 打开的excel文件出现乱码是由于字体造成的,再次打开乱码的excel文件,发现打开的默认字体为一个英文字体,终于找到原因了,解决问题就很简单了,在生成excel时候强制设置表格使用某种支持中文的字体即可,如宋体,代码如下:

$objPHPExcel = new PHPExcel();	
$objPHPExcel->setActiveSheetIndex(0);
$objPHPExcel->getActiveSheet()->getDefaultStyle()->getFont()->setName('宋体');

注意:如果当前文件的编码不是使用UTF8,需要对’宋体’进行编码转换使之成功UTF8编码。

PHPExcel真是个好东西,功能太强大了,有点小遗憾的是中文文档不全,想要实现某种功能只能借助搜索引擎了。

分类: PHP 标签:

php json 中文问题

2012年7月11日 没有评论

php中内置函数json_encode提供把一个array转化为json字符串的功能。网上看到很多人说不能处理中文,这种说法其实是不对的,关键是要看php源文件的编码方式,对于非UTF8的php源文件,中文确实会有问题,反之能正常工作,为什么会这样呢,php手册上说的很清楚

This function only works with UTF-8 encoded data.

对于使用utf8作为文件编码方式的人,可以直接忽视中文问题,那么采用GBK或GB2312的怎么办?要么修改文件的编码方式,往往这个不太显示,总不能为了这个问题把一个项目都修改成UTF-8,另外的一个办法是借助urlencode、urldecode在转换一下,urlencode是把原字符串转换为UTF8格式编码,这就满足了json_encode支持UTF8的需求,而urldecode是把UTF8编码转换成当前字符编码。所以在进行json_encode前先把array中的字符串使用urlencode,然后执行json_encode,接着使用urlencode把json_encode结果进行解码。实例代码如下:

function arrayEncode(&$arr) {
    foreach ($arr as $k => $v) {
        if (is_array($v)) {
            arrayEncode($arr[$k]);
        } else {
            $arr[$k] =  urlencode($v);
        }

        if (is_string($k)) {
            $nk = urlencode($k);

            if ($nk != $k) {
                $arr[$nk] = $arr[$k];

                unset($arr[$k]);
            }
        }
    }
}

function my_json($arr) {
    arrayEncode($arr);
    
    return urldecode(json_encode($arr));
}

php 暂停执行多少毫秒

2012年4月11日 没有评论

在php中暂停代码执行一定时间,有两个函数可以实现,一个是sleep,另一个是usleep,它们参数都是一个整数值。sleep是暂停多少秒,usleep是暂停多少微秒。注意:usleep单位是微秒,1秒 = 1000毫秒 ,1毫秒 = 1000微秒,即1微秒等于百万分之一秒。

如果程序中要使用要暂停多少毫秒,只能使用usleep,务必注意参数的单位,假设暂停 50毫秒,应该使用usleep(50000),而不是usleep(50)。

另外,我的理解,这个暂停的时候不可能是百分百的准确,跟系统的调度,cpu时钟周期等等有一定关系。

分类: PHP 标签: ,

php 获取当前时间的毫秒数

2012年3月13日 没有评论

php本身没有提供返回毫秒数的函数,但提供了一个microtime()函数,该函数返回一个array,包含两个元素,一个是秒数,一个是小数表示的毫秒数,借助此函数,可以很容易定义一个返回毫秒数的函数,例如:

function getMillisecond() {
    list($s1, $s2) = explode(' ', microtime());
    return (float)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000);
}

需要注意,在32位系统中php的int最大值远远小于毫秒数,所以不能使用int类型,而php中没有long类型,所以只好使用浮点数来表示。由于使用了浮点数,如果精度设置不对,使用echo显示获取的结果时可能会不正确,要想看到输出正确的结果,精度设置不能低于13位。

关于浮点数精度问题,可以参考:理解 php 浮点数精度值

理解 php 浮点数精度值

2012年3月13日 没有评论

php中浮点数的精度值是用来控制输出该浮点数时使用的,可以理解为控制输出的位数,精度值不同,看到输出结果也可能不一样,注意:其内部还是按照实际值存储的,当两个浮点数进行四则运算时,用的还是其本来的值

php的配置文件中使用precision来设定全局指定浮点数的精度值,似乎每个发行版,它的默认设置都不太一样,我在window下看到是12,在linux下看到此值是14,当然也可以通过程序中使用ini_set来改变全局设置,例如:

	ini_set("precision", "15");

对于精度我一直理解为小数点后保留多少,那么在php的浮点数中是这样的么?答案是否定的。

浮点数其实是整数部分和小数部分组成,这里的精度是指整数部分的位数加小数部分的位数不能超过其精度最大值,如果超过,则按照四舍五入的方法截断到最大的精度值。整数部分如果是0,则不计位数,小数部分末尾0也不计入位数。另外对于同一个数,precision的不同,可能显示的出来表现形式也不一样。下面通过例子的方式来说明。

整数部分为 0 情况

	$num = 0.12345600000000000;
	//整数部分为0 ,位数为 0 ,小数部分末尾的 0 不计入位数,所以总位数为 6

	ini_set("precision", "12");
	echo $num; // 0.123456
	//未超过精度值,显示的结果为 0.123456

	ini_set("precision", "3");
	echo $num; // 0.123
	//超过精度值,保留3位

	ini_set("precision", "5");
	echo $num; // 0.12346
	//超过精度值,保留5位

这种情况下,精度值等价于小数点后保留几位。

整数部分大于 0 情况

	$num = 12.12345600000000000;
	//整数部分为12 ,位数为 2 ,小数部分末尾的 0 不计入位数,位数为6,所以总位数为 2 + 6

	ini_set("precision", "12");
	echo $num; // 12.123456
	//未超过精度值,显示的结果为 12.123456

	ini_set("precision", "3");
	echo $num; // 12.1
	//超过精度值,整数部分位数为 2 ,所以只保留一位小数

	ini_set("precision", "5");
	echo $num; // 12.123
	//超过精度值,整数部分位数为 2 ,所以只保留3位小数

可以看到小数点后保留的位数跟精度已经整数部分的位数有关。

整数部分大于 0 情况 之二

	$num = 12345678.12345600000000000;
	//整数部分为12345678 ,位数为 8 ,小数部分末尾的 0 不计入位数,位数为6,所以总位数为 8 + 6

	ini_set("precision", "12");
	echo $num; // 12345678.1235
	//超过精度值,显示的结果为 12345678.1235

	ini_set("precision", "3");
	echo $num; // 1.23E+7
	//超过精度值,且整数部分位数超过精度,小数部分舍弃,且整数部分只取3位

	ini_set("precision", "5");
	echo $num; // 12346000
	//超过精度值,且整数部分位数超过精度,小数部分舍弃,且整数部分只取5位

上述例子中可以看到,精度值也关系到整数部分的截取。注意到最后两个例子中显示的方式不一样,一个是使用科学计数法,一个是后面用 0 补。通过实验得出的结论是当整数部分的位数 减去 精度值 大于 4 的时候,使用科学计数法的方式,否则后面用 0 补,换句话说,就是整数部分位数超过精度值后,截断后,补 0 的个数不会超过 4 。

浮点数运算

	$num1 = 1331625729.687;
	$num2 = 1331625730.934;
	ini_set("precision", "8");

	echo $num1 . '
';
	echo $num2 . '
';

	$sub = $num1 - $num2;

	echo $sub . '
';
//输出的结果为:
/*
	1331625700
	1331625700
	-1.247
*/

上述例子就说明了精度值只是控制显示结果,内部存储还是原始值,所以 $sub 的值为1331625729.687减1331625730.934。

分类: PHP 标签:

PHP strtotime 性能问题

2012年2月22日 没有评论

在php中对一个有五万多个元素的数组进行遍历同时做一些简单的逻辑运算,发生耗时居然达到了13秒之多,通过排发现耗时的操作都是在strtotime上,使用strtotime把字符串“2012-02-22 10:07:34”转化为秒形式。开始以为就是strtotime的效率有问题,后来突然想起来,如果在PHP 5中,如果没有显式的设置timezone,php会有一个警告信息,猜测造成strtotime耗时的原因就是php需要处理警告,在php.ini中设置date.timezone = PRC 后在测试,果然不需要那么久了。

总结:在php 5后需要设置timezone,否则可能在进行日期、时间操作函数造成性能问题,另外在错误日志会出现大量的警告信息。

分类: PHP 标签:

关于php的时间相关函数需要注意时区问题

2012年1月1日 没有评论

time()函数能获取一个相对于1901年的时间秒数,但是需要注意,如果系统没有设置时区,那么获得的结果是UTC时间,相对中国用户来说,就是相差了8个小时,例如通过date来获取当前的日期,date(‘Y-m-d’),在早上8点前看到的日期是昨天的,所以需要显示设置时区,可以在php.ini中设置,date.timezone = PRC,或者在使用前用date_default_timezone_set来设置,例如 date_default_timezone_set(“PRC”);

分类: PHP 标签:

无觅相关文章插件,快速提升流量