按日期归档:2013 年 5 月 19 日

PHP读取Excel数字问题

1.查看PHP配置文件precision默认12位

2.  格式化可能造成科学计数的数据

     

 if (strpos($d, '+') !== false){
          $d['express_no']=sprintf("%.2f", $d);
  }

 

 

 

php-fcgi进程数超过预设值问题的解决

昨日,有朋友问我,他将Web服务器换成Nginx 0.6.31 + PHP 4.4.7(FastCGI)后,有时候访问会出现“502 Bad Gateway”错误,如何解决。

我让按照以下两个步骤去解决,最后在第2步中将FastCGI的timeout时间增加为300,问题解决:

PS:比较羡慕迅雷的Web服务器,16G内存。

1、查看当前的PHP FastCGI进程数是否够用:
netstat -anpo | grep “php-cgi” | wc -l

如果实际使用的“FastCGI进程数”接近预设的“FastCGI进程数”,那么,说明“FastCGI进程数”不够用,需要增大。

2、部分PHP程序的执行时间超过了Nginx的等待时间,可以适当增加nginx.conf配置文件中FastCGI的timeout时间,例如:
……
http
{
……
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
……
}

 

==================================================

php-fpm 修改php-cgi进程数

vi /usr/local/php/etc/php-fpm.conf

修改这个里面的值
5

然后
/usr/local/php/sbin/php-fpm restart

==================================================
现象:
某日和开发的同事调试服务器php状态时候发现下面这种情况:
ps aux |grep php-fcgi |wc -l
602
表面上看是没什么问题,可是我明明记得 php-fcgi我只开了300个啊!难道有人改过了?
立 刻查看php-fpm.conf找到这一项
<value name=”max_children”>300</value>
确实是300个啊~~,怎么会有600个?
ps aux |grep php-fcgi |more
www      11707  0.0  0.7 250192  3888 ?        S    17:07
www      11708  0.0  0.7 250192  3888 ?        S    17:07
www      11709  0.0  0.7 250192  3888 ?        S    17:07
www      11710  0.0  0.7 250192  3888 ?        S    17:07
www      11711  0.0  0.7 250192  3888 ?        S    17:07
状态都正常啊,奇怪了。尝试把 php-fcgi重启一下
/usr/local/php-fcgi/sbin/php-fpm restart
Shutting down php_fpm . done
Starting php_fpm  done

再次查看
ps aux |grep php-fcgi |wc -l
602

还 是多了300个…..奇怪了,这三百个是怎么来的呢?
因为我们的php和nginx是 一起的,所以我又想到了nginx。
在访问量不高的时候偷偷重启了一下nginx
/etc/init.d/nginx restart
停止 nginx:                                               [确定]
Shutting down php_fpm  done
启动 nginx:                                               [确定]
Starting php_fpm  done

再次查看,我倒…..真服了。我和开发的同事都一头雾水
ps aux |grep php-fcgi |wc -l
602
这回不能简单的考虑重启服务了,需要想想到底是哪里 出的问题,而且这是生产服务器不能随便弄。
因为现在线上的服务都还算正常,这个问题我们就先放下了。
第二天,那个同事跟我说。那个问题他知道怎么解决了,而 且也知道是什么原因造成的。我赶紧问清楚:
原来是这样,最近因为测试比较频繁,对nginx服务重启次数较多。不知道哪次重启时候失败导致nginx进程虽然停止了,
但是一起的300个php-fcgi却没有重启,导致这些进程还留在内存里不能被释放。需要强制手动杀掉所有的php- fcgi进程后再重启php-fpm就可以了。
听到这里我恍然大悟。马上去服务器上操作,果然问题解决了,具体步骤如下
pkill php-cgi
再次查看
ps aux |grep php-fcgi |wc -l
1
好了没有了,赶紧重启,因为现在访问网页已经是 502了。
/usr/local/php-fcgi/sbin/php-fpm restart
Shutting down php_fpm warning, no pid file found – php-fpm is not running ?
Starting php_fpm  done
再次查看进 程数
ps aux |grep php-cgi |wc -l
302
好了,正常 了,呵呵
后来我在试验机上面又测试了一下,果然重现了那个问题

[root@ime /]# /etc/init.d/nginx restart
停止 nginx:                                               [确定]
Shutting down php_fpm  done
启动 nginx:                                               [确定]
Starting php_fpm  done
[root@ime /]# ps aux |grep php-cgi|wc -l
302
这时进程数是正常的,下面杀掉nginx 进程
[root@ime /]# pkill nginx
[root@ime /]# lsof -i:80
[root@ime /]# ps aux |grep php-cgi|wc -l
302
这300个进程就傻乎乎的留在这里了,再 次启动nginx
[root@ime /]# /etc/init.d/nginx start
启动 nginx:                                               [确定]
Starting php_fpm  done
[root@ime /]# lsof -i:80
COMMAND   PID USER   FD   TYPE DEVICE SIZE NODE NAME
nginx   14072 root    8u  IPv4  64090       TCP *:http (LISTEN)
nginx   14073  www    8u  IPv4  64090       TCP *:http (LISTEN)

[root@ime /]# ps aux |grep php-cgi|wc -l
603
php-fcgi没有去理会在内存中存在的进程,继续开启了300个…
我如果再重复这个过程呢?
[root@ime /]# pkill nginx
[root@ime /]# lsof -i:80
[root@ime /]# /etc/init.d/nginx start
启动 nginx:                                               [确定]
Starting php_fpm  done
[root@ime /]# pkill nginx
[root@ime /]# lsof -i:80
[root@ime /]# ps aux |grep php-cgi|wc -l
904
900个… 继续重复
[root@ime /]# /etc/init.d/nginx start
启动 nginx:                                               [确定]
Starting php_fpm  done
[root@ime /]# ps aux |grep php-cgi|wc -l
954
[root@ime /]# ps aux |grep php-cgi|wc -l
1205
机 器开始变慢了,估计再重复几次机器就会挂掉了…
[root@ime /]# pkill php-cgi
[root@ime /]# ps aux |grep php-cgi|wc -l
5
[root@ime /]# ps aux |grep php-cgi|wc -l
5
[root@ime /]# ps aux |grep php-cgi|wc -l
1
[root@ime /]# /etc/init.d/nginx restart
停止 nginx:                                               [确定]
Shutting down php_fpm warning, no pid file found – php-fpm is not running ?
启动 nginx:                                               [确定]
Starting php_fpm  done
[root@ime /]# ps aux |grep php-cgi|wc -l
302
好了,恢复正常….
看来需要修改一下 php-fpm的启动脚本了

=====================================================================

1、查看当前的PHP FastCGI进程数是否够用:
netstat -anpo | grep “php-cgi” | wc -l

如果实际使用的 “FastCGI进程数”接近预设的“FastCGI进程数”,那么,说明“FastCGI进程数”不够用,需要增大。
2、部分PHP程序的执行时间超过了Nginx的等待时间,可以适当增加nginx.conf配置文件中FastCGI的timeout时间,例如:
……
http
{
……
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
……
}
……

将原始文件重命名后下载,有助于处理路径的安全非暴露问题

/**
 * 文件下载
 * @param $filepath 文件路径 为绝对或者相对的物理地址(一定是物理地址);
 * @param $filename 文件名称 将下载的文件重新命名
 */
function file_down($filepath, $filename = '') {
    if(!$filename) $filename = basename($filepath);
    if(is_ie()) $filename = rawurlencode($filename);
    $filetype = fileext($filename);
    $filesize = sprintf("%u", filesize($filepath));
    if(ob_get_length() !== false) @ob_end_clean();
    header('Pragma: public');
    header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
    header('Cache-Control: no-store, no-cache, must-revalidate');
    header('Cache-Control: pre-check=0, post-check=0, max-age=0');
    header('Content-Transfer-Encoding: binary');
    header('Content-Encoding: none');
    header('Content-type: '.$filetype);
    header('Content-Disposition: attachment; filename="'.$filename.'"');
    header('Content-length: '.$filesize);
    readfile($filepath);
    exit;
}

/**
 * 取得文件扩展
 * @param $filename 文件名
 * @return 扩展名
 */
