1,CI框架开发,mvc思想还不错,其自己实现的cookie,session脱离框架之后使用起来不方便;
2,当心mysql_pconnect[持久连接,不建议使用],mysql_connect的释放结果集,释放连接。
3,  apache,php配置,数据库是否使用持久连接。
4,  firefox的中文cookie问题,使用php的escape。

文件包介绍:
db : php mysql封装数据库访问;
smtp:建立smtp发送mail,不用安装smtp server;
template:smary6.2使用;
xml:解析xml。

/Files/xiaomage234/php-tools.rar
posted @ 2009-02-25 11:35 小马歌 阅读(77) | 评论 (0)编辑 收藏
 

processlist命令的输出结果显示了有哪些线程在运行,可以帮助识别出有问题的查询语句,两种方式使用这个命令。

1.       进入mysql/bin目录下输入mysqladmin processlist;

2.       启动mysql,输入show processlist;

如果有 SUPER 权限,则可以看到全部的线程,否则,只能看到自己发起的线程(这是指,当前对应的MySQL帐户运行的线程)。

得到数据形式如下(只截取了三条):

mysql> show processlist;

+-----+-------------+--------------------+-------+---------+-------+----------------------------------+----------

| Id | User| Host            | db| Command | Time| State    | Info                                                                                           

+-----+-------------+--------------------+-------+---------+-------+----------------------------------+----------

|207|root |192.168.0.20:51718 |mytest | Sleep  | 5  |       | NULL                                                                                                 

|208|root |192.168.0.20:51719 |mytest | Sleep    | 5    |        | NULL        

|220|root|192.168.0.20:51731 |mytest |Query    | 84   | Locked|

select bookname,culture,value,typefrom book where id=001

先简单说一下各列的含义和用途,第一列,id,不用说了吧,一个标识,你要kill一个语句的时候很有用。user列,显示单前用户,如果不是root,这个命令就只显示你权限范围内的sql语句。host列,显示这个语句是从哪个ip的哪个端口上发出的。呵呵,可以用来追踪出问题语句的用户。db列,显示这个进程目前连接的是哪个数据库command列,显示当前连接的执行的命令,一般就是休眠(sleep),查询(query),连接(connect)。time列,此这个状态持续的时间,单位是秒。state列,显示使用当前连接的sql语句的状态,很重要的列,后续会有所有的状态的描述,请注意,state只是语句执行中的某一个状态,一个sql语句,已查询为例,可能需要经过copying to tmp tableSorting resultSending data等状态才可以完成,info列,显示这个sql语句,因为长度有限,所以长的sql语句就显示不全,但是一个判断问题语句的重要依据。

这个命令中最关键的就是state列,mysql列出的状态主要有以下几种:

  Checking table
 正在检查数据表(这是自动的)。

 Closing tables
 正在将表中修改的数据刷新到磁盘中,同时正在关闭已经用完的表。这是一个很快的操作,如果不是这样的话,就应该确认磁盘空间是否已经满了或者磁盘是否正处于重负中。

 Connect Out
 复制从服务器正在连接主服务器。

 Copying to tmp table on disk
 由于临时结果集大于 tmp_table_size,正在将临时表从内存存储转为磁盘存储以此节省内存。

 Creating tmp table
 正在创建临时表以存放部分查询结果。

 deleting from main table
 服务器正在执行多表删除中的第一部分,刚删除第一个表。

 deleting from reference tables
 服务器正在执行多表删除中的第二部分,正在删除其他表的记录。

 Flushing tables
 正在执行 FLUSH TABLES,等待其他线程关闭数据表。

 Killed
 发送了一个kill请求给某线程,那么这个线程将会检查kill标志位,同时会放弃下一个kill请求。MySQL会在每次的主循环中检查kill标志位,不过有些情况下该线程可能会过一小段才能死掉。如果该线程程被其他线程锁住了,那么kill请求会在锁释放时马上生效。

 Locked
 被其他查询锁住了。

 Sending data
 正在处理 SELECT 查询的记录,同时正在把结果发送给客户端。

 Sorting for group
 正在为 GROUP BY 做排序。

 Sorting for order
 正在为 ORDER BY 做排序。

 Opening tables
 这个过程应该会很快,除非受到其他因素的干扰。例如,在执 ALTER TABLE LOCK TABLE 语句行完以前,数据表无法被其他线程打开。正尝试打开一个表。

 Removing duplicates
 正在执行一个 SELECT DISTINCT 方式的查询,但是MySQL无法在前一个阶段优化掉那些重复的记录。因此,MySQL需要再次去掉重复的记录,然后再把结果发送给客户端。

 Reopen table
 获得了对一个表的锁,但是必须在表结构修改之后才能获得这个锁。已经释放锁,关闭数据表,正尝试重新打开数据表。

 Repair by sorting
 修复指令正在排序以创建索引。

 Repair with keycache
 修复指令正在利用索引缓存一个一个地创建新索引。它会比 Repair by sorting 慢些。

 Searching rows for update
 正在讲符合条件的记录找出来以备更新。它必须在 UPDATE 要修改相关的记录之前就完成了。

 Sleeping
 正在等待客户端发送新请求
