php扩展中使用动态链接库

整理下大概知识点:

  • C的编译、链接、安装过程
  • autoconf基本语法
  • config.m4中的PHP_XX系列宏(在aclocal.m4中)

具体例子:
以使用taglib(https://github.com/taglib/taglib)编写一个操作mp3的id3标签的PHP扩展为例,按照默认编译安装taglib,头文件在/usr/local/include/taglib/tag_c.h,共享库文件在/usr/local/lib/libtag_c.so
我用到了taglib这个库的c语言版,安装后taglib-config –libs命令得到的是它的c++版的库,所以要在config.m4里自己写。

config.m4的关键代码:

PHP_ARG_WITH(taglib, for taglib support, [  --with-taglib             Include taglib support])

if test "$PHP_TAGLIB" != "no"; then

SEARCH_PATH="/usr/local /usr"
SEARCH_FOR="/include/taglib/tag_c.h"
if test -r $PHP_TAGLIB/$SEARCH_FOR; then # path given as parameter
TAGLIB_DIR=$PHP_TAGLIB
else # search default path list
AC_MSG_CHECKING([for taglib files in default path])
for i in $SEARCH_PATH ; do
if test -r $i/$SEARCH_FOR; then
TAGLIB_DIR=$i
AC_MSG_RESULT(found in $i)
fi
done
fi

if test -z "$TAGLIB_DIR"; then
AC_MSG_RESULT([not found])
AC_MSG_ERROR([Please reinstall the taglib distribution])
fi

PHP_ADD_INCLUDE($TAGLIB_DIR/include)

dnl #库文件 libtag_c.so
LIBNAME=tag_c

dnl #库函数
LIBSYMBOL=taglib_file_tag

dnl 第三个参数要设置成EXTRA_LDFLAGS时,链接的时候才会加上 -ltag_c 参数...这个PHP_ADD_LIBRARY_WITH_PATH的原型还没看明白...
dnl 貌似还有好几种解决方案,PHP_EVAL_LIBLINE?
PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $TAGLIB_DIR/lib, EXTRA_LDFLAGS)

PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
[
AC_DEFINE(HAVE_TAGLIB,1,[ ])
],[
AC_MSG_ERROR()
],[
-L$TAGLIB_DIR/lib -lm
])

PHP_NEW_EXTENSION(php_taglib, php_taglib.c, $ext_shared)
PHP_SUBST(TAGLIB_SHARED_LIBADD)
fi

接下来是

configure [--with-taglib[=/path]]
make
make install

顺利的话可以到php.ini里面加载扩展。

期间可能会出现tag_c.h文件找不到的问题,注意下头文件的路径是由 config.m4 文件里的 PHP_ADD_INCLUDE($TAGLIB_DIR/include) 加上 扩展源码里 #include “taglib/tag_c.h” 组成的。

然后,即使扩展编译安装成功,php_info()里看到加载成功,但是cli执行php 扩展测试代码的时候出现 symbol lookup error的话,应该是扩展链接的时候没有找到libtag_c.so, 注意下PHP_ADD_LIBRARY_WITH_PATH() 的第三个参数即可。

观片一部《暮光之城:破晓下》

很久很久没有写电影日志了。
电影字幕的最后说,‘以本系列电影的终篇,纪念逝去五年的时光’,从大二第一次看暮光系列,到今天,原来五年就这样过去了。
记得一开始看的时候,对电影里面很多新鲜的东西都着迷不已:Kristen Stewart迷人内敛的神态、吸血家族的各种特异功能、狼人的威猛、校园的各种小说般的故事…,接下来,却不知是因为年龄还是因为其他的什么,对中间的几部感觉都不那么好,然后,到了今天看最后一部,心情却如此的难以平静。五年的时间,逝去的绝对不仅仅是时间啊:很多很多的人,或许这辈子都不会再见到!很多很多的事,或许只能在回忆里发生了!很多很多的机会,或许我只能感叹了!
我不知道是不是以后人生的每个五年都能有如此多的回忆。但我肯定以后再也不会有如此轻松且兼带酸涩和甜蜜的感觉了。我们会渐渐的被残酷的现实浸泡得麻木。
电影的最后,Bella发现可以利用自己的能力对Edward去掉自己所有的防护,然后说了句:Now You know, nobody has ever loved andybody as much as I love you. 原来,最爱一个人并不需要什么,而是对他无条件的放下所有的防备担心忧虑…
以此简单的文字纪念逝去的大学四年,I miss the times, and the guys…

观片一部《天注定》

我可以感受我的思想和我的灵魂正在一点一点的死去。
面对生活里的种种,我变得越来越“正常”。我会因为想到没钱而感到压力巨大,会因为想到利益关系去和别人打交道,会因为被别人疏远而感到害怕。我就像一匹渐渐被生活驯服的野马,灵魂也慢慢的因为肉体的妥协而屈服。我再也找不回思维由兴而歌,灵魂随风起舞的感觉。
瞬时间,仿佛一切都已天注定。
几年来,职业的道路上我一直在为充实自己而努力,尽管我选择了自己喜欢的职业,但我却忽略了人生中其它重要的东西,比如亲人,比如朋友,比如爱。很多时候,我很容易被一篇技术文章刺激到满身动力和理想,而对生活中的很多的感动却麻木了。我很少打电话和朋友甚至亲人聊天,因为我不知道该说些什么,因为我还没学会关心。我很少对别人敞开心腹,因为我一直以为别人会知道的,因为我一直不知道怎样接受别人。
贾樟柯的这部电影是如此的平淡,让我感到只不过是把真实的生活稍加剪辑而已。但是它居然真实的就像你身边的故事,甚至就是某一部分的你的写照。生活在这样一个时代,当我们的坚持不被正视,当我们的灵魂被逼出卖,当我们的梦想逐渐模糊,如果在再不去感动,再不去珍惜,再不去爱,我怕惭愧也洗不清我们的罪恶、弥补不了我们的遗憾。

近况

最近身边发生了很多事,自己有了一些新的想法。

先说说自己吧,无论技术还是处世,仍未得到自己想要那种改变。借口依然很多,决心还是不够。虽然没人知道自己在做改变–也就不会有人鼓励–但还是希望自己能跨过这道坎。

然后年纪也不小了,开始被催结婚。买房这个问题自然避免不了。曾几何时,我想过一定要买房才结婚而自己又无能为力的话情愿不结婚,但是现在想想没有一个自己的家真的很不甘心,看来这个压力并不是来自于谁,而是一种需要。这或许是二十年没有一个真正的家造成的,我所需要的其实只是大多数人所有的一份归属感。

一个好友的奶奶最近仙去,我猛的想到自己的祖辈。有多久没和他们见过面打过电话了?我想,到了那个阶段,他们对生活其实已经没有什么要求了,唯一的要求可能就是能够看着自己的子孙快乐的生活着,能多见下面,能多说几句……爷爷的离去到现在十年了,我还没缓过来,每次回到家乡那间熟悉的房子,都会让我因为陌生而感到喘不过气来。那个我曾作为主人的地方,少了一个身影和一把声音,便让我的位置和感觉再难重现。所以面对现今自己仍有幸陪伴的几个老人家,我心里有说不出的愧疚和恐惧。

一个婚纱照都拍了的朋友去了打胎。不讨论原因,两个人家长见了,床上了,婚纱照都拍了,到了这一步,而且恰是到了这里居然散了,我很震惊。如果觉得相处有问题就不应该走这一步,两个人相处,硬生生的跨过路上的障碍,只会让以后的矛盾更深。或许爱情根本就无规可循,又或许爱情早已变味。

一个一起创业打拼的同事要离职。不知道他是耐不住寂寞还是看不到希望。这应该是一个转折点,无论是对他,对公司,还是对我。我会重新评估这个项目和自己,尽快在接下来的一个月内做出决定。重新审视过去一年的付出。可以说这是第一个自己在产品层面参与的项目,发现自己想问题的深度不够,眼界过于狭隘,思维方式还不够系统。主要表现在有些问题想得太轻浮即兴;有时候喜欢钻牛角尖;提出的解决方案并没有经过自己的推敲论证,也是即兴的或者参考的居多;发表意见时传达不清晰。

种种一切,让我觉得身边很不安全,生命的每一步,还是需要自己踏实地走。

JS+PHP实现图片裁剪

用到几个插件:
1.Jquery上传插件: Fine Uploader
2.JS图片裁剪:imgAreaSelect
3.PHP上传/PHP GD库

原理:
PHP的imagecopy()函数可以将一张图片的一部分复制到另一张图片中,而imgAreaSelect可以获得用户裁剪图片的坐标及高宽,利用imgAreaSelect将需裁剪的x轴起点、y轴起点、宽、高四个参数传给PHP,PHP完成复制图片工作。

要点:
1.图片预览/截图。如果浏览器兼容FileApi ,问题就简单多,直接读取本地文件完成预览、获得截图的坐标和宽高等参数。考虑到IE10之前都不支持的情况,可以利用AJAX上传的方法,先将图片传到服务器,然后读取出来进行预览和裁剪。
2.PHP处理图片。PHP进行图片复制需要获得以下几个参数:原图片路径、x轴起点、y轴起点、宽、高。如果服务器支持ImageMagick扩展,可以直接利用Imagick::cropImage函数进行裁剪。不支持的话,可以采用最原始的方法,先用imagecreatetruecolor函数生成一副和截图区域等宽等高的空白图片,再用imagecopy将原图的截图复制过来。

关键代码:
1.PHP的处理


class Pic{
	public $picInfo;

	public function get_pic_info( $file ){
		if( ($im = getimagesize($file)) == false ){
			$this->error = "$file is not a valid image file";
			return false;
		}

		$fileInfo = pathinfo( $file );
		$info = array(
			'width'	=> $im[0],
			'height'=> $im[1],
			'name'	=> $fileInfo['filename'],
			'type'	=> strtolower($fileInfo['extension']),
			'mime'	=> $im['mime'],
			'path'	=> $fileInfo['dirname'].'/'
			);
		$this->picInfo = $info;
		//return $info;
      	}

	/**
	 * 截取图片
	 * 
	 * @param $source_file 源文件地址
	 * @param $x 截取x轴起点
	 * @param $y 截取y轴起点
	 * @param $width 截取宽度
	 * @param $height 截取高度
	 * @return bool | resource
	 * @since v1.0
	 * @create 2012-12-20
	 */
	public function cut( $source_file, $x, $y, $width, $height ){
		$this->get_pic_info( $source_file );	
		$info = $this->picInfo;
		if( !$info ){
			$this->error = "failed to get $source_file";
			return false;
		}
		// 判断截取是否有效
		if( $x>=$info['width'] || $y>=$info['height'] || $width>$info['width'] || $height>$info['height'] || !$width || !$height ){
			$this->error = "invalid crop params";
			return false;
		}

		$type = $info['type'] == 'jpg' ? 'jpeg' : $info['type'];
		// 根据源文件类型创建对象
		$func = "imagecreatefrom".$type;
		if( ($im = $func( $source_file )) ==  false ){
			$this->error = "create gd resource failed";
			return false;		
		}

		// 创建一个目标文件
		$dst = imagecreatetruecolor( $width, $height );
		// 设定背景色为白色
		$color = imagecolorallocatealpha($dst, 255, 255, 255, 0);	
		imagefill( $dst, 0, 0, $color );
		// 复制源文件的指定区域
		if( !imagecopy( $dst, $im, 0, 0, $x, $y, $width, $height ) ){
			$this->error = "copy image fail";
			return false;
		}

		// 根据文件类型保存对象
		$func = "image".$type;

		ob_start();
		if( $type=='jpeg' ){
			$func( $dst, NULL, 85);
		}else{
			$func( $dst, NULL ); 
		}
		$newIm = ob_get_clean();

		if( !$newIm ){
			$this->error = "create image fail";
			return false;
		}
		imagedestroy( $dst );

		return $newIm;
	}
}

2. JS的处理:


var picEditor;
var imguploader = $(‘#fileuploadbtn’).fineUploader({
request: {
endpoint: ‘upload.php’,
},validation: {
allowedExtensions: [‘jpeg’, ‘jpg’, ‘png’, ‘gif’],
sizeLimit: 2097152
},
text: {
uploadButton: ‘点击上传’
},
dragAndDrop: {
extraDropzones:[$(‘#dropzone’)],
hideDropzones: true,
disableDefaultDropzone: false,
},
template: ‘

‘ +

{uploadButtonText}

‘ +

    ‘ +


    }).on(‘complete’, function(event, id, filename, json){
    // ajax上传返回json数据
    if (json.status) {
    //初始化js裁剪插件,设置参数请参看官网文档
    picEditor = $(‘#topfileupload img’).imgAreaSelect({
    handles: true,
    aspectRatio: ‘{$aspectRatio}’,
    instance: true,
    imageHeight: json.height,
    imageWidth: json.width,
    classPrefix: ‘imgareaselect’,
    onSelectEnd: function(img, sel){
    change_preview(sel);
    }
    });
    } else {
    if( json.info ) alert(‘上传失败:’+json.info);
    }
    }).on(‘error’,function(id,fileName,error){
    alert(‘只允许上传小于2M的图片’);
    });

    // 将裁剪参数传给PHP处理
    $(‘#btnSubmit’).click(function(){
    if( !picEditor ){
    $.bigpu.alert(‘请先上传图片’);
    return;
    }
    var s = picEditor.getSelection();
    var f = $(‘#topfileupload img’).attr(‘src’);
    $.ajax({
    url: ‘crop.php’,
    data: ‘file=’+f+’&x=’+s.x1+’&y=’+s.y1+’&width=’+s.width+’&height=’+s.height,
    dataType: ‘json’,
    success: function(json){
    if( json.status ){
    picEditor.remove();
    // PHP完成任务,返回Json供Js回调
    pic_editor_success( json );
    }else{
    alert(‘图片保存失败%>_<%。'); } } }); }) // 截图预览 function change_preview(selection){ //预览宽高 var prevWidth = 100; var prevHeight = 100; if ( selection.width == 0 || selection.height == 0 || !prevWidth || !prevHeight ) { return false;} // 缩放比例 var scaleX = prevWidth / selection.width; var scaleY = prevHeight / selection.height; // 预览定位 $('#imgPreview').css({ width: Math.round(scaleX * picInfo['oldWidth']) + 'px', height: Math.round(scaleY * picInfo['oldHeight']) + 'px', marginLeft: '-' + Math.round(scaleX * selection.x1) + 'px', marginTop: '-' + Math.round(scaleY * selection.y1) + 'px' }); // 记录位置 $('#x').val( selection.x1 ); $('#y').val( selection.y1 ); $('#w').val( selection.width ); $('#h').val( selection.height ); return; } [/javascript]

    20121104

    一个人的躺着,床头那本小说翻了两页便放下了,内心无论如何也难以平静。心里无比的渴望平静,把这段时间萦绕在心头徘徊在脑海的种种烦恼、琐事、不安、恐惧……通通一并沉淀下来。
    秋天的到来,总会莫名其妙的增加我的伤感。有时候我甚至不知道这伤感来自那里,一旦走到外面,视野中的人和物耳朵听到的声音甚至偶然迎面吹来的秋风,似乎都在提醒我,到时候忧伤了。
    这个二十四快满,二十五将到的前夕,年龄的数字游戏带给我的压力前所未有的大。是游戏都可以放弃认输,但是是玩游戏的人都会像想当赢家。当发现自己是时候去抗家庭婚姻事业这些东西的时候,就越觉得这个游戏不能输。当这个数字默默的增加,就越明白自己手头上的筹码不足。

    20120704

    网站迁移到VPS。

    前几天的事了。

    时间过得很快也很忙,生活过得很快乐也很痛苦。

     

    20120129

    春节假期就这样过去了,七天里几乎有六天在床上赖着,这不是件值得开心的事,更不是件好事。
    过年没回家乡,是有史以来第一次。其中夹带着很多的因素,假期短、天气冷、怕坐车、怕去拜年、怕面对各式亲戚朋友……我也不知道到底哪个才是牵住我的原因,只知道现在过年的感觉越来越少心情越来越沉重。
    这个年过得真的有点压抑,即使面对着最亲的亲人,我也无法得到自在和幸福的感觉,取而代之的是压抑拘谨内疚。我感到与外面世界那层隔膜似乎越来越厚,而且前所未有的真实。
    昨天终于把安娜卡列琳娜看完了。大体上还是能看明白的,但由于文化环境时代背景等原因,加上自己修养不够,还是有些东西理解不了,只能说是把书翻了一遍。其中印象最深的是很多的心理描写,很多的自言自语,给我的感觉在某种程度上似乎几个主要人物都比较孤独:安娜,她哥,她嫂子,伏伦斯基,列文。
    列文最后那个茅塞顿开有点牵强,他之前思考了那么久的,曾为之迷茫挣扎甚至轻生的人生意义,居然凭一个普通农奴的一句话就解脱了。之前一天他还想着自杀的…更何况他一直不太信教,也没经历大悲大喜,怎么一下子改变的这么快…
    另外我真的感觉不到安娜和伏伦斯基之间有爱情的存在,一方面,我觉得伏伦斯基这人比较轻佻虚伪,可能开头他和吉娣那段给了我一个很不好的印象,以安娜的魅力和修养,我觉得她更应该爱上列文那类型或者更好的…另一方面他们两一起后的生活好像一直比较平淡(除了他们在社交界的影响),没有什么刻骨铭心的悲伤或快乐,至少我是没有感受出来,可能时代不一样,也可能是基于前一原因我没办法感受。安娜最后的死也比较突然,他们不是第一次吵架,安娜也不是第一次觉得痛苦,我还以为(因为一开始就有人剧透说安娜最后卧轨)会在发生悲痛欲绝的事,如他儿子挂了、伏伦斯基为保名誉而放弃了她、或者后来她发现她居然爱上了已婚的列文,等等……不知道为什么这么快这么轻易就做决定。
    总的来说,小说超出我的正常理解范围,但是有时却能找到共鸣。唯一能解释的是因为时代不同,很多当时不可思议不可原谅的行为,在今天看来已经很普遍了,比如劈腿,比如离婚,但是很多在那个时代很正当的勾当在今天看来却又很不可思议。
    接下来想换换口味,看些心理学或哲学上面的书。
    想买个kindle fire。
    想找个伴。

    yardvps配置手记

    I.新建用户(test):

    购买vps时只有root一个用户,ubuntu上习惯用普通用户:

    1、输入用户管理的命令,新建用户(以test为例):

    useradd test

    修改 test 用户的密码:

    passwd test

    2、将新用户添加到管理组:

    gpasswd -a test admin

    3、给 test 用户创建自己的目录:

    cd /home
    
    	mkdir test
    
    	chown test /home/test

    4、添加sudoer权限:

    vim /etc/sudoers文件。找到这一 行:”root ALL=(ALL) ALL”在起下面添加”xxx ALL=(ALL) ALL”(这里的xxx是你的用户名),保存退出.

    5、指定shell:

    vim /etc/passwd,找到相应的用户,指定shell路径:/bin/bash

    II.OPENVPN:

    1、安装:

    sudo apt-get installl openvpn

    2、准备和安装:

    sudo cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0/ /etc/openvpn/
    	cd /etc/openvpn/2.0/
    	sudo vim vars
    	su (切换到root,用普通用户老出错)
    	source vars
    	./clean-all
    	./build-ca
    	./build-key-server server
    	./build-key client1
    	./build-dh

    3、配置:

    sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn
    	cd /etc/openvpn
    	sudo gzip -d server.conf.gz
    	sudo vim server.conf

    4、配置nat转发:

    sudo bash
    	sudo echo 1 > /proc/sys/net/ipv4/ip_forward
    	sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 
    
    -j MASQUERADE
    	
    	iptables-save > /etc/iptables.up.rules
    	sudo vim /etc/network/interfaces
    	最后添加:
    	pre-up iptables-restore < /etc/iptables.up.rules

    If you made a mistake and want to remove all rules from IPTables:

    sudo iptables -F -t nat

    III. Apache:

    1、安装:

    下载源码包,解压。

    cd httpd-xxx
    	sudo ./configure --prefix=/usr/local/apache2 –-enable-mem-cache –-enable-vhost-alias --enable-cache -with-ssl --enable-ssl --enable-so --enable-rewrite --enable-mime-magic
    	sudo make
    	sudo make install

    IV. Mysql:

    sudo apt-get install cmake libncurses5-dev build-essential g++ sysv-rc-conf
    (centos6 : yum install bison gcc gcc-c++ autoconf automake zlib* libxml* ncurses-devel libtool-ltdl-devel*)
    	sudo cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/usr/local/mysql/data -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DMYSQL_UNIX_ADDR=/tmp/mysqld.sock
    	sudo make
    	sudo make install
    	cd /usr/local/mysql
    	sudo chown -R mysql .
    	sudo chgrp -R mysql .
    	sudo ./mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --no-defaults
    	sudo cp /usr/local/mysql/support-files/my-medium.cnf /etc/mysql/my.cnf
    	sudo vim /etc/mysql/my.cnf
    	在[mysqld]下添加:
    	basedir=/usr/local/mysql
    	datadir=/usr/local/mysql/data
    	user=mysql
    
    	sudo /usr/local/mysql/support-files/mysql.server start

    (如果能启动成功,则说明配置成功)

    配置开机启动:

    cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysql
    	sudo sysv-rc-conf

    找到【mysql】一栏,选定【3】【4】【5】这三列

    PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !

    To do so, start the server, then issue the following commands:

    /usr/local/mysql/bin/mysqladmin -u root password 'new-password'

    /usr/local/mysql/bin/mysqladmin -u root -h veapon.com password 'new-password'

    V. PHP:

    sudo apt-get install -y libltdl-dev libssl-dev sendmail libjpeg8 libjpeg8-dev libpng12-0  libpng12-dev libxml2-dev libcurl4-openssl-dev libmcrypt-dev
    	sudo ln -s /usr/lib/x86_64-linux-gnu/libpng* /usr/lib/
    	cd php-xxx
    	sudo ./configure --prefix=/usr/local/php --with-curl --with-mcrypt --enable-mbstring --enable-pdo --with-openssl --with-imap-ssl --with-gd --with-jpeg-dir=/usr/lib/ --with-png-dir=/usr/lib/ --enable-exif --enable-zip --with-apxs2=/usr/local/apache2/bin/apxs --with-mysql=/usr/local/mysql
    	sudo make
    	sudo make install
    	sudo cp php.ini-development /usr/local/php/lib/php.ini
    	sudo vim /usr/local/apache2/conf/httpd.conf

    适当位置加入:

    AddType application/x-httpd-php .php

    安装mysqli扩展

    sudo apt-get install autoconf
    	cd /path/to/php-source/ext/mysqli
            sudo /usr/local/php/bin/phpize
    	sudo ./configure --prefix=/usr/local/php/include/php/ext/mysqli --with-php-config=/usr/local/php/bin/php-config --with-mysqli=/usr/local/mysql/bin/mysql_config
    	sudo vim /usr/local/php/lib/php.ini

    加入:

    extension=/usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/mysqli.so

    VI. subversion:

    sudo apt-get install subversion subversion-tools
    	sudo mkdir /var/svn/test
    	sudo svnadmin create /var/svn

    修改配置:

    sudo vim /var/svn/test/conf/svnserver.conf
    	#匿名访问的权限,可以是read,write,none,默认为read
    	anon-access = none
    	#认证用户的权限,可以是read,write,none,默认为write
    	auth-access = write
    	#账号数据库
    	password-db = passwd

    添加账号:

    sudo vim /var/svn/test/conf/passwd
    	#格式:用户名 = 密码
    	user = passwd

    修改权限:

    chmod -R 755 /var/svn/test

    VII. Memcache:
    1.安装libevent:

    sudo wget https://github.com/downloads/libevent/libevent/libevent-2.0.17-stable.tar.gz
    sudo tar -zvxf libevent-2.0.17-stable.tar.gz
    cd libevent-xxx
    sudo ./configure
    sudo make && sudo make install
    sudo ln -s /usr/local/lib/libevent-2.0.so.5 /usr/lib
    

    2.memcached服务端:

    sudo wget http://memcached.googlecode.com/files/memcached-x.xx.x.tar.gz
    sudo mkdir /usr/local/memcached
    sudo tar -zvxf memcached-xxx.tar.gz
    cd memcached-xxx
    sudo ./configure --prefix=/usr/local/memcached
    sudo make && sudo make install
    /usr/local/memcached/bin/memcached -h
    

    3.php memcache扩展

    sudo wget http://pecl.php.net/get/memcache-2.2.6.tgz
    sudo tar -zvxf memcache-x.x.x.tgz  
    cd memcache-1.5  
    sudo /usr/local/php/bin/phpize  
    sudo ./configure --enable-memcache --with-php-config=/usr/local/php/bin/php-config --with-zlib-dir  
    sudo make  
    sudo make install  
    sudo vim /usr/local/php/lib/php.ini
    

    加入:

    extension=/usr/local/php/lib/php/extensions/no-debug-zts-20090626/memcache.so
    sudo /usr/local/apahce2/bin/apachectl -k restart