function fileext($filename) {
    return strtolower(trim(substr(strrchr($filename, '.'), 1, 10)));
}

/**
 * IE浏览器判断
 */

function is_ie() {
    $useragent = strtolower($_SERVER['HTTP_USER_AGENT']);
    if((strpos($useragent, 'opera') !== false) || (strpos($useragent, 'konqueror') !== false)) return false;
    if(strpos($useragent, 'msie ') !== false) return true;
    return false;
}

/**
* 产生随机字符串
*
* @param    int        $length  输出长度 
* @param    string     $chars   可选的 ,默认为 0123456789
* @return   string     字符串
*/
function random($length, $chars = '0123456789') {
    $hash = '';
    $max = strlen($chars) - 1;
    for($i = 0; $i < $length; $i++) {
        $hash .= $chars[mt_rand(0, $max)];
    }
    return $hash;
}

 

用法:

//$filename为相对的或者绝对的物理地址,不能是http地址,否则出错          

           $basefilename = basename($filename);
$ext = fileext($basefilename);
$basefilename = date(‘Ymd_his’).random(3).’.’.$ext;
file_down($filename, $basefilename);

thinkphp框架在nginx环境下去掉index.php路径显示

协助用户将apache下的一个网站迁移到nginx环境中,结果发现用户用的ThinkPHP框架做的开发,默认用的pathinfo。

这是一个很头疼的问题,因为nginx不支持pathinfo,贸然一并打开也担心不安全。

于是查询资料后整理如下:

找到applications/Conf/的配置文件 config.php
return array(
‘URL_MODEL’=>2,  //关于URL更多说明请参考Tinkphp/Common/convention.php
);
复制代码
配置 Nginx.conf

在你的虚拟主机下添加

location / {
if (!-e $request_filename){
rewrite ^/(.*)$ /index.php/$1 last;
}
}
复制代码
如果你的项目入口文件在一个子目录内则

location /目录/ {
if (!-e $request_filename){
rewrite ^/目录/(.*)$ /目录/index.php/$1 last;
}
}

点评:
测试成功,注意Tinkphp/Common/convention.php
和网站下的applications/Conf/config.php
两个文件 都要修改。

主要就是改成模式2,rewrite方式就可以了。

win8 音频服务无法启动的解决方法是什么

win+R,输入”regedit”打开注册表编辑器,搜索”Audiosrv”~用全字匹配,把里面的RequiredPrivileges后面对应的Data数据里面的数据的后两项删除,只保留SeChangeNotifyPrivilege。

注册表修改后进入控制面板——管理工具——进入服务——双击Windows Audio,选择登陆——此帐户——浏览——高级——立即查找——LOCALSERVICE确定——密码清空——Ok!!!!

Linux 时间跑快

在系统中依次执行以下命令:
*******************************

1) echo -e “0.asia.pool.ntp.org\n1.asia.pool.ntp.org\n2.asia.pool.ntp.org\n3.asia.pool.ntp.org\n210.72.145.44”>>/etc/ntp/step-tickers
2) service ntpd stop
3) ntpdate 0.asia.pool.ntp.org
4) echo -e “server 0.asia.pool.ntp.org prefer\nserver 1.asia.pool.ntp.org\nserver 2.asia.pool.ntp.org\nserver 3.asia.pool.ntp.org\nserver 210.72.145.44”>>/etc/ntp.conf
5) service ntpd start
6) chkconfig –level 35 ntpd on
*******************************
执行以上命令后,将开启NTP时间服务,主机会自动与授时中心同步时间。

Windows 下制作免安装的 MySQL 简化版