.
 
System lock
 正在等待取得一个外部的系统锁。如果当前没有运行多个 mysqld 服务器同时请求同一个表,那么可以通过增加 --skip-external-locking参数来禁止外部系统锁。

 Upgrading lock
 INSERT DELAYED 正在尝试取得一个锁表以插入新记录。

 Updating
 正在搜索匹配的记录,并且修改它们。

 User Lock
 正在等待 GET_LOCK()

 Waiting for tables
 该线程得到通知,数据表结构已经被修改了,需要重新打开数据表以取得新的结构。然后,为了能的重新打开数据表,必须等到所有其他线程关闭这个表。以下几种情况下会产生这个通知:FLUSH TABLES tbl_name, ALTER TABLE, RENAME TABLE, REPAIR TABLE, ANALYZE TABLE, OPTIMIZE TABLE

 waiting for handler insert
 INSERT DELAYED 已经处理完了所有待处理的插入操作,正在等待新的请求。

 大部分状态对应很快的操作,只要有一个线程保持同一个状态好几秒钟,那么可能是有问题发生了,需要检查一下。
 还有其他的状态没在上面中列出来,不过它们大部分只是在查看服务器是否有存在错误是才用得着。

posted @ 2009-02-25 11:23 小马歌 阅读(130) | 评论 (0)编辑 收藏
 
$array 是存储返回内容集得变量名字

mysql_fetch_row返回得要用
$array[0],$array[1]…… 这样得格式调用

mysql_fetch_array(返回索引数组+关联数组)
即可以用 $array[0],$array[1]…… 这样得格式调用
也可以用 $array['字段名1'],$array['字段名2']…… 这样得格式调用

mysql_fetch_object 返回对象格式
$array->字段名1,$array->字段名2…… 这样调用

以下是摘自官网的详细说明:
1、
mysql_fetch_object
返回类资料。

语法: object mysql_fetch_object(int result, int [result_typ]);

返回值: 类

函数种类: 数据库功能

内容说明 

本函数用来将查询结果 result 拆到类变量中。使用方法和 mysql_fetch_array() 几乎相同,不同的地方在于本函数返回资料是类而不是数组。若 result 没有资料,则返回 false 值。另外治募 注意的地方是,取回的类资料的索引只能是文字而不能用数字,这是因为类的特性。类资料的特性中所有的属性 (property) 名称都不能是数字,因此只好乖乖使用文字字符串当索引了。参数 result_typ是一个常量值,有以下几种常量 MYSQL_ASSOC、MYSQL_NUM 与 MYSQL_BOTH。关于速度方面,本函数的处理速度几乎和 mysql_fetch_row() 及 mysql_fetch_array() 二函数差不多,要用哪个函数还是看使用的需求决定。

使用范例 

下面的例子示范如使用返回的类。

<?php 
mysql_connect($host,$user,$password);
$result = mysql_db_query("MyDatabase","select * from test");
while($row = mysql_fetch_object($result)) {
    echo $row->user_id;
    echo $row->fullname;
}
mysql_free_result($result);
?> 

2、
mysql_fetch_array
返回数组资料。

语法: array mysql_fetch_array(int result, int [result_typ]);

返回值: 数组

函数种类: 数据库功能

内容说明 

本函数用来将查询结果 result 拆到数组变量中。若 result 没有资料,则返回 false 值。而本函数可以说是 mysql_fetch_row() 的加强函数,除可以将返回列及数字索引放入数组之外,还可以将文字索引放入数组中。若是好几个返回字段都是相同的文字名称,则最后一个置入的字段有效,解决方法是使用数字索引或者为这些同名的字段 (column) 取别名 (alias)。治募 注意的是使用本函数的处理速度其实不会比 mysql_fetch_row() 函数慢,要用哪个函数还是看使用的需求决定。参数 result_typ 是一个常量值,有以下几种常量 MYSQL_ASSOC、MYSQL_NUM 与 MYSQL_BOTH。

使用范例 

<?php
mysql_connect($host,$user,$password);
$result = mysql_db_query("database","select * from table");
while($row = mysql_fetch_array($result)) {
echo $row["user_id"];
echo $row["fullname"];
}
mysql_free_result($result);
?>

3、
MySQL 数据库函数库

mysql_fetch_row
返回单列的各字段。

语法: array mysql_fetch_row(int result);

返回值: 数组

函数种类: 数据库功能

内容说明 

本函数用来将查询结果 result 之单列拆到数组变量中。数组的索引是数字索引,第一个的索引值是 0。若 result 没有资料,则返回 false 值。
posted @ 2009-02-25 11:21 小马歌 阅读(602) | 评论 (0)编辑 收藏
 

from  :  http://gudai.cnblogs.com/articles/294580.html
2005-12-10。从下午12点奋斗到晚上9点。
2005-12-11。根据唠叨的回帖,更新了转换的算法。对于那篇unicode编码的faq.我总算理解了整个转换的过程。理解了这个公式。

