手把手教你在centos下编译安装配置高性能web服务器环境nginx+php(fast-cgi)+mysql等/适合小内存vps使用

本文为实战操作过程的全程记录,采用一台新创建的linode vps(512M内存)环境,操作系统采用centos 6.2,以从源码编译的方式安装配置nginx, php(fast-cgi模式)web环境。

我们的目标:配置一台高性能、安全的web服务器。

继续阅读

centos 6下编译安装php时安装mcrypt支持库

centos6本身不带mcrypt库的支持,手工编译php时,还需要先安装该库,这里有两个途径

1. 使用第三方源实现yum安装,推荐使用RPMforge,在centos下配置该yum源,配置后即可尝试yum install libmcrypt, yum install libmcrypt-devel, yum install mcrypt-devel 安装该库。本人没有实际操作,不确定具体该包的包名。因为如果使用该库,就没必要手工编译php了,直接yum安装好了。配置RPMforge如下

 rpm -ivh http://packages.sw.be/rpmforge-release/rpmforge-release-0.5.2-2.el6.rf.i686.rpm
 yum clean all
 yum makecache

请参看RPMforge, 很不错的centos RPM/yum源

2. 手工编译安装mcrypt库的支持。

这才是本文主要针对的,手工编译。按php官方的说明 http://www.php.net/manual/en/mcrypt.requirements.php

These functions work using » mcrypt. To use it, download libmcrypt-x.x.tar.gz from» http://mcrypt.sourceforge.net/ and follow the included installation instructions

但是http://mcrypt.sourceforge.net/并没有libmcrypt,而是应该到sourceforge上下载,http://sourceforge.net/projects/mcrypt/files/Libmcrypt/2.5.8/

下载,解压,./configure, make,make install, 很常规的步骤。注意libmcrypt需要c++编译器,请保证安装过gcc-c++, 否则请yum install gcc-c++装之

 

centOS 6下通过yum安装php-mssql以使php支持microsoft sql server连接

centos 6下,安装fedoraproject的epel-release源,即可以安装php的mssql模块。

注:epel是fedora开发组为centos开发的附加软件yum源,可以弥补centos上游redhat里缺少的软件包。epel的质量还是相当之高的。

[root@c12 html]# rpm -ivh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-5.noarch.rpm
[root@c12 html]# rpm -ivh http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
[root@c12 html]# yum install php-mssql
[root@c12 html]# /etc/init.d/httpd graceful

完成。

phpinfo中可以看到mssql的信息

mssql模块实际还是FreeTDS,其功能主要是在Liunx下能够访问Sybase及MS SQL,官方网站是:http://www.freetds.org/ 。当然也可以手工编译mssql模块到php中,不过通过yum更简单一点。

关于epel源,参看这里 http://fedoraproject.org/wiki/EPEL/zh-cn