1、首先下载免安装包 mysql-noinstall-5.1.54-win32.zip(其它版本类似)
2、复制 bin 、data 和 share 三个目录和 my-medium.ini 文件到 d:\tools\mysql 目录
修改 my-medium.ini 的名称为 my.ini
保留 bin 目录下的 mysqld.exe 文件,mysqladmin.exe 和 mysql.exe 建议也保留,其它文件是否保留视情况而定
data 和 share 两个目录不需要修改
【注】如果使用 innodb_plugin 功能,还需要复制 lib\plugin\ha_innodb_plugin.dll 文件(保持目录结构)
3、修改配置文件 my.ini 指定基本目录和数据目录
basedir=”d:\tools\mysql ”
datadir=”d:\tools\mysql \data\”
如果使用 innodb_plugin 功能,修改配置文件 my.ini 增加如下配置
ignore-builtin-innodb
plugin-load=innodb=ha_innodb_plugin.dll
innodb_file_format=barracuda
innodb_strict_mode=1
4、安装 MySQL 服务器,将其注册为 Windows 服务
命令行切换到 d:\tools\mysql\bin 目录
执行安装的命令
mysqld.exe –install MySQL5 –defaults-file=”d:/tools/mysql/my.ini”
执行卸载的命令
mysqld –remove MySQL5

PHP读取 excel(.csv, .xls)文件的方法

常用的用PHP读取EXCEL的方法有以下三种,各自有各自的优缺点。个人推荐用第三种方法,因为它可以跨平台使用。

1. 以.csv格式读取

将.xls转换成.csv的文本格式,然后再用PHP分析这个文件,和PHP分析文本没有什么区别。

优点:跨平台,效率比较高、可以读写。

缺点:只能直接使用.csv的文件,如果经常接受.xls二进制文件的话需要手工转换,不能自动化。一个文件只有一个SHEET。

PHP有自带的分析.csv函数:fgetcsv

array fgetcsv ( int $handle [, int $length [, string $delimiter [, string $enclosure]]] )

handle 一个由 fopen()、popen() 或 fsockopen() 产生的有效文件指针。

length (可选)必须大于 CVS 文件内最长的一行。在 PHP 5 中该参数是可选的。如果忽略(在 PHP 5.0.4 以后的版本中设为 0)该参数的话,那么长度就没有限制,不过可能会影响执行效率。

delimiter (可选)设置字段分界符(只允许一个字符),默认值为逗号。

enclosure (可选)设置字段环绕符(只允许一个字符),默认值为双引号。该参数是在 PHP 4.3.0 中添加的。 和 fgets() 类似,只除了 fgetcsv() 解析读入的行并找出 CSV 格式的字段然后返回一个包含这些字段的数组。

fgetcsv() 出错时返回 FALSE,包括碰到文件结束时。

注意: CSV 文件中的空行将被返回为一个包含有单个 null 字段的数组,不会被当成错误。

当然也可以自己手动分析字符串。

<?php$row = 1;$handle = fopen("test.csv","r");while ($data = fgetcsv($handle, 1000, ",")) { $num = count($data); echo " $num fields in line $row:\n"; $row++; for ($c=0; $c < $num; $c++) { echo $data[$c] . "\n"; }}fclose($handle);?>

 

还可以利用fputcsv函数将行格式化为 CSV 并写入文件指针。

2. ODBC链接数据源

优点:支持多种格式,cvs, xls等。支持读写,使用标准SQL语言,和SQLSERVER、MYSQL数据库几乎完全一样。

缺点:值支持windows服务器

3. PHP自定义类

优点:跨平台。某些类支持写操作。支持.xls二进制文件

常用的类有phpExcelReader、PHPExcel。其中后者支持读写,但是需要php5.2以上版本。

phpExcelReader是专门用来读取文件的。返回一个数组,包含表格的所有内容。

该 class 使用的方法可以参考网站下载回来的压缩档中的 example.php。

不过我下载回来的 (版本 2009-03-30),有两点要注意:

reader.php 中的下面这行要修改

将 require_once ‘Spreadsheet/Excel/Reader/OLERead.php’;

改为 require_once ‘oleread.inc’;

example.php 中

修改 $data->setOutputEncoding(’CP1251′);

为 $data->setOutputEncoding(’CP936′);

修改 nl2br(htmlentities($data->sheets[$sheet][‘cells’][$row][$col]));

为 $table_output[$sheet] .= nl2br(htmlspecialchars($data->sheets[$sheet][‘cells’][$row][$col]));

不然中文会有问题。

繁体的话可以修改为CP950、日文是CP932,具体可参考codepage说明。