参考文章http://tech.163.com/05/0516/10/1JS9KEGA00091589.html
UTF编码

  UTF-8就是以8位为单元对UCS进行编码。从UCS-2到UTF-8的编码方式如下:

UCS-2编码(16进制) UTF-8 字节流(二进制)
0000 - 007F 0xxxxxxx
0080 - 07FF 110xxxxx 10xxxxxx
0800 - FFFF 1110xxxx 10xxxxxx 10xxxxxx

  例如“汉”字的Unicode编码是6C49。6C49在0800-FFFF之间,所以肯定要用3字节模板了:1110xxxx 10xxxxxx 10xxxxxx。将6C49写成二进制是:0110 110001 001001, 用这个比特流依次代替模板中的x,得到:11100110 10110001 10001001,即E6 B1 89。




终于将unicode和utf8互转搞定。


如果utf-8编码的字符ch是3个字节。xx yy zz
将xx和1F AND 操作得到 a
将yy和7F AND 操作得到 b
将zz和7F AND 操作得到 c

(64a+b)*64+c = ch(unicode编码)

echo.php没什么。就是几个函数。

<?php
require_once("echo.php");

$data = "大闹西奴xx x8890.-_奴";
echo(urlencode($data));echo("<br/>");
//写入unicode文件
$ucs2data = utf8ToUnicode($data,"little");
$endian = chr(0xFE).chr(0xFF);
$endian =  chr(0xFF).chr(0xFE);
$rt = file_put_contents ( "ucs2.txt", $endian.$ucs2data);
                //19:32,utf8toUnicode函数ok.
                //20:09。发现little endian 和big endian问题。并解决。
                //big endian 方式存入的unicode字符串,ue和editplus均不能
                //识别。只有notepad正常识别。

$rt = file_put_contents ( "usc2ys_data.txt", $ucs2_ysdata);
//写入utf8文件
$utf8data = unicodeToUtf8($ucs2data);   // 20:52. 将字串转回utf8码ok.
$rt = file_put_contents ( "utf8.txt", $utf8data);
echo(urlencode($utf8data));echo("<br/>");

$esc = utf8Escape($data);
echot($esc);
$esc = phpEscape($data);
echot($esc);
$unesc = phpUnescape($esc);
echot($unesc);


/**
* 此函数将utf8编码字串转为unicode编码字符串
* 参数 str ,utf8编码的字符串。
* 参数 order,存放数据格式,是big endian还是little endian,默认的unicode存放次序是little.
* 如:"大"的unicode码是 5927。little方式存放即为:27 59 。big方式则顺序不变:59 27.
* little 存放格式文件的开头均需有FF FE。big 存放方式的文件开头为 FE FF。否则。将会产生严重混乱。
* 本函数只转换字符,不负责增加头部。
* iconv转换过来的字符串是 big endian存放的。
* 返回 ucs2string , 转换过的字符串。
* 感谢唠叨(xuzuning)
*/
function utf8ToUnicode($str,$order="little")
{
  $ucs2string ="";
    $n=strlen($str);
    for ($i=0;$i<$n ;$i++ ) {
  $v = $str[$i];
  $ord = ord($v);
  if( $ord<=0x7F){ //  0xxxxxxx 
     if ($order=="little") {
       $ucs2string .= $v.chr(0); 
   }
   else {
       $ucs2string .= chr(0).$v; 
   }
  }
  elseif ($ord<0xE0 && ord($str[$i+1])>0x80) {  //110xxxxx 10xxxxxx
   $a = (ord($str[$i]) & 0x3F )<<6;
   $b =  ord($str[$i+1]) & 0x3F ;
   $ucsCode = dechex($a+$b);   //echot($ucsCode);
   $h = intval(substr($ucsCode,0,2),16);
   $l  =  intval(substr($ucsCode,2,2),16);
   if ($order=="little") {
       $ucs2string   .= chr($l).chr($h);
   }
   else {
        $ucs2string   .= chr($h).chr($l);
   }
   $i++;
  }elseif ($ord<0xF0  && ord($str[$i+1])>0x80  && ord($str[$i+2])>0x80) { //1110xxxx 10xxxxxx 10xxxxxx
      $a = (ord($str[$i]) & 0x1F)<<12;    
   $b = (ord($str[$i+1]) & 0x3F )<<6;
   $c =  ord($str[$i+2]) & 0x3F ;
   $ucsCode = dechex($a+$b+$c);   //echot($ucsCode);
   $h = intval(substr($ucsCode,0,2),16);
   $l  =  intval(substr($ucsCode,2,2),16);
   if ($order=="little") {
       $ucs2string   .= chr($l).chr($h);
   }
   else {
        $ucs2string   .= chr($h).chr($l);
   }   
   $i +=2;
  }
    }
 return $ucs2string;  
} // end func

