月份:2009年1月

今天可以回家过年咯,随便把博客搬到了我的国外VPS上

今天可以回家过年咯,顺便把博客搬到了我的国外VPS上

昨天运气超级棒!排队四十多分钟就买到了一张今天回南昌的卧铺票


目前已知的二种通过web免费发送短信到指定的手机

这二种免费发送短信到手机的方法都只适用于自己的手机,或是朋友手机(需做一定的设置),并且一定是移动的号!不可向任意手机发送短信!

所以这二种方法只适合把网站的留言或是订单信息发送到指定的手机中,当然也可以在php程序里写好,比如把每天的网站统计或是监控服务器异常等,可以做的事情就多了。。。。

第一种,利用的是移动的139邮箱的邮件到达提醒功能,http://www.139.com 先用自己的手机号申请免费的邮箱!
在环境配置控制面板里找到收信助理。然后,点击下面的添加,添加一条添加过滤条件,指定你要发送邮件的发送方邮箱地址(这个可以在php程序里设置)
注:发送短信通知,只发送邮件的标题(适用于小内容) 发送信件正文内容则是再把邮件的正文中的250个汉字发送至短信
这样做的目的是减少短信骚扰,因为139邮箱可以把全部的邮件通过短信通知方式发送到你的手机。

这种方法,因为是邮箱模式,所以有一定的延时,并且因为邮件头也会发送至短信,所以一般是多条短信发过来,比较烦!但有一个好处,不管是php或是其它语言,只要能发email就可以实现。在php里如果能过mail()发送的话,速度会非常的快 但注意 邮件的标题和正文都必需gb2312的编码(在utf-8时,注意转换一下这二块内容的编码)

第二种,利用飞信开放的API,网络上有大牛写了php发送飞信的类库。这种方法前提是你自己得申请一个飞信号,记好自己飞信的密码,然后直接php调用php发飞信信息的类,就完成了!非常方便,但缺点是速度比较慢

演示:http://www.ye55.com/fetion

下载:

fetion.zip


php分词实现mysql全文检索

感谢thinkphp中英分词算法的作者!

最近项目需要做全文检索方面,所以找了thinkphp中英分词算法进行拓展,首先把词库sqlite形式转成了mysql

其次把分词后的中文转变成区位码形式,从而支持mysql的全文检索!

演示:http://www.ye55.cn/fc/fc.php

下载:http://www.ye55.cn/fc/group.zip   (内含词库sql文件,包含近30W词的词库,再次感谢yhustc)

主要的文件:WordSegment.class.php

 

