• 2009-10-13

    提交textarea到mysql,换行 - [php]

    郁闷,折腾了半天,提交的数据室带换行的,结果取出来不换行,google了半天,说得云里雾里,一会又是css一会又是js的,最后PHP的nl2br函数搞定。$data = nl2br($data);

    真是郁闷,被这个小东西搞了半天,丢人啊

  • 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

  • 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,还会有华丽的大图噢


    Tag:php linux
  • 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]

    <?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);
    ?>
    Tag:php
  • 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);

    Tag:php
  • 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  搞定

    Tag:php linux
  • 2009-06-16

    有关类与方法 - [php]

    抽象类必须被继承,抽象方法必须被重写。抽象方法只需声明,无需实现;抽象类不能被实例化,抽象类不一定要包含抽象方法。若类中包含了抽象方法,则该类必须被定义为抽象类。

    Tag:php
  • 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>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
          </tr>
         <tr  onmouseover="this.bgColor='#666666'" onmouseout="this.bgColor='#FFFFFF'" >
              <td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
         </tr>
    </table>

    Tag:php JS
  • 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的执行目录下

    1. //检查有多少个脸型
    2. var_dump(face_count('party.jpeg', haarcascade_frontalface_alt.xml'));
    3. //返回脸型在图片中的位置参数,多个则返回数组
    4. $arr = face_detect('party.jpeg', haarcascade_frontalface_alt2.xml');
    5. print_r($arr);



    3.应用
    结合imagick可以将图片做一下应用。因为 face_detect只返回一个矩形参数,包含x,y坐标和w,h长宽参数。下面是我的一个应用demo

    1. <?php
    2. if($_FILES){
    3. $img = $_FILES['pic']['tmp_name'];
    4. $arr = face_detect($img'haarcascade_frontalface_alt2.xml');
    5. //$arr1 = face_detect($img, 'haarcascade_frontalface_alt_tree.xml');
    6. if(is_array($arr1)) $all =array_merge($arr,$arr1);
    7. else $all = $arr;
    8. $im = new Imagick($img);
    9. //$draw =new ImagickDraw();
    10. //$borderColor = new ImagickPixel('red');
    11. //$draw->setFillAlpha(0.0);
    12. //$draw->setStrokeColor  ($borderColor);
    13. //$draw->setStrokeWidth  (1);
    14. if(is_array($all)){
    15.   foreach ($all as $v){
    16.     $im_cl = $im->clone();
    17.     $im_cl->cropImage($v['w'],$v['h'],$v['x'],$v['y']);
    18.     
    19.     $im_cl->swirlImage(60);
    20.     $im->compositeImage( $im_cl, Imagick::COMPOSITE_OVER , $v['x'], $v['y'] );
    21.     
    22.     //$draw->rectangle($v['x'],$v['y'],$v['x']+$v['w'],$v['y']+$v['h']);
    23.     //$im->drawimage($draw);
    24.     
    25.     
    26.   }
    27. }
    28.   header( "Content-Type: image/png" );
    29.   echo $im;
    30. }else{
    31.   ?>
    32.   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    33.   <form method="POST" enctype="multipart/form-data">
    34.   人脸识别试验:只支持jpg,png<br>
    35.   上传一张图片 <input type="file" name="pic">
    36.   <input type="submit" value="upload">
    37.   </form>
    38.   <?
    39. }
    40. ?>






    参考资料:
    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 install

    2 安装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.so

    3 重启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

    Tag:php
  • 2009-04-26

    中文截取,出现乱码,解决方法 - [php]

    1. <?php  
    2. $text = "牛逼牛逼牛逼的牛牛逼的逼哈哈哈";  
    3. $value = substr($text, 0, 18);  
    4. $value_length = strlen($value);     
    5. $value_count = 0;     
    6. for ($i = 0; $i < $value_length$i++)     
    7. {     
    8.     if (ord($value{$i}) > 127)     
    9.     {     
    10.         $value_count++;     
    11.     }     
    12. }     
    13. if ($value_count % 2 != 0)     
    14. {     
    15.     $value = substr($text, 0, $value_length - 1);   
    16. }  
    17. echo $value."<BR>";  
    18. ?> 

    -------------------------------------------------------------------------

    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;
    }

    Tag:php
  • 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");
    ?>

    Tag:php linux
  • 2009-04-24

    PHP tips - [php]

    A.include 和 require的区别 :
    include('file.inc'); require('file.inc');
      1>.当file.inc不存在时,include会继续执行下面的,require会终止。
      2>.当file.inc存在时,不管包含的文件是否有错,都会终止。
    include_once和require_once 都只会在包含的时候检查,包含过了就不包了。

    B.当类文件里有$this->时,必须实例化才能调用,而Class::xxx则可以不实例化

    Tag:php
  • 2009-04-16

    PHP,取整函数,字符串也可取整为0 - [php]

    经常用到取整的函数,今天小小的总结一下!其实很简单,就是几个函数而已~~

    主要是:ceil,floor,round,intval

    ceil -- 进一法取整
    说明
    float ceil ( float value )
    返回不小于 value 的下一个整数,value 如果有小数部分则进一位。ceil() 返回的类型仍然是 float,因为 float 值的范围通常比 integer 要大。 

    例子 1. ceil() 例子

    <?php
    echo ceil(4.3);     // 5
    echo ceil(9.999);     // 10
    ?>  


    floor -- 舍去法取整
    说明
    float floor ( float value )
    返回不大于 value 的下一个整数,将 value 的小数部分舍去取整。floor() 返回的类型仍然是 float,因为 float 值的范围通常比 integer 要大。 

    例子 1. floor() 例子

    <?php
    echo floor(4.3);     // 4
    echo floor(9.999); // 9
    ?>  


    round -- 对浮点数进行四舍五入
    说明
    float round ( float val [, int precision] )
    返回将 val 根据指定精度 precision(十进制小数点后数字的数目)进行四舍五入的结果。precision 也可以是负数或零(默认值)。 

    例子 1. round() 例子

    <?php
    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
    ?>

    intval---对变数转成整数型态

    例子intval()

    <?php
    echo intval(4.3);    //4
    echo intval(4.6);  // 4  
    echo intval("undifine");  // 0
    ?>

    Tag:php
  • 2009-04-11

    string和array之间的转化,函数 - [php]

        /**
         * 将数组转成字符串    
         *    
         * @param array $array 数组数据
         * @return string strnig。 以 “|” 分割的字符串
         * @access private
         */
        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 数组数据
         * @access private
         */
        function _string2array($string)
        {
            $array = array();
            if (!empty($string))
            {
                $array = preg_split ('/\|/' ,$string);
            }
            return $array;
        }

    Tag:php