/*
* 此函数将unicode编码字串转为utf8编码字符串
* 参数 str ,unicode编码的字符串。
* 参数 order ,unicode字串的存放次序,为big endian还是little endian.
* 返回 utf8string , 转换过的字符串。
*
*/
function unicodeToUtf8($str,$order="little")
{
 $utf8string ="";
    $n=strlen($str);
    for ($i=0;$i<$n ;$i++ ) {
  if ($order=="little") {
      $val = dechex(ord($str[$i+1])).dechex(ord($str[$i]));
  }
  else {
   $val = dechex(ord($str[$i])).dechex(ord($str[$i+1]));
  }
  $val = intval($val,16); //由于上次的.连接,导致$val变为字符串,这里得转回来。
  $i++; //两个字节表示一个unicode字符。
  $c = "";
  if($val < 0x7F){        // 0000-007F
   $c .= chr($val);
  }elseif($val < 0x800) { // 0080-0800
   $c .= chr(0xC0 | ($val / 64));
   $c .= chr(0x80 | ($val % 64));
  }else{                // 0800-FFFF
   $c .= chr(0xE0 | (($val / 64) / 64));
   $c .= chr(0x80 | (($val / 64) % 64));
   $c .= chr(0x80 | ($val % 64));
   //echot($c);
  }  
  $utf8string .= $c;
    }
 return $utf8string;
} // end func

 

/*
* 将utf8编码的字符串编码为unicode 码型,等同escape
* 之所以只接受utf8码,因为只有utf8码和unicode之间有公式转换,其他的编码都得查码表来转换。
* 不知道查找utf8码的正则是否完全正确。迷茫ing
* 虽然调用utf2ucs对每个字符进行码值计算。效率过低。然而,代码清晰,要是把那个计算过程嵌入。
* 代码就不太容易阅读了。
*/
function utf8Escape($str) {
  preg_match_all("/[\xC0-\xE0].|[\xE0-\xF0]..|[\x01-\x7f]+/",$str,$r);
  //prt($r);
  $ar = $r[0];
  foreach($ar as $k=>$v) {
 $ord = ord($v[0]);
    if( $ord<=0x7F)
      $ar[$k] = rawurlencode($v);
    elseif ($ord<0xE0) { //双字节utf8码
      $ar[$k] = "%u".utf2ucs($v);
    }
  elseif ($ord<0xF0) { //三字节utf8码
      $ar[$k] = "%u".utf2ucs($v);
 }
  }//foreach
  return join("",$ar);
}

/**
*
* 把utf8编码字符转为ucs-2编码
* 参数 utf8编码的字符。
* 返回 该字符的unicode码值。知道了码值,你就可以使用chr将字符弄出来了。
*
*  原理:unicode转为utf-8码的算法是。头部固定位或。
 该过程的逆向算法就是这个函数了,头部固定位反位与。
*/

function utf2ucs($str){
 $n=strlen($str);
 if ($n=3) {
     $highCode = ord($str[0]);    
  $midCode = ord($str[1]);
     $lowCode = ord($str[2]);
  $a   = 0x1F & $highCode;
  $b   = 0x7F & $midCode;
  $c   = 0x7F & $lowCode;
  $ucsCode = (64*$a + $b)*64 + $c; 
 }
 elseif ($n==2) {
    $highCode = ord($str[0]);    
     $lowCode = ord($str[1]);
  $a   = 0x3F & $highCode;  //0x3F是0xC0的补数
  $b   = 0x7F & $lowCode;  //0x7F是0x80的补数
  $ucsCode = 64*$a + $b; 
 }
 elseif($n==1) {
     $ucscode = ord($str);
 }
 return dechex($ucsCode);
}

 


/*
* 用处 :此函数用来逆转javascript的escape函数编码后的字符。
* 关键的正则查找我不知道有没有问题.
* 参数:javascript编码过的字符串。
* 如:unicodeToUtf8("%u5927")= 大
* 2005-12-10
*
*/
function phpUnescape($escstr){
  preg_match_all("/%u[0-9A-Za-z]{4}|%.{2}|[0-9a-zA-Z.+-_]+/",$escstr,$matches); //prt($matches);
  $ar = &$matches[0];
  $c = "";
  foreach($ar as $val){
 if (substr($val,0,1)!="%") { //如果是字母数字+-_.的ascii码
     $c .=$val;
 }
 elseif (substr($val,1,1)!="u") { //如果是非字母数字+-_.的ascii码
  $x = hexdec(substr($val,1,2));
     $c .=chr($x);
 }
 else { //如果是大于0xFF的码
  $val = intval(substr($val,2),16);
  if($val < 0x7F){        // 0000-007F
   $c .= chr($val);
  }elseif($val < 0x800) { // 0080-0800
   $c .= chr(0xC0 | ($val / 64));
   $c .= chr(0x80 | ($val % 64));
  }else{                // 0800-FFFF
   $c .= chr(0xE0 | (($val / 64) / 64));
   $c .= chr(0x80 | (($val / 64) % 64));
   $c .= chr(0x80 | ($val % 64));
  }
 }
  }
  return $c;
}

 