PHP代码
  1. <?php   
  2. /** 
  3.  +—————————————————————————— 
  4.  * 中英文分词类库 
  5.  * 使用正向扫描最大字长匹配算法进行分词,使用未匹配词的队列识别字典中没有的词 
  6.  * 提供SQLITE字典查询作为参考,可以自己扩展字典查找的findinDict方法 
  7.  +—————————————————————————— 
  8.  */  
  9. class WordSegment  
  10. {//类定义开始  
  11.     // 存放结果的数组  
  12.     var $result = array();  
  13.   
  14.     /** 
  15.      +———————————————————- 
  16.      * 字典的连接句柄和字典查询次数 
  17.      +———————————————————- 
  18.      * @var integer 
  19.      * @access protected 
  20.      +———————————————————- 
  21.      */  
  22.     protected $db;  
  23.     var $querytimes = 0;  
  24.       
  25.     protected $enChar = array("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","1","2","3","4","5","6","7","8","9","0","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","0","1","2","3","4","5","6","7","8","9");  
  26.   
  27.     /** 
  28.      +———————————————————- 
  29.      * 高频词列表,这次字很难单独组词,会干扰分词程序 
  30.      +———————————————————- 
  31.      * @var array 
  32.      * @access protected 
  33.      +———————————————————- 
  34.      */  
  35.     protected $highfreq = array(‘我’,‘是’,‘为’,‘了’,‘的’,‘你’,‘他’,‘她’,‘它’,‘们’,‘这’,‘那’,‘在’,‘和’,‘一’,‘不’,‘有’,‘对’,‘中’,‘这’,‘要’,‘上’,‘也’,‘人’,‘等’,‘说’);  
  36.   
  37.     /** 
  38.      +———————————————————- 
  39.      * 标点符号列表 
  40.      +———————————————————- 
  41.      * @var array 
  42.      * @access protected 
  43.      +———————————————————- 
  44.      */  
  45.     protected   
  46.     $sign = array(‘\r’,‘\n’,‘\t’,‘`’,‘~’,‘!’,‘@’,‘#’,‘$’,‘%’,‘^’,‘&’,‘*’,‘(‘,‘)’,‘-‘,‘_’,‘+’,‘=’,‘|’,‘\\’,’\,‘"’,‘;’,‘:’,‘/’,‘?’,‘.’,‘>’,‘,’,‘<‘,‘[‘,‘{‘,‘]’,‘}’,‘·’,‘~’,‘!’,‘@’,‘#’,‘¥’,‘%’,‘……’,‘&’,‘×’,‘(’,‘)’,‘-’,‘——’,‘=’,‘+’,‘\’,‘|’,‘【’,‘{’,‘】’,‘}’,‘‘’,‘“’,‘”’,‘;’,‘:’,‘、’,‘?’,‘。’,‘》’,‘,’,‘《’,‘ ‘,‘ ’);  
  47.   
  48.     /** 
  49.      +———————————————————- 
  50.      * 挂载字典 
  51.      +———————————————————- 
  52.      * @static 
  53.      * @access public  
  54.      +———————————————————- 
  55.      * @param string $src 字典源 
  56.      +———————————————————- 
  57.      * @return void 
  58.      +———————————————————- 
  59.      */  
  60.      function openDict($pdo) {  
  61.         $this->db= new PDO($pdo[‘dbType’].‘:host=’.$pdo[‘dbHost’].‘;dbname=’.$pdo[‘dbName’], $pdo[‘dbUser’],$pdo[‘dbPass’]);  
  62.         $this->db->exec(‘SET NAMES utf8’);  
  63.      }  
  64.   
  65.     /** 
  66.      +———————————————————- 
  67.      * 卸载字典 
  68.      +———————————————————- 
  69.      * @static 
  70.      * @access public  
  71.      +———————————————————- 
  72.      * @param string $src 字典源 
  73.      +———————————————————- 
  74.      * @return void 
  75.      +———————————————————- 
  76.      */  
  77.      function closeDict() {  
  78.         $this->db=null;  
  79.      }  
  80.   
  81.     /** 
  82.      +———————————————————- 
  83.      * 在字典中查找字串.提供sqlite版本作为参考,用户可以自己扩展 
  84.      +———————————————————- 
  85.      * @static 
  86.      * @access public  
  87.      +———————————————————- 
  88.      * @param string $string 待查找的字符串 
  89.      +———————————————————- 
  90.      * @return bool 
  91.      +———————————————————- 
  92.      */  
  93.      function findinDict($string) {  
  94.         $this->querytimes++;  
  95.         $sql = "SELECT `word` FROM `dict` where `word`=‘".$string."’ limit 1"; 
  96.         $rs = $this->db->query($sql); 
  97.         if ($row=$rs->fetch(PDO::FETCH_ASSOC)) 
  98.             return true; 
  99.         else 
  100.             return false; 
  101.      } 
  102.  
  103.     /** 
  104.      +———————————————————- 
  105.      * 用中英文标点对句子进行粗分,划分成短句 
  106.      +———————————————————- 
  107.      * @static 
  108.      * @access public  
  109.      +———————————————————- 
  110.      * @param string $sentence 完整的句子 
  111.      * @param string $minSen 通过标点断句最短的词组长度 
  112.      * @param string $saveInter 是否保留标点符号 
  113.      * @param string $encoding 文字编码,默认为utf-8 
  114.      +———————————————————- 
  115.      * @return array 
  116.      +———————————————————- 
  117.      */ 
  118.      function cnSplit($sentence, $minSen, $saveInter, $encoding) { 
  119.         $len = mb_strlen($sentence,$encoding); 
  120.         $substring = array(); 
  121.         $cnTmpStr = "";  
  122.         $enTmpStr = ""; 
  123.  
  124.         for($i=0;$i<$len;$i++) 
  125.         { 
  126.             $char = mb_substr($sentence,$i,1,$encoding); 
  127.             if(in_array($char,$this->sign)) 
  128.             { 
  129.                 if($cnTmpStr != "") 
  130.                 { // 一连串的中文放入待分词的词组 
  131.                     if(mb_strlen(trim($cnTmpStr),$encoding)<=$minSen) // 遇到标点了,根据设置的标点断句最短的词组长度判断是否直接分词 
  132.                         $substring[] = array(trim($cnTmpStr),’1′); 
  133.                     else 
  134.                         $substring[] = array(trim($cnTmpStr),’0′); 
  135.                     $cnTmpStr = "";  
  136.                 }  
  137.   
  138.                 if($enTmpStr != "") 
  139.                 { // 一连串的英语字母或数字可以直接返回分词结果 
  140.                     $substring[] = array(trim($enTmpStr),’1′); 
  141.                     $enTmpStr = ""; 
  142.                 } 
  143.  
  144.                 if($saveInter) // 如果要保留标点可以直接返回分词结果 
  145.                     $substring[] = array($char,’1′); 
  146.             } 
  147.             else if(in_array($char,$this->enChar)) 
  148.             { 
  149.                 if($cnTmpStr != "") 
  150.                 { // 遇到英文或数字了,可以给中文句子断句了 
  151.                     if(mb_strlen(trim($cnTmpStr),$encoding)<=$minSen) // 遇到标点了,根据设置的标点断句最短的词组长度判断是否直接分词 
  152.                         $substring[] = array(trim($cnTmpStr),’1′); 
  153.                     else 
  154.                         $substring[] = array(trim($cnTmpStr),’0′); 
  155.                     $cnTmpStr = ""; 
  156.                 } 
  157.  
  158.                 $enTmpStr .= $char; 
  159.             } 
  160.             else 
  161.             { 
  162.                 if($enTmpStr != "") 
  163.                 { // 遇到中文了,可以给英文句子或数字断句了 
  164.                     $substring[] = array(trim($enTmpStr),’1′); 
  165.                     $enTmpStr = ""; 
  166.                 } 
  167.  
  168.                 $cnTmpStr .= $char; 
  169.             } 
  170.         } 
  171.          
  172.         // 追加没有添加到子句中的中英文句子 
  173.         if($cnTmpStr != "") {  
  174.             if($enTmpStr == "" && mb_strlen(trim($cnTmpStr),$encoding)<=$minSen) // 要判断一下后面没有英文词组,这样句子是在没有标点符号的情况下结束了 
  175.                 $substring[] = array(trim($cnTmpStr),’1′); 
  176.             else 
  177.                 $substring[] = array(trim($cnTmpStr),’0′); 
  178.         } 
  179.         if($enTmpStr != "") $substring[] = array(trim($enTmpStr),’1′); 
  180.  
  181.         return $substring; 
  182.      } 
  183.  
  184.      /** 
  185.      +———————————————————- 
  186.      * 分词函数 
  187.      +———————————————————- 
  188.      * @static 
  189.      * @access public  
  190.      +———————————————————- 
  191.      * @param string $sentence 待分词的句子 
  192.      * @param string $maxlen 每次取子串最长字数,默认为8个字.越大分词越慢,但是越准确 
  193.      * @param string $minSen 通过标点断句最短的词组长度 
  194.      * @param string $saveSingle 是否保留不能组词的单个的字 
  195.      * @param string $saveInter 是否保留标点符号 
  196.      * @param string $encoding 文字编码,默认为utf-8 
  197.      * @param string $dict 字典的连接字符串 
  198.      +———————————————————- 
  199.      * @return array 
  200.      +———————————————————- 
  201.      */ 
  202.      function segment($sentence,$pdo=array(‘dbType’=>’mysql’,’dbHost’=>’localhost’,’dbName’=>’furyee’,’dbUser’=>’root’,’dbPass’=>’root’),$maxlen = 8, $minSen = 3, $saveSingle = false, $saveInter = false, $encoding=’utf-8′) { 
  203.         $this->openDict($pdo); // 挂载字典 
  204.          
  205.         $this->result = array(); 
  206.         $this->querytimes = 0; 
  207.  
  208.         $subSens = $this->cnSplit($sentence, $minSen, $saveInter, $encoding); //使用标点将长句分成短句 
  209.  
  210.         foreach($subSens as $item) 
  211.         { 
  212.             if($item[1] == ‘1’) 
  213.             { 
  214.                 $this->result[] = trim($item[0]); 
  215.                 continue; 
  216.             } 
  217.             else 
  218.                 $subSen = $item[0]; 
  219.  
  220.             $bFind = false; 
  221.             $i = $j = $N = 0; // i,j是扫描的指针.N是本次扫描的子串字数上界 
  222.             $M = $maxlen; // 每次取子串最长字数,默认为8个字.M越大分词越慢,但是越准确 
  223.             $tmpStr = ”; //用来记录没有匹配的字,多个连续的未匹配的字认为组合成一个词. 
  224.             $sub_str = ”; //每次取的子串 
  225.  
  226.             $senLen = mb_strlen($subSen,$encoding); //字符串长度 
  227.              
  228.             while($i < $senLen) { 
  229.                 $N = ($i+$M) < $senLen ? $M : $senLen-$i; 
  230.                 //N是本次扫描的子串字数上界 
  231.                 $bFind = false; 
  232.                 for($j = $N; $j > 0; $j–) { 
  233.                     //取子串到字典中匹配 
  234.                     $sub_str = mb_substr($subSen,$i,$j,$encoding); //从$i指的地方开始,取$j的长度 
  235.  
  236.                     if($this->findinDict($sub_str)) { 
  237.                         // 字典中有该词 
  238.                         if(mb_strlen($tmpStr,$encoding) < 2 && !$saveSingle) //临时字符串中只有一个字或没有词 
  239.                             $tmpStr = ""; //清空它  
  240.                         else if($tmpStr != "") 
  241.                         { 
  242.                             $this->result[] = $tmpStr; //多个连续的没有匹配的字认为他组成一个生词 
  243.                             $tmpStr = ""; 
  244.                         } 
  245.  
  246.                         $this->result[] = $sub_str; 
  247.  
  248.                         $bFind = true; 
  249.                         $i+=$j; //指针后移 
  250.                         break; 
  251.                     } 
  252.                 } 
  253.  
  254.                 if(!$bFind) { 
  255.                     if(in_array($sub_str,$this->highfreq)) //当前单个字无法匹配,而且它是高频词 
  256.                     { 
  257.                         if(mb_strlen($tmpStr,$encoding) ==1 && !$saveSingle) 
  258.                         //临时字符串中只有一个字,遇到高频词可以进行断句,所以要判断一下临时队列 
  259.                             $tmpStr = ""; //清空它  
  260.                         else if($tmpStr != "") 
  261.                         { 
  262.                             $this->result[] = $tmpStr; //多个连续的没有匹配的字认为他组成一个生词 
  263.                             $tmpStr = ""; 
  264.                         } 
  265.  
  266.                         if($saveSingle) // 如果要保留单个的高频字,将它保留下来,否则剔除 
  267.                             $this->result[] = $sub_str; 
  268.                     } 
  269.                     else 
  270.                         $tmpStr .= $sub_str; //不是标点,是一个没有匹配的单个的字 
  271.                     $i++; 
  272.                 } 
  273.             } 
  274.             if($tmpStr !="" ) $this->result[] = $tmpStr; // 扫描结束,临时队列还有词,那应该是最后面无法进行分词的一些字 
  275.         } 
  276.         $this->closeDict(); //卸载字典 
  277.         return $this->result; 
  278.      } 
  279.  
  280.     function zhcode($sentence,$pdo=array(‘dbType’=>’mysql’,’dbHost’=>’localhost’,’dbName’=>’furyee’,’dbUser’=>’root’,’dbPass’=>’root’),$maxlen = 8, $minSen = 3, $saveSingle = false, $saveInter = false, $encoding=’utf-8′) 
  281.     { 
  282.         $val=”; 
  283.         $arr=$this->segment($sentence,$pdo,$maxlen,$minSen,$saveSingle,$saveInter,$encoding); 
  284.          
  285.         $str=implode(‘ ‘,$arr); 
  286.         $strlen=mb_strlen($str,$encoding); 
  287.          
  288.         for($i=0;$i<$strlen;$i++){ 
  289.             $tmpstr=mb_substr($str,$i,1,$encoding);          
  290.             if(strlen($tmpstr)==1){ 
  291.                 $val.=$tmpstr; 
  292.             }else{ 
  293.                 //echo $tmpstr.'<br>’; 
  294.                 $tmpstr=iconv(‘UTF-8′,’GB2312’,$tmpstr); 
  295.                 $str_qwm = sprintf("%02d%02d",ord($tmpstr[0])-160,ord($tmpstr[1])-160);  
  296.                 //echo iconv(‘GB2312′,’UTF-8′,$tmpstr).$str_qwm.'<br>’;  
  297.                 $val.=$str_qwm;   
  298.             }  
  299.         }  
  300.           
  301.         return array($val,$arr);  
  302.     }  
  303. }  
  304. ?>  

 

 

演示文件: fc.php

 

PHP代码
  1. <?php  
  2. $starttime = ExecTime();  
  3. include(‘WordSegment.class.php’);  
  4. $str=‘冻番茄www.phpd.cn<p>现在市面上的樱花啊,爆米花的笔都可以画出美丽可爱的立体图案,可以装饰手机什么的,但是价钱贵,还不方便,比方说爆米花的,就要通过加热才会有效果.</p><p>最好有一种写出来就是爆米花的效果的笔.那就最好了,最好还可以通过不停的温度有不同的颜色(就像会变色的手表)和效果……</p><p><img src="/upload/image/2008-09-01/2008090104363891/55a19b38ee7f6671e64b7ee46feb2b0a.jpg" alt="" /></p>’;  
  5.   
  6. $ws = new WordSegment; // 实例化一个分词类的对象  
  7. $result = $ws->zhcode($str);  
  8. print_r($result);  
  9. $totaltime =ExecTime()-$starttime ;  
  10. echo "<BR><BR><BR>分词时间: $totaltime 秒<br><br>www.phpd.cn 冻番茄";  
  11. function ExecTime(){  
  12.     $time = explode(" ", microtime());  
  13.     $usec = (double)$time[0];  
  14.     $sec = (double)$time[1];  
  15.     return $sec + $usec;  
  16. }  
  17. ?>