1.查看PHP配置文件precision默认12位
2. 格式化可能造成科学计数的数据
if (strpos($d, '+') !== false){ $d['express_no']=sprintf("%.2f", $d); }
1.查看PHP配置文件precision默认12位
2. 格式化可能造成科学计数的数据
if (strpos($d, '+') !== false){ $d['express_no']=sprintf("%.2f", $d); }
昨日,有朋友问我,他将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);
协助用户将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方式就可以了。
win+R,输入”regedit”打开注册表编辑器,搜索”Audiosrv”~用全字匹配,把里面的RequiredPrivileges后面对应的Data数据里面的数据的后两项删除,只保留SeChangeNotifyPrivilege。
注册表修改后进入控制面板——管理工具——进入服务——双击Windows Audio,选择登陆——此帐户——浏览——高级——立即查找——LOCALSERVICE确定——密码清空——Ok!!!!
在系统中依次执行以下命令:
*******************************
INNODB的数据是存储在%datadir%ibdata1 文件中的,FRM文件只保存表的结构和定义。所以需要COPY之
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的方法有以下三种,各自有各自的优缺点。个人推荐用第三种方法,因为它可以跨平台使用。
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_on
改为 require_on
example.php 中
修改 $da
为 $da
修改 nl2br(htmlentities($da
为 $table_output[$sheet] .= nl2br(htmlspecialchars($da
不然中文会有问题。
繁体的话可以修改为CP950、日文是CP932,具体可参考codepage说明。
修改 $da
这是下载地址:
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."秒"; ?>
去掉字符串中的空格 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个字符开始截取,截取倒数第一个字符 ?>