/*
* 等同escape
* 来自网上。本文件其他几个函数都参考了这个函数里面的关键算法。
*/
function phpEscape($str,$encode="") {
  if ($encode=="" && !(function_exists("mb_detect_encoding"))) {
      echo "error You must enter the string's encoding or extend the php for mb_string";
   return ;
  }
  elseif($encode=="") {
   echo "Use mb_string function to detect the string's encoding <br/>";
      $encode = mb_detect_encoding($str);
  }
  preg_match_all("/[\xC0-\xE0].|[\xE0-\xF0]..|[\x01-\x7f]+/",$str,$r);
  //prt($r);
  $ar = $r[0];
  foreach($ar as $k=>$v) {
 $ord = ord($v[0]);
    if( $ord<=0x7F)
      $ar[$k] = rawurlencode($v);
    elseif ($ord<0xE0) {
      $ar[$k] = "%u".bin2hex(iconv($encode,"UCS-2",$v));
    }
  elseif ($ord<0xF0) {
      $ar[$k] = "%u".bin2hex(iconv($encode,"UCS-2",$v));
 }
  }//foreach
  return join("",$ar);
}

?>

Posted on 2005-12-10 20:54 古代 阅读(698) 评论(2)  编辑 收藏 网摘 所属分类: wapphp

Feedback

#1楼 [楼主]   回复  引用  查看    

2006-09-12 22:24 by 古代的专栏      
上文的phpescape函数是错的,补上正确的

/*
* 等同escape , 只能转gbk编码的汉字并在gb2312的网页中被unescape
* gbk汉字: 第一:0x81-0xFE 第二:0x40-0xFE
*/
function phpEscape( $str )
{
$chars = preg_split('//', $str, -1 ) ; //pr($chars);
$n = count( $chars )-1 ;
for($i=1;$i<$n ;$i++ ) {
$char = $chars[$i];
$ord = ord( $char ); //echo $ord . " -- ".chr($ord)." -- $i<br>";
if( $ord<=0x7F){
$ar .= rawurlencode( $char );
}else{
$ar .= "%u".bin2hex( iconv( 'gbk' ,"UCS-2",$chars[$i].$chars[$i+1] ) );
$i++;
}
}//foreach
return $ar;
}
posted @ 2009-02-25 11:19 小马歌 阅读(1013) | 评论 (0)编辑 收藏
 
AddSlashes: 字符串加入斜线。
bin2hex: 二进位转成十六进位。
Chop: 去除连续空白。
Chr: 返回序数值的字符。
chunk_split: 将字符串分成小段。
convert_cyr_string: 转换古斯拉夫字符串成其它字符串。
crypt: 将字符串用 DES 编码加密。
echo: 输出字符串。
explode: 切开字符串。
flush: 清出输出缓冲区。
get_meta_tags: 抽出文件所有 meta 标记的资料。
htmlspecialchars: 将特殊字符转成 HTML 格式。
htmlentities: 将所有的字符都转成 HTML 字符串。
implode: 将数组变成字符串。
join: 将数组变成字符串。
ltrim: 去除连续空白。
md5: 计算字符串的 MD5 哈稀。
nl2br: 将换行字符转成

Ord: 返回字符的序数值。
parse_str: 解析 query 字符串成变量。
print: 输出字符串。
printf: 输出格式化字符串。
quoted_printable_decode: 将 qp 编码字符串转成 8 位字符串。
QuoteMeta: 加入引用符号。
rawurldecode: 从 URL 专用格式字符串还原成普通字符串。
rawurlencode: 将字符串编码成 URL 专用格式。
setlocale: 配置地域化信息。
similar_text: 计算字符串相似度。
soundex: 计算字符串的读音值
sprintf: 将字符串格式化。
strchr: 寻找第一个出现的字符。
strcmp: 字符串比较。
strcspn: 不同字符串的长度。
strip_tags: 去掉 HTML 及 PHP 的标记。
StripSlashes: 去掉反斜线字符。
strlen: 取得字符串长度。
strrpos: 寻找字符串中某字符最后出现处。
strpos: 寻找字符串中某字符最先出现处。
strrchr: 取得某字符最后出现处起的字符串。
strrev: 颠倒字符串。
strspn: 找出某字符串落在另一字符串遮罩的数目。
strstr: 返回字符串中某字符串开始处至结束的字符串。
strtok: 切开字符串。
strtolower: 字符串全转为小写。
strtoupper: 字符串全转为大写。
str_replace: 字符串取代。
strtr: 转换某些字符。
substr: 取部份字符串。
trim: 截去字符串首尾的空格。
ucfirst: 将字符串第一个字符改大写。
ucwords: 将字符串每个字第一个字母改大写。
posted @ 2009-02-19 12:53 小马歌 阅读(125) | 评论 (0)编辑 收藏
 

今天写了一段代码,出现错误Cannot modify header information - headers already sent by
代码结构如下:
//一些数据库查询的操作之后,有一个redirect跳转

$class->load->model('shop/muser');
$id=$class->muser->getUserId($user,$pwd); //这里出了点问题
redirect('index');

codeigniter里的redirect()执行一个指定的利用header头文件实现跳转本地网址URL的操作,也就是类似header()的功能。
google之:“所有对header()函数有了解的人都知道,这个函数会发送一段文件头给浏览器,但是如果在使用这个函数之前已经有了任何输出(包括空输出 ,如空格,回车和换行)就会提示出错:”Header had all ready send by”!”
这种错误的原因是发送http头之前有输出。迷惑了,我的代码并没有任何输出呀?仔细检查了一下之前的操作,发现数据库查询是出了点问题,原因就在这,因为出问题后,会输出一些错误提示。在网上找的解决办法是在程序前面使用ob_start()函数,ob_start打开了缓冲区,要输出的内容就不会出现到浏览器,而是保留在服务器,直到你使用flush或者ob_end_flush才会输出,所以并不会有任何文件头输出的错误!
ob_start确实管用,但是要知道它同时欺骗了我,我认为我的程序很完美,根本意识不到自己犯下的错误,因为没有错误提示。


from:http://www.tonsh.net/blog/?p=24#more-24

posted @ 2009-02-18 16:15 小马歌 阅读(403) | 评论 (0)编辑 收藏
 
第一次看到中央三台的著名企业音乐电视展播是五粮液的《爱到春潮滚滚来》,当时的感觉就是三个字--太美了!后来又陆续看到了《仙林青梅》和康美制药拍的《康美之恋》,个人觉得已经远超过了广告本身的含义,达到了一种艺术的美的享受。且不管一个已经如此大牌的企业花巨资拍这样奢侈的广告片是否值得,也不管这些资金是否可以有更好的别的用武之地,做为观众,这几个音乐电视绝对值得我们用心去欣赏,感受唯美……
《爱到春潮滚滚来》
在线播放地址:http://vzone.xunlei.com/brand/29/opus/content622.html [提供.flv格式下载]
一江春水情不尽,我梦绕魂牵,一夜春雨梦不停,你多情缠绵
一朝春露万花开,我美丽无限,一日春风人心暖,你风情万千……
下载地址:http://www.ybtv.cc/xz/bong/wly/adccggl.rmvb

《康美之恋》
在线播放地址:http://vzone.xunlei.com/brand/28/opus/content621.html [提供.flv格式下载]
一条路,海角天涯,两颗心相依相伴
风吹不走誓言,雨打不湿浪漫……
下载地址:http://podcache.cctv.com/published1/2007/05/11/pub1178846647864.rmvb

《仙林青梅》
在线播放地址:http://vzone.xunlei.com/brand/29/opus/content623.html [提供.flv格式下载]
青山高,云水长,仙林青梅心儿醉
山山水水永不分,风风雨雨长相随……
下载地址:http://zhumin.chc.edu.cn/gq/仙林青梅(杨竹青).avi
posted @ 2009-02-07 10:35 小马歌 阅读(1835) | 评论 (1)编辑 收藏
 
描述:Blackbird是一个用于记录log信息的工具,有了它,你可以抛弃alert提示,你能方便的将它插入页面中,支持多浏览器。
地址:http://www.gscottolson.com/blackbirdjs/



下载包:/Files/xiaomage234/blackbirdjs.rar
posted @ 2009-02-06 10:14 小马歌 阅读(695) | 评论 (1)编辑 收藏
 

以前写过一个刷校内网的人气的工具,Java的(以后再也不行Java程序了),里面用到了验证码识别,那段代码不是我自己写的:-) 校内的验证是完全单色没有任何干挠的验证码,识别起来比较容易,不过从那段代码中可以看到基本的验证码识别方式。这几天在写一个程序的时候需要识别验证码,因为程序是Python写的自然打算用Python进行验证码的识别。
以前没用Python处理过图像,不太了解PIL(Python Image Library)的用法,这几天看了看PIL,发现它太强大了,简直和ImageMagic,PS可以相比了。(这里有PIL不错的文档)
由于上面的验证码是24位的jpeg图像,并且包含了噪点,所以我们要做的就是去噪和去色,我拿PS找了张验证码试了试,使用PS滤镜中的去噪效果还行,但是没有在PIL找到去噪的函数,后来发现中值过滤后可以去掉大部分的噪点,而且PIL里有现成的函数,接下来我试着直接把图像转换为单色,结果发现还是会有不过的噪点留了下来,因为中值过滤时把不少噪点淡化了,但转换为音色时这些噪点又被强化显示了,于是在中值过滤后对图像亮度进行加强处理,然后再转换为单色,这样验证码图片就变得比较容易识别了:


上面这些处理使用Python才几行:
PYTHON:
im = Image.open(image_name)
    im = im.filter(ImageFilter.MedianFilter())
    enhancer = ImageEnhance.Contrast(im)
    im = enhancer.enhance(2)
    im = im.convert('1')
    im.show()
接下来就是提取这些数字的字模,使用shell脚本下载100幅图片,抽出三张图片获取字模:
PYTHON:
#!/usr/bin/env python
#encoding=utf-8
 
import Image,ImageEnhance,ImageFilter
import sys
 
image_name = "./images/81.jpeg"
im = Image.open(image_name)
im = im.filter(ImageFilter.MedianFilter())
enhancer = ImageEnhance.Contrast(im)
im = enhancer.enhance(2)
im = im.convert('1')
#im.show()
                #all by pixel
s = 12          #start postion of first number
w = 10          #width of each number
h = 15          #end postion from top
t = 2           #start postion of top
 
im_new = []
#split four numbers in the picture
for i in range(4):
    im1 = im.crop((s+w*i+i*2,t,s+w*(i+1)+i*2,h))
    im_new.append(im1)
 
f = file("data.txt","a")
for k in range(4):
    l = []
    #im_new[k].show()
    for i in range(13):
        for j in range(10):
            if (im_new[k].getpixel((j,i)) == 255):
                l.append(0)
            else:
                l.append(1)
 
    f.write("l=[")
       
    n = 0
    for i in l:
        if (n%10==0):
            f.write("\n")
        f.write(str(i)+",")
        n+=1
    f.write("]\n")
把字模保存为list,用于接下来的匹配;
提取完字模后剩下来的就是对需要处理的图片进行与数据库中的字模进行匹配了,基本的思路就是看相应点的重合率,但是由于噪点的影响在对(6,8)(8,3)(5,9)的匹配时容易出错,俺自己针对已有的100幅图片数据采集进行分析,采用了双向匹配(图片与字模分别作为基点),做了半天的测试终于可以实现100%的识别率。
PYTHON:
#!/usr/bin/env python
#encoding=utf-8
 
import Image,ImageEnhance,ImageFilter
import Data
 
DEBUG = False
 
def d_print(*msg):
    global DEBUG
    if DEBUG:
        for i in msg:
            print i,
        print
    else:
        pass
 
 
def Get_Num(l=[]):
    min1 = []
    min2 = []
    for n in Data.N:
        count1=count2=count3=count4=0
        if (len(l) != len(n)):
            print "Wrong pic"
            exit()
        for i in range(len(l)):
            if (l[i] == 1):
                count1+=1
                if (n[i] == 1):
                    count2+=1
        for i in range(len(l)):
            if (n[i] == 1):
                count3+=1
                if (l[i] == 1):
                    count4+=1
        d_print(count1,count2,count3,count4)
 
        min1.append(count1-count2)
        min2.append(count3-count4)
    d_print(min1,"\n",min2)
    for i in range(10):
        if (min1[i] <= 2 or min2[i] <= 2):
            if ((abs(min1[i] - min2[i])) <10):
                return i
    for i in range(10):           
        if (min1[i] <= 4 or min2[i] <= 4):
            if (abs(min1[i] - min2[i]) <= 2):
                return i
 
    for i in range(10):
        flag = False
        if (min1[i] <= 3 or min2[i] <= 3):
            for j in range(10):
                if (j != i and (min1[j] <5 or min2[j] &lt;5)):
                    flag = True
                else:
                    pass
            if (not flag):
                return i
    for i in range(10):           
        if (min1[i] <= 5 or min2[i] <= 5):
            if (abs(min1[i] - min2[i]) <= 10):
                return i
    for i in range(10):
        if (min1[i] <= 10 or min2[i] <= 10):
            if (abs(min1[i] - min2[i]) <= 3):
                return i
 
#end of function Get_Num
 
def Pic_Reg(image_name=None):
    im = Image.open(image_name)
    im = im.filter(ImageFilter.MedianFilter())
    enhancer = ImageEnhance.Contrast(im)
    im = enhancer.enhance(2)
    im = im.convert('1')
    im.show()
                    #all by pixel
    s = 12          #start postion of first number
    w = 10          #width of each number
    h = 15          #end postion from top
    t = 2           #start postion of top
    im_new = []
    #split four numbers in the picture
    for i in range(4):
        im1 = im.crop((s+w*i+i*2,t,s+w*(i+1)+i*2,h))
        im_new.append(im1)
 
    s = ""
    for k in range(4):
        l = []
        #im_new[k].show()
        for i in range(13):
            for j in range(10):
                if (im_new[k].getpixel((j,i)) == 255):
                    l.append(0)
                else:
                    l.append(1)
       
        s+=str(Get_Num(l))
    return s
print Pic_Reg("./images/22.jpeg")
这里再提一下验证码识别的基本方法:截图,二值化、中值滤波去噪、分割、紧缩重排(让高矮统一)、字库特征匹配识别。
这里只是针对一般的验证码,高级验证码的识别这里有篇不错的文章,太复杂的话涉及的东西就多了,那俺就没兴趣了,人工智能(好恐怖),俺只喜欢简单的东西。
本文来源于可可熊的窝 http://cocobear.info/blog , 原文地址: http://cocobear.info/blog/2008/08/04/python-pic-recognize/

posted @ 2009-02-04 11:32 小马歌 阅读(2742) | 评论 (0)编辑 收藏
 
什么是 Groovy?
  Groovy 是 JVM 的一个替代语言 — 替代 是指可以用 Groovy 在 Java 平台上进行 Java 编程,使用方式基本与使用 Java 代码的方式相同。在编写新应用程序时,Groovy 代码能够与 Java 代码很好地结合,也能用于扩展现有代码。目前的 Groovy 版本是 1.5.4,在 Java 1.4 和 Java 5 平台上都能使用,也能在 Java 6 上使用。
  Groovy 的一个好处是,它的语法与 Java 语言的语法很相似。虽然 Groovy 的语法源于 Smalltalk 和 Ruby 这类语言的理念,但是可以将它想像成 Java 语言的一种更加简单、表达能力更强的变体。(在这点上,Ruby 与 Groovy 不同,因为它的语法与 Java 语法差异很大。)
  许多 Java 开发人员非常喜欢 Groovy 代码和 Java 代码的相似性。从学习的角度看,如果知道如何编写 Java 代码,那就已经了解 Groovy 了。Groovy 和 Java 语言的主要区别是:完成同样的任务所需的 Groovy 代码比 Java 代码更少。(有时候会少很多!)
Groovy 快捷方式
  开始使用 Groovy 时,您会发现它使日常的编程活动变得快了许多。完成本教程之后,您会了解更多的 Groovy 语法快捷方式。不过现在只需知道以下这些要点:
  Groovy 的松散的 Java 语法允许省略分号和修改符。
  除非另行指定,Groovy 的所有内容都为 public。
  Groovy 允许定义简单脚本,同时无需定义正规的class 对象。
  Groovy 在普通的常用 Java 对象上增加了一些独特的方法和快捷方式,使得它们更容易使用。
  Groovy 语法还允许省略变量类型。
Groovy 的新增特性
  虽然 Groovy 允许省略 Java 语法中的一些元素,但也增加了一些新特性,例如本地集合、内置的正则表达式和闭包。在标准的 Java 代码中,如果想要创建一个项列表,首先要导入<code>java.util.ArrayList</code>,然后程序化地初始化 <code>ArrayList</code> 实例,然后 再向实例中添加项。在 Groovy 中,列表和映射都内置在语法中 — 无需导入任何内容。正则表达式也不需要额外的导入或对象;它们可以通过特殊的 Groovy 语法来创建。
关于闭包
  对于任何 Java 开发人员来说,闭包都是一个令人兴奋的新技巧。这些神奇的构造将会包含在未来的 Java 发行版(很可能是 Java 7)中,成为正式的 Java 语法,但现在已经可以在 Groovy 中使用了。可以将闭包 想像为一个代码块,可以现在定义,以后再执行。可以使用这些强大的构造做许多漂亮的事,不过最著名的是简化迭代。使用 Groovy 之后,就有可能再也不需要编写Iterator 实例了。
  [table][tbody][/tbody][/table]
动态的 Groovy
  从技术上讲,Groovy 可能是您最近听说过的类型最松散的动态语言之一。从这个角度讲,Groovy 与 Java 语言的区别很大,Java 语言是一种固定类型语言。在 Groovy 中,类型是可选的,所以您不必输入String myStr = "Hello"; 来声明 String 变量。
  除此之外,Groovy 代码还能在运行时轻松地改变自己。这实际上意味着,能够在运行时轻松地为对象指定新方法和属性。这一编程领域称为元编程,Groovy 能够很好地支持这种编程方式。在学习本教程的过程中,您将了解到关于 Groovy 的动态性质的更多内容。现在惟一要补充的是,您会惊讶地发现,在 Groovy 会使操作 XML 或普通的 java.io.File 实例变得非常轻松。
一体两面
  用 Groovy 编写的任何内容都可以编译成标准的 Java 类文件并在 Java 代码中重用。类似地,用标准 Java 代码编写的内容也可以在 Groovy 中重用。所以,可以轻易地使用 Groovy 为 Java 代码编写单元测试。而且,如果用 Groovy 编写一个方便的小工具,那么也可以在 Java 程序中使用这个小工具。
  Groovy是用Java实现的开源脚本语言并且和它联系紧密.它需要JDK 1.4. Groovy向Java添加了许多Ruby和Python脚本语言的特性. Groovy的特性包括动态类型(dynamic typing), 闭包(closures),简单对象导航( easy object navigation)和更加简洁的Lists和Maps语法.
  Groovy是由James Strachan和Bob McWhirter创造的. James还参与了许多其他开源项目的开发,其中包括Jelly, dom4j, Jaxen, Betwixt和Maven. Bob是Jaxen和Drools (一个开源的面向对象的JAVA规则引擎) 的创始人.
  目前最新稳定版为Groovy1.5。这个Groovy版本包含了很多Java5的特性(Annotation,泛型,Enum...),并修正了很多错误。
posted @ 2009-02-04 10:47 小马歌 阅读(265) | 评论 (0)编辑 收藏
仅列出标题
共95页: First 上一页 72 73 74 75 76 77 78 79 80 下一页 Last