修改 $data->read(’jxlrwtest.xls’) 为自己的 excel 文件名,zip 档中附的 jxlrwtest.xls 应该是坏了。

这是下载地址:

phpExcelReader:http://sourceforge.net/projects/phpexcelreader/

PHPExcel:http://www.codeplex.com/PHPExcel/Wiki/View.aspx?title=Documents&referringTitle=Home

 

 

有时写程序时后台要求把大量数据导入数据库中,比如计算机考试成绩的查询、电话簿的数据等一般都是存放在excel中的,这时我们可把数据导出成csv文 件,然后通过以下程序即可在后台批量导入数据到数据库中。

  下面只是主要程序部分:

<?php

//定义获取时间函数
function getmicrotime(){
   list($usec, $sec) = explode(" ",microtime());
   return ((float)$usec + (float)$sec);
}
?>

<?php
$time_start = getmicrotime();
include("db.inc.php");//连接数据库
$db=new testcsv;
?>
<?php
$handle = fopen ("test.csv","r");
$sql="insert into scores(idcard,names,num,sex,nation,score) values(";
while ($data = fgetcsv ($handle, 1000, ",")) {
  $num = count ($data);
  for ($c=0; $c < $num; $c++) {
      if($c==$num-1){$sql=$sql.$data[$c].")";break;}
      $sql=$sql.$data[$c].",";
  }
print "<br>";
echo $sql."<br>";
$db->query($sql);
echo "sql语句执行成功!<br>";
$sql="insert into scores(idcard,names,num,sex,nation,score) values(";
}
fclose ($handle);
$time_end = getmicrotime();
$time = $time_end - $time_start;
echo "程序执行时间:".$time."秒";
?>

 

PHP去空格方法大全

去掉字符串中的空格 str_replace(‘ ‘,”,$cat_name)
$str = ” This line contains\tliberal \r\n use of?? whitespace.\n\n”;
$str = trim($str);// 首先去掉头尾空格
$str = preg_replace(’/\s(?=\s)/’, ‘’, $str);// 接着去掉两个空格以上的
$str = preg_replace(’/[\n\r\t]/’, ‘ ‘, $str);// 最后将非空格替换为一个空格
使用上面的例子可以去掉所有多余的空格。
首先使用TRim()去头尾空格,
接着用preg_replace()去掉重复的空格。
当中的(?=)表示只匹配后面的空格跟随前面的空格的空格。

<?php
$str1="?? tt 七夕快乐!nr"; //这里定义一个字符变量,其中包括"空格","t", 水平制表符,"n",换行符
//这里主要调用trim()函数去除空格等,trim()函数用于去除字符中的""空格,"t"水平制表符"n"换行符,"r"回车符
//"\0"字符串结束符,"xOB"垂直制表符。如果想通过此函数过滤掉特殊的字符,可以制定第二个参数。
echo trim($str1)."<br>";
//这里是去除$str1变量中带有tt的字符
echo trim($str1," tt")."<br>";
//定义变量$str2其中包括"."和空格
$str2="... 情人节快乐!...?? 中国...";
//调用trim()函数去除$str2变量中的空格
echo trim($str2)."<br>";
//ltrim()函数用于去除字符串左边的空格或指定字符串,其默认的字符同trim一样。因为这里指定了第二个参数,
//所以只去除$str2变量中左边的"."
echo ltrim($str2,".")."<br>";
//ltrim()函数用于去除字符串(右)边的空格或指定字符串,其默认的字符同trim一样。因为这里指定了第二个参数,
//所以只去除$str2变量中左边的"."
echo rtrim($str2,".")."<br>";
?>
<?php
echo substr("today is father day!",0)."<br>";
echo substr("today is father day!",6,2)."<br>";//这里只截取字符串中第6字符开始截取,并只截取2个字符
echo substr("today is father day!",-5,5)."<br>";//这里从字符串的倒数第5个字符开始截取,截取5个字符
echo substr("today is father day!",0,-5)."<br>";//这里只截取字符串中的首个字符开始截取,截取到字符串的倒数第5个
echo substr("today is father day!",-5,-1)."<br>";//这里从字符串的倒数第5个字符开始截取,截取倒数第一个字符
?>