本方法来源于centOS 6更新yum以便可裝php-mssql (http://blog.hubin411.com/2011/10/13/centos-6%e6%9b%b4%e6%96%b0yum%e4%bb%a5%e4%be%bf%e5%8f%af%e8%a3%9dphp-mssql/) 阅读该页面请自备梯子。或参看如下转录的核心部分:

tep 1:
# wget http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-5.noarch.rpm    //取得rpm檔案

step 2:
# rpm -ivh epel-release-6-5.noarch.rpm    //安裝取得的rpm檔案

step 3:
# yum update    //更新yum的資源庫

step 4:
# yum install php-mssql    //安裝php-mssql

step 5:
# service httpd restart    //重啟apache伺服器

php 通过mssql_xx函数读mssql 2005记录, text/ntext字段非常速度慢

使用php写的web程序,从mssql 2005读取一个文章列表,要读取出文章内容,在列表页面里显示出一部分,起先使用:

SELECT top 20 [id],[title],[content], FROM [news] where xxx

这是很自然直接的写法,但是发现运行速度非常的慢,浏览器访问经常要花费好几秒到几十秒才打开页面,慢的时候还会php脚本执行的超时;该表建有必要的索引,数据量只有几万条而已。通过定时追踪发现问题就出在这个语句上,改成如下的形式:

 $sql="SELECT top $pagesize * from 
    (
        SELECT top $top [id],[title]
         ,convert(varchar(30),[updatetime],120) as [updatetime] ,[keyword]
         ,[picture],convert(varchar(500),content) as concent
        FROM [news] ";
 $sql = $sql.$sql_where." 
        order by updatetime desc
    ) as bb order by updatetime asc";

目的是方便分页,不读取出没用的记录。但事实上并没有起色,还是非常慢(这个写法读出来的记录集其实是倒序的,要在读出到数组里后使用array_reverse来反转一下)。而当把sql语句里的content字段去掉不读,就会快如飞一般。就算是改换$sql_where 里的条件也一样的快(这样mssql就不会使用其内部缓存,方便比较语句效率)。

这么看,text型字段实在是mssql里sql语句效率的杀手;可悲的是,这个内容字段是一定要读取的,这是web系统的功能要求,使用缓存是一个方法,但就算使用缓存,在生成缓存时,也一样会非常慢,甚至超时。

几乎是异想天开的念头:拆成多个语句,先读出不带text字段的记录集,再通过php程序遍历id号,然后一条一条的读出text字段,并拼到结果数组里,没想到,居然速度快多了,打开速度维持在0.5秒内,虽然并不够理想。

实在是无法想像,无法理解为什么是这样子!

代码大致如下:

function get_content($id)
{
	global $conn;
	$content='';
	$sql='select convert(varchar(max),content) as content FROM [news] where id='.(int)$id;
	$rs=mssql_query($sql,$conn);
	if($row=mssql_fetch_assoc($rs)){
		$content=$row['content'];
	}
	$content=substr(strip_tags($content),0,500);
	return $content;
}

$top=($page +1)*$pagesize ;
 $sql="SELECT top $pagesize * from (SELECT top $top [id],[title] ,convert(varchar(30),[updatetime],120) as [updatetime] ,[keyword],[picture] FROM [news] "; $sql = $sql.$sql_where." order by updatetime desc) as bb order by updatetime asc";
$rs=mssql_query($sql,$conn) or die($sql);
$data=array();
while($row=mssql_fetch_assoc($rs)){
	$row=$row+array(
		'content' => get_content($row['id'])
		);

	$data[]=$row;
}
$data=array_reverse($data);

php函数代码:以表格形式输出二维数组

已于2012-01-16更新:对于元素为数组的,也以表格输出(否则将数组子元素显示为array)

直接上代码

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>以表格形式输出二维数组</title>
</head>

<body>
<?php
$comment[100]=array('id'=>100,'parent'=>0,'content'=>'AAAAAAAAAA');
$comment[101]=array('id'=>101,'parent'=>100,'content'=>'BBBBBBBBB');
$comment[102]=array('id'=>102,'parent'=>100,'content'=>'CCCCCCCCCC');
$comment[103]=array('id'=>103,'parent'=>0,'content'=>'DDDDDDDDDDd');
$comment[104]=array('id'=>104,'parent'=>102,'content'=>'EEEEEEEE');
$comment[105]=array('id'=>105,'parent'=>101,'content'=>'FFFFFFFFF');
$comment[106]=array('id'=>106,'parent'=>0,'content'=>'GGGGGGGG');
$comment[107]=array('id'=>107,'parent'=>0,'content'=>'HHHHHHHHH');
$comment[108]=array('id'=>108,'parent'=>101,'content'=>'IIIIIIIIIIII');
$comment[109]=array('id'=>109,'parent'=>105,'content'=>'JJJJJJJJJJ');
$comment[110]=array('id'=>110,'parent'=>103,'content'=>'KKKKKKKKKK');
$comment[111]=array('id'=>111,'parent'=>108,'content'=>'LLLLLLLLL');
$comment[112]=array('id'=>112,'parent'=>105,'content'=>'MMMMMMMMMM');

$data=$comment;

array_table_view($data);

function array_table_view($data)
{
?>
<table width="95%" border="1" cellspacing="0" cellpadding="4"><?php 
    if(!sizeof($data)){
?>
  <tr>
    <td>empty array.</td>
  </tr><?php 
    }else{
        foreach($data as $item){
?>
  <tr><?php 
          foreach($item as $key => $val){ ?>
    <th><?php echo $key; ?></th><?php 
            } ?>
  </tr>
<?php 
            break;
        }

        foreach($data as $item){

?>
  <tr><?php 
          foreach($item as $key => $val){ ?>
    <td><?php 
        if(is_array($val)){
            array_table_view($val);
        }else{
            echo $val;
        }
        ?></td><?php 
            } ?>
  </tr>
<?php
        }
    } ?>
</table>
<?php
}
?>
</body>
</html>

代码下载 array_table_view

代码下载 (请“复制-粘贴-保存”以上代码)

php安装xdebug后,让var_dump()函数输出完整的变量内容

php开发环境里,安装了xdebug模块后,var_dump()输出的结果将比较易于查看,但默认情况下,var_dump() 输出的结果将有所变化:过多的数组元素不再显示,字符串变量将只显示前N个字符,较深的数组元素也被显示成省略号。这点会带来一些不便,我们修改配置文件,设置这些。

在php.ini里的xdebug节点中,加入如下

xdebug.var_display_max_children=128
xdebug.var_display_max_data=512
xdebug.var_display_max_depth=5

含义从名字上看就可看懂。

其实这里有三条配置,正好与本文上述的三点“变化”一一对应嘀 ^..^

从phpinfo()里的xdebug节点里可以看到更多的配置变量,多半也是可以通过php.ini修改的

关于php打开文件的写法原因之辨误

这是对一种错误表述的评论,错误见文后部分

"windows系统是直接输入文件的绝对路径需要这种方式"e:\\aaa.txt",注意是两个反斜杠,一个反斜杠的话就错了"这个说法是误导,或有 误导之嫌。windows系统表示文件路径时,使用一个反斜杠,而反斜杠在很多语言里表示转义之用,所以要用两个反斜杠;路径的字符串在程序运行过程中 (内存里),实际还是一个。

如果在php里,这样的用单引号括起路径字符串,如下这样是这完全正确的 readfile('e:\Downloads\t.txt'); 而readfile("e:\Downloads\t.txt");这样写就错了。不过事实上,在win32版的php里,这样写也是对的 readfile("e:\Downloads\z.txt"); 可能是反斜杠后是一个非转义字符,php把此\解析为常规反斜杠。

php里,用单引号括起路径字符串,readfile('e:\Downloads\t.txt');是这完全正确的,而readfile("e: \Downloads\t.txt");这样写就错了。不过事实上,在win32版的php里,这样写也是对的 readfile("e:\Downloads\z.txt"); 可能是反斜杠后是一个非转义字符,php把此\解析为常规反斜杠(但反对这样使用)。

——以上是对新浪微博里的一条微博做的回复,该条微博如下:http://weibo.com/1767100271/xDUCLyFYM【fopen函数的使用的几种方式】 //第一种使用fopen的方式,windows系统是直接输入文件的绝对路径需要这种方式"e:\\aaa.txt",注意是两个反斜杠,一个反斜杠的话就错了 //

原发微者没有回应,那就这管他了,把该条回复转到这里。

php读取调用远程文件时报错Name or service not known/fedora linux下

不知道什么时候,fedora 14上的php读取http远程文件时就报错,像下面这样

Warning: file_get_contents() [function.file-get-contents]: php_network_getaddresses: getaddrinfo failed: Name or service not known in /home/lib/www/html/myworks/dn2ip/dn2ip.php on line 27

file(),fopen()等函数也有类似情况,如果直接指定ip地址连接是没有问题的,使用php cli也是正常的。另外gethostbyname函数也有问题,$ip = gethostbyname('www.baidu.com'); var_dump($ip); 执行结果是浏览器上输出 www.baidu.com,根本没有解析域名,而只把参数传出来,也没有报错,包括warning级别的错误也没有。

多方查找都没有找到原因,包括在英文站点上搜索也没找到可以解决问题的方案。网上大体有这些方案:检查命令行执行wget 等是否正常执行,检查主机dns服务器设置,重启apache等,但我的fedora是笔记本上的系统,不知道重启了多少次!

实在是很郁闷。想起完全卸载php,甚至连apache也卸载,然后清理一下相关残留文件,再重启重新安装试试。

yum erase php后,重启还有如下一些php包没的卸载,

[root@fsc ~]# rpm -qa |grep php
php-cli-5.3.6-1.fc14.i686
php-gd-5.3.6-1.fc14.i686
php-pdo-5.3.6-1.fc14.i686
php-mbstring-5.3.6-1.fc14.i686
php-xml-5.3.6-1.fc14.i686
php-mysql-5.3.6-1.fc14.i686
php-common-5.3.6-1.fc14.i686

[root@fsc ~]# rpm -ev php-cli php-gd php-pdo php-mbstring php-xml php-mysql php-common
warning: /etc/php.ini saved as /etc/php.ini.rpmsave

php配置文件曾经修改过,与rpm包里的原始版本不一致,所以被rpm自动备份下来了,重新安装php时很有参考价值的。

没有重启httpd,执行刚才的测试文件,发现居然可以解析域名了!那就不用重启再安装php了,直接yum install php,再安装另外几个包,yum install php-mbstring php-xml php-gd ,重启apache,完成!

这个非常怪异的问题,困扰了好些天,这次又莫名其妙的好了。原因不清楚。

 

-------------错误消息文本记录-------------------------------------

执行如下代码

$host="ip138.com";
var_dump(gethostbyname($host));

$url="http://www.baidu.com/";
$html=file_get_contents($url);

完整的错误消息,供参考(使用了xdebug,输出比php默认的消息更友好一点)

string 'ip138.com' (length=9)

 

( ! ) Warning: file_get_contents() [function.file-get-contents]: php_network_getaddresses: getaddrinfo failed: Name or service not known in /home/lib/www/html/myworks/dn2ip/dn2ip.php on line 27
Call Stack
# Time Memory Function Location
1 0.0015 331060 {main}( ) ../dn2ip.php:0
2 0.0105 331556 file_get_contents ( ) ../dn2ip.php:27

 

( ! ) Warning: file_get_contents(http://www.baidu.com/) [function.file-get-contents]: failed to open stream: php_network_getaddresses: getaddrinfo failed: Name or service not known in /home/lib/www/html/myworks/dn2ip/dn2ip.php on line 27
Call Stack
# Time Memory Function Location
1 0.0015 331060 {main}( ) ../dn2ip.php:0
2 0.0105 331556 file_get_contents ( ) ../dn2ip.php:27
string 'http://www.baidu.com/' (length=21)

借用php脚本快速实现php站点数据迁移

一个朋友的网站,换web服务器,要我帮忙。朋友的网站原本在我的虚拟主机空间上,但嫌网通访问速度慢,自己买了个比较快一点的。要换的也还是虚拟主机,而且是超简单的那种,只有一个基于web的简单后台,文件管理都很不完善,连zip压缩解压缩的功能没有,也没有直接下载远程文件并解压的功能,更不用说ssh了。对于这样的虚拟主机最怕就是ftp服务器再有问题。

然而最怕的事情还是来了。

经常在虚拟主机上见到微软的msftp,那个烂啊,都没有可以形容的词了。上传或下载文件的过程中,会莫名其妙的连接中断,要重新连接,而且更可恶的是服务器在断开连接时,连个消息都不给,直接断掉了,ftp客户端还在等待服务器上回应,结果是超时,然后客户端才知道是连接断掉了。有时在上传或者下载一个队列时,上传了一个文件,在进行下一个时,提示消息“传输失败”,然后客户会跳过进行再下一下,再下一个......当然也传问是失败。这个最令人无法忍受的事情,只能强制断开ftp客户端,再重新传输队列。十分的没有效率,而且影响心情。这次的问题跟这个类似,但似乎这个服务器不是windows的,它使用的ftp服务器消息中声称是ProFTPD,看来应该是linux,而虚拟主机服务器的管理员能把linux也搞成这样,实在对不起linux. 以前还从来没有见过配置得这么烂的linux + ftpd!

然而骂归骂,事情还是得做。这次迁移的其实一个很小的网站,只有一千多个文件,跟一个mysql数据库。使用filezilla传输,已经设置文件覆盖规则,以免传输一半被服务器单方面断开、而导致文件重传时的“文件覆盖提醒”。但还是实在无法忍受,传了半个小时才传上了200多个文件,失败的队列文件数目已经涨到300多个,看来照这样的速度,要传不知道多久了,还得多次重置失败队列。于 是想需要用另外的方法来实现,而不能使用ftp了。最简单的php,它本身有文件管理的功能,网上有很多基于php的文件管理工具,下载了几个试用,要么功能太差,没有zip功能,或者文件太多,比朋友的这个小网站文件还多。 因为之前搞过一次php写的zip文件解压缩脚本,不过是使用别人写的。而php本身有从外部站点上下载文件的功能,像fopen, file_get_contents等函数都可以很容易实现。那与其找php文件管理工具,还不如写个简单的程序在目标主机上运行。程序非常简单:

<?php
$foo=__FILE__;
$bar=pathinfo($foo);
$file_path=$bar['dirname'].'/xxx.zip';
$data=file_get_contents("http://xxx.path8.net/xxx/xxx.zip");
$foo=file_put_contents($file_path,$data);
var_dump($foo);
?>

我的虚拟主机好歹有个ssh,可以很方便的压缩所有文件,并通过http访问。上面这段php脚本就可以实现从我的网站上通过http访问,并把整站的压缩文件下载到目标主机上(这里要注意目标主机上不否有写入权限,可以把目录设置777,迁移完成后再改回去)。然后,再使用一个zip解压工具,当然也要是php脚本编写的,网上有这个一个,有简单的页面设计,还比较直观,使用也较简单(附于本文后)。把这个工具也传到目标主机上,跟整站zip压缩包放在同一目录下,使用它解压缩zip,非常快,几秒钟就完成了,如果是使用ftp传输,那真不知道还要几个小时才能完成。

基于php的zip文件解压缩工具: unzip.php

fedora linux下php调试利器xdebug 2.1.0下载/fedora13,14测试通过

核心内容:

笔者曾写过一篇fedora linux apache/php下安装配置xdebug,记录了fedora13下安装xdebug 2.1.0的过程。当时在编译的二进制.so模块可以直接在fedora14下使用,如不想自己编译、且信得过笔者的同学们,请直接下载本文件,或者参考上文自行编译:

下载安装文件xdebug-module-linux-fedora13-14

安装方法:

1. 复制文件xdebug.so/usr/lib/php/modules/

2. 复制文件xdebug.ini/etc/php.d/

3. 重启apache

___________以下是个人安装过程,仅供参考________________

笔者曾写过一篇

fedora linux apache/php下安装配置xdebug

当时是在fedora13下参考xdebug官方的说明文档自行编译,然后把编译过程记下来的。现在fedora14已经发布几个月,当然是覆盖安装了。今天需要写个小东西,php自带的调试消息实在比较简陋,于是想起安装个xdebug,首先想到的yum里找不到,于上网上搜索怎么yum安装,结果发现打开的是这篇自己几个月前写的文章。

难道又要重新编译吗?太没效率了!

于是想是否不用重新编译、而是直接使用以前编译的.so模块呢?试试,不行再编译。

参看文章中之前的记录,还要安装两个工具:phpize与php-config,从它们文件名看,应该是编译过程上用的,现在不用编译,不安装试试。

安装过程:把编译目录里./moduls/xdebug.so复制到/usr/lib/php/modules/, 再写入xdebug配置信息上到文件/etc/php.d/xdebug.ini

[root@fsc prx]# echo 'zend_extension=/usr/lib/php/modules/xdebug.so
> [Xdebug]
> xdebug.profiler_enable=on
> /etc/php.d/xdebug.ini' >/etc/php.d/xdebug.ini

重启apache,结果没有html格式的php消息。运行<?php phpinof();?> 发现xdebug是成功加载了,经验判断是没有打开php的html格式错误显示所致。看之前写文章里,有这一点 的,只是写在后面,看来这篇文章的“读者体验”(从“用户体验”生造来的词~~)不怎么好,连自己看都感觉到不方便! 有必要修改一下。

运行下面代码,把html_errors打开。

[root@fsc prx]# echo 'html_errors=on'>>/etc/php.d/xdebug.ini

再次重启apache,完成。

抓个图来纪念一下: