-
2009-12-04
PHP Tips,留着以后备用(4) - [php]
<?php
/**
* 检查数组是否全是空值
*/
function isEmptyArray($arr) {
if(is_array($arr)) {
foreach($arr as $v) {
if(isEmptyArray($v) == false) {
return false;
}
}
} else {
return empty($arr);
}
return true;
}
/**
* 判断是否有中文字符
*/
<?php
$str = "adsadas的";
$j = 0;
for($i=1;$i<strlen($str);$i++)
{
if(ord(substr($str,$i,1))>0xa0)
{
$j++;
$i++;
}
}
echo "有".$j."个中汉字";
?>
/**
* 用以代替file_get_contents
* 需要cURL支持,当连接超时则返回false,不会卡死php页面
*/
function an_get_contents($url, $second = 5) {
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_HEADER,0);
curl_setopt($ch,CURLOPT_TIMEOUT,$second);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
$content = curl_exec($ch);
curl_close($ch);
return $content;
}
/**
* 转换至UTF-8编码
* 适用于大部分中文情况
*/
function convertToUTF8($str) {
$charset = mb_detect_encoding($str, array('ASCII','UTF-8','GB2312','GBK','BIG5'));
if ($charset!='UTF-8') {
$str = mb_convert_encoding($str,'UTF-8',$charset);
}
return $str
}
/**
* 生成指定范围内指定个数的不重复随机数
*/
function getRand($min, $max, $num) {
if($max-$min<$num) return false;
$res = null;
$arr = range($min,$max);
shuffle($arr);
$rand_keys = array_rand($arr, $num);
foreach($rand_keys as $v) {
$res[] = $arr[$v];
}
return $res;
}
?> -
2009-11-20
php引用符号(&)的作用 - [php]
php的引用(就是在变量或者函数、对象等前面加上&符号)
在PHP 中引用的意思是:不同的名字访问同一个变量内容.
与C语言中的指针是有差别的.C语言中的指针里面存储的是变量的内容在内存中存放的地址
变量的引用
PHP 的引用允许你用两个变量来指向同一个内容
<?
$a="ABC";
$b =&$a;
echo $a;//这里输出:ABC
echo $b;//这里输出:ABC
$b="EFG";
echo $a;//这里$a的值变为EFG 所以输出EFG
echo $b;//这里输出EFG
?>
函数的传址调用
传址调用我就不多说了 下面直接给出代码
function test(&$a)
{
$a=$a+100;
}
$b=1;
echo $b;//输出1
test($b); //这里$b传递给函数的其实是$b的变量内容所处的内存地址,通过在函数里改变$a的值 就可以改变$b的值了
echo "<br>";
echo $b;//输出101
要注意的是,在这里test(1);的话就会出错,原因自己去想
函数的引用返回
先看代码
function &test()
{
static $b=0;//申明一个静态变量
$b=$b+1;
echo $b;
return $b;
}
$a=test();//这条语句会输出 $b的值 为1
$a=5;
$a=test();//这条语句会输出 $b的值 为2
$a=&test();//这条语句会输出 $b的值 为3
$a=5;
$a=test();//这条语句会输出 $b的值 为6
下面解释下:
通过这种方式$a=test();得到的其实不是函数的引用返回,这跟普通的函数调用没有区别 至于原因: 这是PHP的规定
PHP规定通过$a=&test(); 方式得到的才是函数的引用返回
至于什么是引用返回呢(PHP手册上说:引用返回用在当想用函数找到引用应该被绑定在哪一个变量上面时。) 这句狗屁话 害我半天没看懂
用上面的例子来解释就是
$a=test()方式调用函数,只是将函数的值赋给$a而已, 而$a做任何改变 都不会影响到函数中的$b
而通过$a=&test()方式调用函数呢, 他的作用是 将return $b中的 $b变量的内存地址与$a变量的内存地址 指向了同一个地方
即产生了相当于这样的效果($a=&b;) 所以改变$a的值 也同时改变了$b的值 所以在执行了
$a=&test();
$a=5;
以后,$b的值变为了5
这里是为了让大家理解函数的引用返回才使用静态变量的,其实函数的引用返回多用在对象中
对象的引用
<?
class a{
var $abc="ABC";
}
$b=new a;
$c=$b;
echo $b->abc;//这里输出ABC
echo $c->abc;//这里输出ABC
$b->abc="DEF";
echo $c->abc;//这里输出DEF
?>
以上代码是在PHP5中的运行效果
在PHP5中 对象的复制 是通过引用来实现的。上列中$b=new a; $c=$b; 其实等效于$b=new a; $c=&$b;
PHP5中默认就是通过引用来调用对象, 但有时你可能想建立一个对象的副本,并希望原来的对象的改变不影响到副本 . 为了这样的目的,PHP定义了一个特殊的方法,称为__clone.
引用的作用
如果程序比较大,引用同一个对象的变量比较多,并且希望用完该对象后手工清除它,个人建议用 "&" 方式,然后用$var=null的方式清除. 其它时候还是用php5的默认方式吧. 另外, php5中对于大数组的传递,建议用 "&" 方式, 毕竟节省内存空间使用。
取消引用
当你 unset 一个引用,只是断开了变量名和变量内容之间的绑定。这并不意味着变量内容被销毁了。例如:
<?php
$a = 1;
$b =& $a;
unset ($a);
?>
不会 unset $b,只是 $a。
global 引用
当用 global $var 声明一个变量时实际上建立了一个到全局变量的引用。也就是说和这样做是相同的:
<?php
$var =& $GLOBALS["var"];
?>
这意味着,例如,unset $var 不会 unset 全局变量。
$this
在一个对象的方法中,$this 永远是调用它的对象的引用。
//下面再来个小插曲
php中对于地址的指向(类似指针)功能不是由用户自己来实现的,是由Zend核心实现的,php中引用采用的是“写时拷贝”的原理,就是除非发生写操作,指向同一个地址的变量或者对象是不会被拷贝的。
通俗的讲
1:如果有下面的代码
$a="ABC";
$b=$a;
其实此时 $a与$b都是指向同一内存地址 而并不是$a与$b占用不同的内存
2:如果在上面的代码基础上再加上如下代码
$a="EFG";
由于$a与$b所指向的内存的数据要重新写一次了,此时Zend核心会自动判断 自动为$b生产一个$a的数据拷贝,重新申请一块内存进行存储 -
2009-11-17
一些PHP的Tips,面试会遇到 - [php]
HTTP协议中几个状态码的含义:503 500 401 200 301 302
2xx: (成功)
3xx (重定向)
4xx: Client Error 使用者端(浏览器)错误讯息
5xx: Server Error 服务器端错误讯息
400(错误请求) 服务器不理解请求的语法。
401(未授权) 请求要求身份验证。对于登录后请求的网页,服务器可能返回此响应。
500(服务器内部错误) 服务器遇到错误,无法完成请求。
503(服务不可用) 服务器目前无法使用(由于超载或停机维护)。通常,这只是暂时状态。
Include require include_once require_once 的区别.
require() :如果文件不存在,会报出一个fatal error.脚本停止执行
include() : 如果文件不存在,会给出一个 warning,但脚本会继续执行
_once: 会检测是否包含过了,包含过了就不包含了关于HereDOC:
<?php
$a = "---------";
echo <<<HAHA
$a
\$a
HAHA
?>
输出: -----------
$a关于php的魔法引用:
如果php.ini不可改,可以使用.htaccess文件禁用,加入下面的代码 php_flag magic_quotes_gpc Off
相关函数:stripslashes — 去掉反斜杠,得到原始数据。 addslashes — 使用反斜线引用字符串最好设置为OFF,然后自己过滤,在PHP6中已经关闭了,或者用下面的函数:
if (get_magic_quotes_gpc())
{
function stripslashes_deep($value)
{
$value = is_array($value)?array_map('stripslashes_deep',$value):stripslashes($value);
return $value;
}
$_GET = array_map('stripslashes_deep', $_GET);
$_POST = array_map('stripslashes_deep', $_POST);
$_COOKIE = array_map('stripslashes_deep', $_COOKIE);
$_REQUEST = array_map('stripslashes_deep', $_REQUEST);
}一些编译php时的configure 参数
1.作为APACHE模块编译
–with-apxs2
2.作为fastcgi编译
–enable-fastcgi
–enable-force-cgi-redirect
3.动态加载PHP的extension
加载模块的后面加上shared关键词
例如–with-gd=shared
4.enable的扩展选项一样可以使用shared关键词作为外部扩展模块载入
5.with-EXTENSIONS-dir和单纯的with-EXTENSIONS的作用相同
同样是指定加载特定模块
只是可以指定目录
./configure --prefix=/usr/local/php --with-config-file-path=/etc \
--with-apxs2 --enable-fastcgi --enable-force-cgi-redirect \
--with-gd=shared \
--with-jpeg-dir \
--with-png-dir \
--with-zlib-dir \
--enable-gd-native-ttf \
--with-freetype-dir=shared \
--with-zlib=shared \
--with-mysql=shared \
--with-mcrypt=shared \
--with-pear=shared \
--with-curl=shared \
--with-curlwrappers=shared \
--with-xmlrpc=shared \
--without-sqlite --disable-debug --disable-rpath \
--enable-mbstring=shared \
--enable-exif=shared \
--enable-zip=shared \
--enable-ftp=sharedSafe_mode 打开后哪些地方受限.
启动safe_mode,会对许多PHP函数进行限制,特别是和系统相关的文件打开、命令执行等函数。解决多进程/线程同时读写一个文件的问题
对于日IP不高或者说并发数不是很大的应用,一般不用考虑这些!!用一般的文件操作方法完全没有问题。但如果并发高,在我们对文件进行读写操作时,很有可能多个进程对进一文件进行操作,如果这时不对文件的访问进行相应的独占,就容易造成数据丢失。
对于这样的问题,一般的解决方案时当一进程对文件进行操作时,首先对其它进行加锁
所以一般的方案是:
$fp = fopen("/tmp/lock.txt", "w+");
if (flock($fp, LOCK_EX)) {
fwrite($fp, "Write something here\n");
flock($fp, LOCK_UN);
} else {
echo "Couldn't lock the file !";
}
fclose($fp);
但在PHP中,flock似乎工作的不是那么好!在多并发情况下,似乎是经常独占资源,不即时释放,或者是根本不释放,造成死锁,从而使服务器的cpu占用很高,甚至有时候会让服务器彻底死掉。好像在很多linux/unix系统中,都会有这样的情况发生。
如果不考虑使用flock()函数,也同样会有很好的解决方案来解决我们的问题。
方案一:对文件进行加锁时,设置一个超时时间.
if($fp = fopen($fileName, 'a')) {
$startTime = microtime();
do {
$canWrite = flock($fp, LOCK_EX);
if(!$canWrite) usleep(round(rand(0, 100)*1000));
} while ((!$canWrite) && ((microtime()-$startTime) < 1000));
if ($canWrite) {
fwrite($fp, $dataToSave);
}
fclose($fp);
}
超时设置为1ms,如果这里时间内没有获得锁,就反复获得,直接获得到对文件操作权为止,当然。如果超时限制已到,就必需马上退出,让出锁让其它进程来进行操作。
方案二:不使用flock函数,借用临时文件来解决读写冲突的问题。
大致原理如下:
1。将需要更新的文件考虑一份到我们的临时文件目录,将文件最后修改时间保存到一个变量,并为这个临时文件取一个随机的,不容易重复的文件名。
2。当对这个临时文件进行更新后,再检测原文件的最后更新时间和先前所保存的时间是否一致。
3。如果最后一次修改时间一致,就将所修改的临时文件重命名到原文件,为了确保文件状态同步更新,所以需要清除一下文件状态。
4。但是,如果最后一次修改时间和先前所保存的一致,这说明在这期间,原文件已经被修改过,这时,需要把临时文件删除,然后返回false,说明文件这时有其它进程在进行操作。
方案四:将所有要操作的进程放入一个队列中。然后专门放一个服务完成文件操作。
队列中的每一个排除的进程相当于第一个具体的操作,所以第一次我们的服务只需要从队列中取得相当于具体操作事项就可以了,如果这里还有大量的文件操作进程,没关系,排到我们的队列后面即可,只要愿意排,队列的多长都没关系。
参考:http://hqlong.com/2009/01/530.html
使用mod_rewrite,在服务器上没有/archivers/567.html这个物理文件时,重定向到index.php?id=567先php.ini配置中打开mod_rewrite。然后在.htaccess文件中写入:ErrorDocument 404 index.php?id=567
对于大流量的网站,您采用什么样的方法来解决各页面访问量统计问题
网站性能优化 提高网站访问速度的14条实践规则
具体参考:提高网站性能的14条法则:http://www.629d.com/a/200907/62.html
主要:
第一条、尽可能的减少 HTTP 的请求数 (Make Fewer HTTP Requests )
第二条、使用CDN(内容分发网络): Use a Content Delivery Network
第三条、 添加Expire/Cache-Control 头:Add an Expires Header
第五条、将css放在页面最上面 ( Put Stylesheets at the Top)
第六条、将script放在页面最下面 (Put Scripts at the Bottom ) -
2009-08-21
中文全文搜索解决方案sphinx+mysql+mmseg,安装,配置,API调用 - [service]
最近在研究中文搜索引擎,找了许多解决方案,有JAVA下的的Lucene,还有强大的C++下的fietex,哪些比较复杂,对现在的项目来讲,不是很实用,所以把目光瞄向了轻便的sphinx,今天安装还算顺利,以下备忘。
首先,Sphinx默认不支持中文索引及检索,以前用补丁搞定,现在,写补丁那个项目组的人又弄了个CSFT,全称是:CoreSeek Fulltext Search Server,CoreSeek 全文检索服务器。于是呢,就把sphinx集成过来,挺好用的。
1. 去Coreseek官网下载源码,需要mmseg和Coreseek Fulltext Server最好用源码安装,那个RPM文件包反正我没搞定,呵呵。
2. 装mmseg。
# tar zxf mmseg3_0b3.tar.gz
# cd mmseg3_0b4;
# ./configure –prefix=/Data/apps/mmseg (这个目录可以改)
# make && make install
运行mmseg,如果成功会有显示
3. 装CSFT
# tar zxf csft3_0b4.tar.gz
# cd csft3_0b3
# ./configure -prefix=/Data/apps/sphinx (这个需要mysql和mmseg,别把目录写错了)
-with-mysql=/Data/apps/mysql
-with-mmseg=/Data/apps/mmseg
-with-mmseg-includes=/Data/apps/mmseg/include/mmseg
-with-mmseg-libs=/Data/apps/mmseg/lib/
-with-mysql-includes=/Data/apps/mysql/include/mysql/
-with-mysql-libs=/Data/apps/mysql/lib/mysql/
# make && make install
4. sphinx.conf
安装完成后,会生成/Data/apps/sphinx/etc/sphinx.conf.dist 要更改为.conf
#cp /Data/apps/sphinx/etc/sphinx.conf.dist /Data/apps/sphinx/etc/sphinx.conf
5. 生成字典
因为用到中文分词,需要生成字典,去安装目录,比如我的是 /home/changyou/mmseg.3.0b3/data/
#mmseg -u unigram.txt 该命令执行后,将会产生一个名为unigram.txt.uni的文件,将该文件改名为uni.lib,完成词典的构造。
然后,在/Data/apps/sphinx/var/下建立文件夹 dict,然后把uni.lib放进去
6. 配置
sphinx.conf 文件中需要对charset_dictpath指定uni.lib的路径/Data/apps/sphinx/var/dict/
还有连接mysql的信息,这个不用说了罢。
这里有个参数对于中文用户要注意一下:
charset_type
字符集编码类型。可选选项,默认为“sbcs”。已知的值包括“sbcs”和“utf-8”。
对于中文用户,可选的值还可以有“zh_cn.utf-8 ”和“zh_cn.gbk”。当设置charset_type值为上面的两种时,系统默认您开启了中文分词特性。
但是我设置了zh_cn.utf-8,报错说“unknown charset type 'zh_cn.utf-8'”,不知道为什么。。。。。
7. 运行
# /Data/apps/sphinx/bin/indexer
启动索引服务时,如果报下面的错:
error while loading shared libraries: libmysqlclient.so.15: cannot open shared object file: No such file or directory
原因应该是因为mysql的lib文件不在系统的lib搜索路径上导致的。
运行命令,解决:
# ln -s /Data/apps/mysql/lib/mysql/libmysqlclient.so.15 /usr/lib/libmysqlclient.so.15
8. 导入测试数据
# mysql -uroot -p test < /Data/apps/sphinx/etc/example.sql
这里千万注意,mysql编码一定要为UTF-8 !!!
9. 测试建立索引
#indexer --all
出错,Coreseek Full Text Server 3.1
Copyright (c) 2006-2008 coreseek.com
FATAL: no readable config file (looked in /usr/local/sphinx/etc/csft.conf, ./csft.conf)
这是因为 Coreseek 默认要去读 csft.conf,所以要复制一份
# cp /Data/apps/sphinx/etc/sphinx.conf /Data/apps/sphinx/bin/csft.conf
( 或者,也可以指定conf文件,#indexer --config /Data/apps/sphinx/etc/sphinx.conf --all 这里我没有指定,所以用了2个conf文件,很不靠谱)
10. 然后继续运行 #indexer --all ,应该会看到如下输出:
Coreseek Full Text Server 2.1
Copyright (c) 2006-2008 coreseek.com
using config file '/usr/local/etc/csft.conf'...
indexing index 'test1'...
collected 5 docs, 0.0 MB
sorted 0.0 Mhits, 100.0% done
total 5 docs, 230 bytes
total 0.146 sec, 1577.50 bytes/sec, 34.29 docs/sec
indexing index 'test1stemmed'...
collected 5 docs, 0.0 MB
sorted 0.0 Mhits, 100.0% done
total 5 docs, 230 bytes
total 0.011 sec, 21879.74 bytes/sec, 475.65 docs/sec
11. 测试全文检索
# search doc 应该会看到如下输出:
Coreseek Full Text Server 3.1
Copyright (c) 2006-2008 coreseek.com
using config file './csft.conf'...
index 'test1': query 'doc ': returned 2 matches of 2 total in 0.000 sec
displaying matches:
1. document=3, weight=1, group_id=2, date_added=Sat Aug 22 03:54:19 2009
id=3
group_id=2
group_id2=7
date_added=2009-08-22 03:54:19
title=another doc
content=this is another group
2. document=4, weight=1, group_id=2, date_added=Sat Aug 22 03:54:19 2009
id=4
group_id=2
group_id2=8
date_added=2009-08-22 03:54:19
title=doc number four
content=this is to test groups
words:
1. 'doc': 2 documents, 2 hits
index 'test1stemmed': query 'doc ': returned 2 matches of 2 total in 0.000 sec
displaying matches:
1. document=3, weight=1, group_id=2, date_added=Sat Aug 22 03:54:19 2009
id=3
group_id=2
group_id2=7
date_added=2009-08-22 03:54:19
title=another doc
content=this is another group
2. document=4, weight=1, group_id=2, date_added=Sat Aug 22 03:54:19 2009
id=4
group_id=2
group_id2=8
date_added=2009-08-22 03:54:19
title=doc number four
content=this is to test groups
words:1. 'doc': 2 documents, 2 hits
12. 启动searchd进程
# searchd
PHP接口在源安装包下面的api/下,可以调用测试,很好用,明天继续研究!
接上一回,调用sphinx,我们先插入一个中文的数据:
INSERT INTO `test`.`documents` (`id` ,`group_id` ,`group_id2` ,`date_added` ,title` ,`content`)VALUES (NULL , '3', '9', NOW( ) ,'sphinx中文搜索','Sphinx是一个基于SQL的全文检索引擎,可以结合MySQL,PostgreSQL做全文搜索,它可以提供比数据库本身更专业的搜索功能,使得应用程序更容易实现专业化的全文检索。Sphinx特别为一些脚本语言设计搜索API接口,如 PHP,Python,Perl,Ruby等,同时为 MySQL也设计了一个存储引擎插件');
因为有新数据,所以要重建索引(关于这个问题,以后遇到再研究,如果每天有新数据都要重建索引,很不靠谱)
先kill searchd进程,运行:
# searchd --stop 然后
# indexer --all
1.调用sphinx:
一是通过Sphinx官方提供的API接口(接口有Python,Java,Php三种版本)
二是通过安装SphinxSE(具体见1.2部分),然后创建一个中介sphinxSE类型的表,再通过执行特定的SQL语句实现。
现在,我们用API接口,在sphinx安装目录有一个API目录,里面有三个PHP文件:test.php,test2.php和 sphinxapi.php。 sphinxapi.php是sphinx调用接口封装文件,test.php是一个在命令行下执行的查询例子文件,test2.php是一个生成摘要的例子文件。
运行:
# php /home/changyou/csft-3.1/api/test.php -i test1 doc
返回结果:
Query 'doc ' retrieved 2 of 2 matches in 0.000 sec.
Query stats: 'doc' found 2 times in 2 documents
Matches:
1. doc_id=3, weight=100, group_id=2, date_added=2009-08-22 03:54:19
2. doc_id=4, weight=100, group_id=2, date_added=2009-08-22 03:54:19
注意:这里,如果不输入参数 -i test1 doc ,那test.php就不会知道你要查那个索引并且搜索什么字句。
所以,如果想引入生产环境中,我们需要手动修改一下test.php
a. 注释掉10行-43行,
b. 然后添加:$search_info = array("1" => "-i", "2" => "test1", "3" => "$keyword");
c. foreach ( $search_info as $arg ) 替换原来的foreach
d. 自己定义下$keyword="设计",记得把文件另存为utf-8
e. 然后,运行: # php /home/changyou/csft-3.1/api/test.php
Query '(乱码)' retrieved 1 of 1 matches in 0.000 sec.
Query stats:
'(乱码)' found 8 times in 1 documents
Matches:
1. doc_id=5, weight=2, group_id=3, date_added=2009-08-26 20:18:33
哈哈,OK啦!可以将sphinx文件封装好,就可以用与生产环境了。
从上面可以看出Query并不能全部取得我们想要的记录内容,比如说Title,Contents字段就没有取出来,根据官方的说明是sphinx 并没有连到mysql去取记录,只是根据它自己的索引内容进行计算,因此如果想用sphinxAPI去取得我们想要的记录,还必须将Query的结果为依据去查询MySQL才可以得到最终我们想要的结果集。
2.搜索全文时的摘要,高亮显示。
假设我要搜索关键词"test",通过sphinx可以取到搜索结果,在显示搜索结果时,我希望将含有"test"的进行红色或加粗显示,同时,我不希望全部都显示出来,只需要显示一段摘要,就象google或百度那样,搜出来的结果不是全篇显示,只是部分显示,这个就是摘要的作用。
以test2.php中为例,可以利用BuildExcerpts方法可以实现摘要的功能。具体可以看看test2.php的代码。这里不说了。
3.后记
从网上看到,还可以用SphinxSE方式调用Sphinx。但问题是,我安装的时候,不知道为什么没有安装SphinxSE引擎,在mysql 里用mysql> show engine; 查看。可能是我没有直接编译sphinx然后打2个中文补丁吧,而是用了官网推荐的中文搜索安装包。从索引得到ID号,然后再去查询数据库,也可以实现中文搜索的效果,但是具体效率怎么样就不知道了。
最后,在sphinx配置文件里,如要用自己的数据,需要修改源数据,这一项:sql_query = \SELECT id, group_id, UNIX_TIMESTAMP(date_added) AS date_added, title, content \ FROM documents;
让他自己抓取合适你数据结构的语句即可。
参考:http://blog.c1gstudio.com/archives/722
http://www.zhengjinjun.com/index.php/2009/06/28/sphinxmysql%E4%B8%AD%E6%96%87%E5%88%86%E8%AF%8D%E5%AE%89%E8%A3%85-%E5%AE%9E%E7%8E%B0%E4%B8%AD%E6%96%87%E5%85%A8%E6%96%87%E6%90%9C%E7%B4%A2/
http://www.htmldata.cn/?p=171 -
2009-08-20
php的调试工具XHProf的安装,运用 - [php]
分了台新服务器做测试,最近很闲,正好拿来练手,哈哈,先拿XHProf玩吧。调试PHP时,XDebug一直是大众的不二选择,搭配上Webgrind,可以获得不错的效果,但是很耗资源,CPU一会就到100%了。最近看别人的blog,发现了XHProf,于是想体验了一下。安装过程很简单,但也遇到不少挫折,因为新服务器,上面有些东西是运维装好了,所以没有仔细了解。都是些小问题,不过折腾死了。
1.#wget http://pecl.php.net/get/xhprof-0.9.2.tgz 一开始wget用不了,报错:Resolving dada... failed: Temporary failure in name resolution.查明是DNS解析的原因,然后更改 /etc/resolv.conf,问运维,写上正确的IP。
2.下载完了,解压 #tar zxf xhprof-0.9.2.tgz 然后,#cd cd xhprof-0.9.2/extension/
3.然后 #phpize (一般编译安装的PHP都有,没有去下)
4.#./configure --with-php-config=/usr/bin/php-config
5.#make #make install #make test 就搞定了
6.然后 更改php.ini 把下面的加到文件中
[xhprof]
extension=xhprof.so
;
; directory used by default implementation of the iXHProfRuns
; interface (namely, the XHProfRuns_Default class) for storing
; XHProf runs.
;xhprof.output_dir=<这里写你要保存xhp生成log的目录>7.搞定啦!! 整个过程最郁闷的是,php.ini中的extend扩展地址没写,还是默认的“./”一直没发现,试了半天都不成功,崩溃了,最后还是抽了根烟才发现,呵呵,烟是好东西啊。
测试下,
<?php
function bar($x) {
if ($x > 0) {
bar($x - 1);
}
}
function foo() {
for ($idx = 0; $idx < 2; $idx++) {
bar($idx);
$x = strlen("abc");
}
}
// start profiling
xhprof_enable();
// run program
foo();
// stop profiler
$xhprof_data = xhprof_disable();
// display raw xhprof data for the profiler run
print_r($xhprof_data);?>
最后返回数组,就表示安装好了。具体哪些值是什么意思先别管,因为下面有UI的配置。会很直观!8.首先,为了好看,装个Graphviz:
wget http://www.graphviz.org/pub/graphviz/stable/SOURCES/graphviz-2.24.0.tar.gz
tar zxf graphviz-2.24.0.tar.gz
cd graphviz-2.24.0
./configure
make
make install
安装完成后,会生成/usr/local/bin/dot文件,你应该确保路径在PATH环境变量里,以便XHProf能找到它。9.把上面的测试代码拿过来改改,在最后面,加上几行:
include_once ("/Data/web/changyou/xhprof_lib/utils/xhprof_lib.php");
include_once ("/Data/web/changyou/xhprof_lib/utils/xhprof_runs.php");
$xhprof_runs = new XHProfRuns_Default();
// Save the run under a namespace "xhprof_foo".
// **NOTE**:
// By default save_run() will automatically generate a unique
// run id for you. [You can override that behavior by passing
// a run id (optional arg) to the save_run() method instead.]
//
$run_id = $xhprof_runs->save_run($xhprof_data, "xhprof_foo");
echo "<br>---------------<br>".
"Assuming you have set up the http based UI for <br>".
"XHProf at some address, you can view run at <br>".
"http://192.168.5.148/changyou/xhprof_html/index.php?run=$run_id&source=xhprof_foo<br>".
"---------------<br>";?>
然后,好了,运行那个打印出来的URL,OK啦!看看效果,如果你安装了Graphviz,还会有华丽的大图噢
-
2009-08-13
中文分词,应用 - [php]
1.什么是中文分词,以及一些开源项目,见:http://www.williamlong.info/archives/1839.html
2.中文分词一般在搜索的时候用得较多,分词系统一般是基于词频的,并辅以一定的专有名称,人名,地名,数字年代等规则识别来达到基本分词,经小范围测试大概准确率在 90% ~ 95% 之间,已能基本满足一些小型搜索引擎、关键字提取等场合运用。
3.公司现有2个分词系统(开源)
一个是:SCWS(强大,有PHP接口),开发者:Hightman。
一个是:HJ_SegWord(超轻量,用PHP写的)。4.先说Segword,引用类:HJ_SegWord_Class.php,实例化后调用接口:Seg_Word_NM
include_once('HJ_SegWord_Class.php');
$HJ_SegWord = new HJ_Segword_Class();
$keyword = implode(' ', $HJ_SegWord->Seg_Word_NM($keyword));
$HJ_SegWord->Clear();
$keyword = empty($keyword) ? $keyword : conutf8($keyword);
return $keyword;5.至于SCWS,安装见官方文档,使用呢:
$dict = 'lib/pscws/dict/dict.xdb'; //词典
$version = 3; // 采用版本
$autodis = true; // 是否识别名字
$ignore = true; // 是否忽略标点
$debug = false; // 是否为除错模式
$stats = false; // 是否查看统计结果
$object = 'PSCWS' . $version;
require_once('lib/pscws/pscws3.class.php');
$cws = new $object($dict);
$cws->set_ignore_mark($ignore); // 是否忽略标点
$cws->set_autodis($autodis);// 是否识别名字
$cws->set_debug($debug); // 是否为除错模式
// 开启统计
$cws->set_statistics($stats);// 是否查看统计结果
$keyword = implode(' ', $cws->segment($keyword, 'words_cb'));
$keyword = empty($keyword) ? $keyword : conutf8($keyword);return $keyword;
-
2009-08-13
PHP Tips,留着以后备用(3) - [php]
//取函数后缀名
<?php
$file_name = "course_notice.mp3.rar"; //名字是随便起的
$extend = explode(".",$file_name);
$extend_id = count($extend)-1;
$extend_name = $extend[$extend_id];
echo($extend_name);
?>
<?php
$file_name = "course_notice.mp3.rar";
$pt = strrpos($file_name,".")+1;
$extend_name = substr($file_name,$pt);
echo($extend_name);
?>
<?php
$file_name = "course_notice.mp3.rar";
$extend_name = substr(strrchr($file_name,"."),1);
echo($extend_name);
?>
<?php
$file_name = "course_notice.mp3.rar";
$extend = pathinfo($file_name);
$extend_name = $extend['extension'];
echo($extend_name);
?> -
2009-08-12
curl函数库,应用说明 - [php]
最近遇到一个需求,后台DBA给了我一个接口调用,在浏览器上用,半秒就出来了,可是在程序里用下面的方法调用,耗时10-19秒:
$get = "http://221.123.176.20:8080/userid=".$userid;
$rank = @file_get_contents($get);
return $rank;很不靠谱。于是想到curl。
使用PHP的cURL库可以简单和有效地去抓网页。你只需要运行一个脚本,然后分析一下你所抓取的网页,然后就可以以程序的方式得到你想要的数据了。无论 是你想从从一个链接上取部分数据,或是取一个XML文件并把其导入数据库,那怕就是简单的获取网页内容,cURL 是一个功能强大的PHP库。
1.安装:用phpinfo()查看是否有安装。如没有,win下修改php.ini,linux下则需重新编译PHP。
2.取URL:
// 初始化一个 cURL 对象
$curl = curl_init();
// 设置你需要抓取的URL
$url_info = "http://221.123.176.20:8080/userid=".$gb_userid;
curl_setopt($curl,CURLOPT_URL,"$url_info");
// 设置header
curl_setopt($curl, CURLOPT_HEADER, false);
// 设置cURL 参数,要求结果保存到字符串中还是输出到屏幕上。
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($curl);
// 关闭URL请求
curl_close($curl);
// 显示获得的数据
var_dump($data); -
2009-07-14
linux下修改php.ini,重启apache - [linux]
公司php安装居然没有配置error_display为Off,导致报错时用户清晰看到服务器路径,还贴在了BBS上,太乐了。
PHP本来安装在/usr/bin/下,但是公司统一安装的时候,是在/Apps/下,找了半天找不到,最后干脆用了php_info(),发现在/Apps/PHP5/zend/php.ini,然后修改,之后,要重启apache,找了下,就在/Apps/apache/bin/下,ls发现,有一堆,如:
-rwxr-xr-x 1 root root 100399 Nov 26 2008 ab
-rwxr-xr-x 1 root root 3428 Nov 26 2008 apachectl
-rwxr-xr-x 1 root root 7001 Nov 26 2008 apr-1-config
-rwxr-xr-x 1 root root 6201 Nov 26 2008 apu-1-config
-rwxr-xr-x 1 root root 22597 Nov 26 2008 apxs
-rwxr-xr-x 1 root root 9562 Nov 26 2008 checkgid
-rwxr-xr-x 1 root root 8876 Nov 26 2008 dbmmanage
-rw-r--r-- 1 root root 978 Nov 17 2008 envvars
-rw-r--r-- 1 root root 978 Nov 26 2008 envvars-std
-rwxr-xr-x 1 root root 35852 Nov 26 2008 htcacheclean
-rwxr-xr-x 1 root root 23529 Nov 26 2008 htdbm
-rwxr-xr-x 1 root root 16962 Nov 26 2008 htdigest
-rwxr-xr-x 1 root root 23686 Nov 26 2008 htpasswd
-rwxr-xr-x 1 root root 1156959 Nov 26 2008 httpd
-rwxr-xr-x 1 root root 16311 Nov 26 2008 httxt2dbm
-rwxr-xr-x 1 root root 15869 Nov 26 2008 logresolve
-rwxr-xr-x 1 root root 20441 Nov 26 2008 rotatelogs最后,运行:#./apachectl restart 搞定
-
2009-05-14
JS和CSS的一些小应用 - [JQuery]
1.select对话框,选择对应value的内容,并显示在DIV里。
<script>
function showimage(arg){
var dd = arg.indexOf('img:');
var ff = arg.substring(dd+4);
hehe.style.display='';
susu.src= 'Dock.jpg';
}
function qudiao(){
hehe.style.display='none';
}
</script>
<style type="text/css">
<!--
#hehe {
position:absolute;
width:200px;
height:115px;
z-index:1;
left: 66px;
top: 21px;
}
-->
</style>
<div id="hehe" style="display:none">
<img id="susu" onmouseout="qudiao()" src="" width="500px" height="100px" border="0" /></div>
<select id="engraving_cy" style="width: 800px;" size="5" name="engraving_cy" onchange="showimage(this.options[selectedIndex].text)">
<option value="950@p@140x77x3xpublic/upload/material/431a25f852f7b0ea79c9adc594785812.jpg@p@mm">dimg:public/upload/material/431a25f852f7b0ea79c9adc594785812.jpg</option>
<option value="650@p@140x77x2xpublic/upload/material/431a25f852f7b0ea79c9adc594785812.jpg@p@mm">price:650;width:140;height:77;amount:2;unit:;img:public/upload/material/431a25f852f7b0ea79c9adc594785812.jpg</option>
</select>2. 鼠标划过,变色!!!
最简单的办法:
<table width="200" border="1">
<tr onmouseover="this.bgColor='#666666'" onmouseout="this.bgColor='#FFFFFF'" >
<td> </td><td> </td><td> </td>
</tr>
<tr onmouseover="this.bgColor='#666666'" onmouseout="this.bgColor='#FFFFFF'" >
<td> </td><td> </td><td> </td>
</tr>
</table> -
2009-04-28
基于OpenCV的PHP图像人脸识别技术 - [php]
[转]基于OpenCV的PHP图像人脸识别技术
本文所介绍的技术不是原创,而是从一个叫Robert Eisele的德国人那里学习来的。他写了一个PHP扩展openCV,只封装了两个函数,叫face_detect和face_count。 openCV是一个开源的用C/C++开发的计算机图形图像库,非常强大,研究资料很齐全。本文重点是介绍如何使用php来调用其中的局部的功能。人脸侦 查技术只是openCV一个应用分支。
1.安装
从源代码编译成一个动态的so文件。
1.1.安装 OpenCV (OpenCV 1.0.0)
下载地址:http://sourceforge.net/project/showfiles.php?group_id=22870&package_id=16948
#tar xvzf OpenCV-1.0.0.tar.gz
#cd opencv-1.0.0
#./configure
#make
#make install
#make check (检查是否安装全部正确)
提示: 不要指定安装路径,否则后面编译facedetect会找不到OpenCV的路径。
1.2 安装facedetect
下载地址http://www.xarg.org/download/facedetect-1.0.0.tar.gz
#tar xzvf facedetect-1.0.0.tar.gz
#cd facedetect-1.0.0
#phpize && ./configure && make && make install
编译完之后会提示facedetect.so 文件所在的位置。
最后确认在php.ini加入
extension=facedetect.so,重启apache.
2.函数使用
在phpinfo()里检查是否有facedetect这个模块。
从openCV源代码/data/haarcascades/里头取出所有xml文件放在php的执行目录下- //检查有多少个脸型
- var_dump(face_count('party.jpeg', haarcascade_frontalface_alt.xml'));
- //返回脸型在图片中的位置参数,多个则返回数组
- $arr = face_detect('party.jpeg', haarcascade_frontalface_alt2.xml');
- print_r($arr);
3.应用
结合imagick可以将图片做一下应用。因为 face_detect只返回一个矩形参数,包含x,y坐标和w,h长宽参数。下面是我的一个应用demo- <?php
- if($_FILES){
- $img = $_FILES['pic']['tmp_name'];
- $arr = face_detect($img, 'haarcascade_frontalface_alt2.xml');
- //$arr1 = face_detect($img, 'haarcascade_frontalface_alt_tree.xml');
- if(is_array($arr1)) $all =array_merge($arr,$arr1);
- else $all = $arr;
- $im = new Imagick($img);
- //$draw =new ImagickDraw();
- //$borderColor = new ImagickPixel('red');
- //$draw->setFillAlpha(0.0);
- //$draw->setStrokeColor ($borderColor);
- //$draw->setStrokeWidth (1);
- if(is_array($all)){
- foreach ($all as $v){
- $im_cl = $im->clone();
- $im_cl->cropImage($v['w'],$v['h'],$v['x'],$v['y']);
- $im_cl->swirlImage(60);
- $im->compositeImage( $im_cl, Imagick::COMPOSITE_OVER , $v['x'], $v['y'] );
- //$draw->rectangle($v['x'],$v['y'],$v['x']+$v['w'],$v['y']+$v['h']);
- //$im->drawimage($draw);
- }
- }
- header( "Content-Type: image/png" );
- echo $im;
- }else{
- ?>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <form method="POST" enctype="multipart/form-data">
- 人脸识别试验:只支持jpg,png<br>
- 上传一张图片 <input type="file" name="pic">
- <input type="submit" value="upload">
- </form>
- <?
- }
- ?>
参考资料:
http://www.xarg.org/2008/07/face-detection-with-php/
http://www.opencv.org.cn/index.php/首页
http://www.cs.iit.edu/~agam/cs512/lect-notes/opencv-intro/index.html以上文章来源:http://blog.csdn.net/zhongmao/archive/2009/01/11/3753377.aspx
使用测试
安装测试了一下,如果越是高清的大图,效果越明显,感觉不错
一 安装
1 安装opencv
http://sourceforge.net/project/showfiles.php?group_id=22870&package_id=16948
下载opencv-1.1pre1.tar.gz(1.0版本没有安装成功)
#tar zxvf opencv-1.1pre1.tar.gz
# cd opencv-1.1.0/
# /.configure
#make
#make install2 安装facedetect
#wget http://www.xarg.org/download/facedetect-1.0.0.tar.gz
#tar xzvf facedetect-1.0.0.tar.gz
#cd facedetect-1.0.0
#/usr/local/php/bin/phpize
#./configure –with-php-config=/usr/local/php/bin/php-config
#make
#make install#vi /usr/local/php/etc/php.ini
// 增加extension=facedetect.so3 重启web服务器,在phpinfo()里查看是否有facedetect这个模块
二 简单测试
从openCV源代码/data/haarcascades/里头取出所有xml文件放在php的执行目录下//检查有多少个脸型
var_dump(face_count(’test.jpg’, ‘haarcascade_frontalface_alt.xml’));//返回脸型在图片中的位置参数,多个则返回数组
$arr = face_detect(’test.jpg’, ‘haarcascade_frontalface_alt2.xml’);print_r($arr);
三 测试代码
<?
if(empty($_POST)) {
?>
<form name=”form” id=”form” method=”POST” enctype=”multipart/form-data” action=”">
上传图片:<input type=”file” name=”pic” size=”20″><input type=”submit” name=”submit” value=”上传”>
</form>
<?
} else {
$img = $_FILES['pic']['tmp_name'];$arr = face_detect($img, ‘haarcascade_frontalface_alt2.xml’);
if(is_array($arr1)) {
$all = array_merge($arr,$arr1);
} else {
$all = $arr;
}
$allowtype = 1;
switch($_FILES['pic']['type']){
case ‘image/pjpeg’: $fix_pic.= “.jpg”; break;
case ‘image/jpeg’: $fix_pic.= “.jpg”; break;
case ‘image/x-png’: $fix_pic.= “.png”; break;
case ‘image/png’: $fix_pic.= “.png”; break;
default: $allowtype = 0; break;
}if($allowtype == 0) {
echo “文件格式错误:只运行jpg或png图片”;exit;
}$tmp_name = time();
$src_pic = “/usr/website/nginx/face/haarcascades/upload/”.$tmp_name.$fix_pic;
move_uploaded_file($_FILES['pic']['tmp_name'], $src_pic);$pic_src = $pic_dst = array();
if(is_array($all)){
foreach ($all as $k => $v){
$tmp_name_new = $tmp_name.”_”.$k;
$x = $v['x'];
$y = $v['y'];
$w = $v['w'];
$h = $v['h'];
$dst_pic = “/usr/website/nginx/face/haarcascades/upload/”.$tmp_name_new.$fix_pic;
// echo $src_pic.”<br>”;
// echo $dst_pic.”<br>”;
$cmd = “/usr/bin/convert -crop “.$w.”x”.$h.”+”.$x.”+”.$y.” “.$src_pic.” “.$dst_pic;
// echo $cmd.”<br>”;
echo `$cmd`;
$pic_src[] = “upload/”.$tmp_name.$fix_pic;
$pic_dst[] = “upload/”.$tmp_name_new.$fix_pic;
}
}foreach($pic_src as $key => $value) {
echo “<img src=’”.$value.”‘> => <img src=’”.$pic_dst[$key].”‘><br>”;
}
}
?>



以上文章来源:http://www.sysbus.com/?p=124
-
2009-04-25
分布式服务器,查看各台服务器网页内容 - [service]
/************************
* 函数用途:同一域名对应多个IP时,获取指定服务器的远程网页内容
* 创建时间:2008-12-09
* 参数说明:
* $ip 服务器的IP地址
* $host 服务器的host名称
* $url 服务器的URL地址(不含域名)
* 返回值:
* 获取到的远程网页内容
* false 访问远程网页失败
************************/
function HttpVisit($ip, $host, $url)
{
$fp = fsockopen ($ip, 80);
if (!$fp)
{
return $erro=$ip." cant connected!!";
}
else
{
$out = "GET {$url} HTTP/1.1\r\n";
$out .= "Host:{$host}\r\n";
$out .= "Connection: close\r\n\r\n";
fputs ($fp, $out);
while($line = fread($fp, 4096))
{
$response .= $line;
}
fclose( $fp );
//去掉Header头信息
$pos = strpos($response, "\r\n\r\n");
$response = substr($response, $pos + 4);
return $response;
}
}
//调用方法:
$server_info1 = HttpVisit("60.28.209.250", "my.molihe.com", "index.php");
$server_info2 = HttpVisit("60.28.209.245", "my.molihe.com", "index.php");
$server_info3 = HttpVisit("60.28.209.221", "my.molihe.com", "index.php");
?> -
2009-04-16
PHP Tips,留着以后备用(2) - [php]
//检查数组是否全是空值
function isEmptyArray($arr) {
if(is_array($arr)) {
foreach($arr as $v) {
if(isEmptyArray($v) == false) {
return false;
}
}
} else {
return empty($arr);
}
return true;
}
//判断是否有中文字符
function isChinese($word) {
return preg_match ('/[^\x0-\x7F]/', $word);
}
//取出字符串中的url
$get_url='<a href="http://localhost/member.php?action=login">会员登陆</a>';
preg_match_all('!<a href=[\"](.+?)[\"]>!is',$get_url,$temp);
echo $temp[1][0]; //输出 :http://localhost/member.php?action=login
//时间戳换成标准时间
$Unix_time = 967766400;
$time= date("Y-m-d H:m:s",$Unix_time);
echo $time; // return 2000-11-1 0:0:0;
//标准时间换成时间戳
$time = "1 September 2000"; //这里必须是英文的标准时间!!
$Unix_time = strtotime($time);
echo $Unix_time; // return 967766400;
//例子 1. ceil()
echo ceil(4.3); // 5
echo ceil(9.999); // 10
//例子 2. floor()
echo floor(4.3); // 4
echo floor(9.999); // 9
//例子 3. round()
echo round(3.4); // 3
echo round(3.5); // 4
echo round(3.6); // 4
echo round(3.6, 0); // 4
echo round(1.95583, 2); // 1.96
echo round(1241757, -3); // 1242000
echo round(5.045, 2); // 5.05
echo round(5.055, 2); // 5.06
//例子 4.intval()
echo intval(4.3); //4
echo intval(4.6); // 4
echo intval("undifine"); // 0
/**
* 将数组转成字符串
* @param array $array 数组数据
* @return string strnig。 以 “|” 分割的字符串
*/
function _array2string($array)
{
if (!is_array($array))
{
echo "array is exist";
}
$string = '';
foreach($array as $k =>$v)
{
$string .= $v.'|';
}
if (strlen($string) > 0)
{
$string = substr($string,0,-1 );//去掉多增加的标志符
}
return $string;
}
/**
* 将字符串转成数组
* @param string $string 以‘|’分隔的字符串
* @return array $array 数组数据
*/
function _string2array($string)
{
$array = array();
if (!empty($string))
{
$array = preg_split ('/\|/' ,$string);
}
return $array;
} -
2009-03-02
PHP Tips,留着以后备用(1) - [php]
<?php
//中文字符截取 1
$text = "牛逼牛逼牛逼的牛牛逼的逼哈哈哈";
$value = substr($text, 0, 18);
$value_length = strlen($value);
$value_count = 0;
for ($i = 0; $i < $value_length; $i++)
{
if (ord($value{$i}) > 127)
{
$value_count++;
}
}
if ($value_count % 2 != 0)
{
$value = substr($text, 0, $value_length - 1);
}
echo $value."<BR>";
//中文字符截取 2
function cut_str($msg,$cut_size,$charset="UTF-8",$suffix="...")
{
if($cut_size<=0) return $msg;
$i=1;$han=0;$eng=0;
while ($i <= strlen($msg)) {
if(ord($msg[($i-1)])>127) {
$han++;
if($charset=="UTF-8") {
$i=$i+3;
}else{
$i=$i+2;
}
}else{
$eng++;
$i=$i+1;
}
if(($han+$eng)==$cut_size) {
if($charset=="UTF-8") {
$cut_size = $eng + (int)$han*3;
}else{
$cut_size = $eng + (int)$han*2;
}
break;
}
}
for ($i=0;$i<$cut_size;$i++) {
$str .=$msg[$i];
}
return $str.$suffix;
}
//取得来访者的IP,包括代理服务器!
function iptype1 ()
{
if (getenv("HTTP_CLIENT_IP")) return getenv("HTTP_CLIENT_IP");
else return "none";
}
function iptype2 ()
{
if (getenv("HTTP_X_FORWARDED_FOR")) return getenv("HTTP_X_FORWARDED_FOR");
else return "none";
}
function iptype3 ()
{
if (getenv("REMOTE_ADDR")) return getenv("REMOTE_ADDR");
else return "none";
}
function ip()
{
$ip1 = iptype1();
$ip2 = iptype2();
$ip3 = iptype3();
if (isset($ip1) && $ip1 != "none" && $ip1 != "unknown") {
return $ip1;
}
elseif (isset($ip2) && $ip2 != "none" && $ip2 != "unknown") {
return $ip2;
}
elseif (isset($ip3) && $ip3 != "none" && $ip3 != "unknown") {
return $ip3;
}
else {
return "none";
}
}
echo ip(); -
2009-02-26
解决Apache2+PHP上传文件大小限制的问题 - [service]
在php.ini里面可以设置最大上传文件大小
解决方法:
第一:
在php.ini里面查看如下行:
upload_max_filesize = 8M
post_max_size = 10M
memory_limit = 20M
另外要确认上传的 <form> 里类似下面的这行
<input type="hidden" name="MAX_FILE_SIZE" value="500000">第二:
如果是apache 2 需要修改
/etc/httpd/conf.d/php.conf
中的LimitRequestBody 524288将524288(=512×1024)改大,比如5M(=5×1024×1024)









