首先自我检讨一下..因为正则不过关,所以自己写的过滤条件基本失败了...
上网查的函数也看不懂,改了也出错....在csdn的各路神仙指点下,略微开了点窍...原问题帖链接现放出各个路子的函数,供各位已经死过还尚未死成的同志使用....
希望大家积极补充,把平时常用的方法帖出来基础函数
-----------------------------------------------------------------------------------
其实mysql和php自带很多函数可以处理字符问题,下面给出几个会经常用到的.
ps:由于php6开始不支持magic_quotes_gpc,所以下面的东西都是假设在magic_quotes_gpc=off的条件上(不知道php6会出什么新东西....)mysql_real_escape_string()
定义:函数转义 SQL 语句中使用的字符串中的特殊字符。
语法: mysql_real_escape_string(string,connection)
说明:本函数将 string 中的特殊字符转义,并考虑到连接的当前字符集,因此可以安全用于 mysql_query()。
由于实例代码过长,给出函数解释链接  w3school     phpnetaddSlashes()
定义:addslashes() 函数在指定的预定义字符前添加反斜杠。
语法:addslashes(string)
注释:默认情况下,PHP 指令 magic_quotes_gpc 为 on,对所有的 GET、POST 和 COOKIE 数据自动运行 addslashes()。不要对已经被 magic_quotes_gpc 转义过的字符串使用 addslashes(),因为这样会导致双层转义。遇到这种情况时可以使用函数 get_magic_quotes_gpc() 进行检测。
由于实例代码过长,给出函数解释链接  w3school    phpnet
相关函数
StripSlashes()去掉反斜线字符。(解释过滤字符时用)mb_convert_encoding()
PHP的内码转换函数
版本(PHP 4 >= 4.0.6, PHP 5)
这个函数可以将各种编码互相转换
相关链接 phpneticonv()
php内码转换函数,同上
因为iconv()在转换gb2312时的bug,所以要这样处理
iconv( "UTF-8", "gb2312//IGNORE" , $str)
ignore的意思是忽略转换时的错误,发现iconv在转换字符"—"到gb2312时会出错,如果没有ignore参数,所有该字符后面的字符串都无法被保存。
另外mb_convert_encoding没有这个bug,所以最好的写法是:
mb_convert_encoding($str,"gb2312", "UTF-8");
但是需要先enable mbstring 扩展库。
也可以把mysql数据库的collation设成utf-8就不用作转换了
三句mysql真言SET NAMES utf8;
SET CHARACTER SET utf8;
SET COLLATION_CONNECTION='utf8_general_ci';相关链接 phpnet
资料参考 link1  link2  link3自定函数1
-----------------------------------------------------------------------------------

网上找的转换函数,将GB2312进行转换的,修改为utf-8后转换错误,无法解析中文.....期待正则狂人...
<?php
function escape($str) {
         preg_match_all("/[\x80-\xff].|[\x01-\x7f]+/",$str,$r);
        $ar = $r[0];
        foreach($ar as $k=>$v) {
                 if(ord($v[0]) < 128)
                            $ar[$k] = rawurlencode($v);
                 else
                            $ar[$k] = "%u".bin2hex(iconv("GB2312","UCS-2",$v));
                                                     }
        return join("",$ar);
}function unescape($str) {
       $str = rawurldecode($str);
       preg_match_all("/(?:%u.{4})|.+/",$str,$r);
       $ar = $r[0];
       foreach($ar as $k=>$v) {
                if(substr($v,0,2) == "%u" && strlen($v) == 6)
                $ar[$k] = iconv("UCS-2","GB2312",pack("H4",substr($v,-4)));
                  }
       return join("",$ar);
}
?>自定函数2
-----------------------------------------------------------------------------------

感谢论坛gingzai777 ,高手就是不一样,一眼就能看出问题所在.....
以后php过滤用这个行了,不需要顾虑文件编码了.....
<?php
function addslashes_str($str){
$str=addslashes($str);
$str=str_replace($str,";",'\;');
return $str;
}
function stripslashes_str($str){
$str=stripslashes($str);
$str=str_replace($str,'\;',";");
return $str;
}
?>-------------------------------------------------------------------------------------
ps:如果有什么错误,希望大家指出,另外希望大家把平时用到的一些方法提供一下,互相学习...散分...
我写的原文

解决方案 »

  1.   

    不错,比较了解了<?php
    function addslashes_str($str){
    $str=addslashes($str);
    $str=str_replace($str,";",'\;');
    return $str;
    }
    ?>$str=str_replace($str,";",'\;');这个有什么用?
      

  2.   

    1)
    请使用mysqli或者pdo,不要再使用mysql了。mysql这个已经不怎么维护了。2)
    “SET NAMES utf8;”,这个用法是错误的,在某些编码下存在漏洞。在php5.0.5以后,都应该用mysqli_set_charset(类似的是mysql_set_charset)。
    http://cn.php.net/manual/en/mysqli.set-charset.php至于为什么mysql_query("set names xxx")存在漏洞,说起来就比较复杂了,一句话就是:某些编码里,\会作为字符的一部分,导致串解析异常。mysqli_set_charset的作用是除了client,connection,result之外,还设置了mysql的某个内部结构的charset。不要再使用set names了,也不要再叫别人去使用它了。3)
    addslash*,无论是自定义,还是官方的,大多数情况下都是多余的东西。要遵循一个原则,就是过滤在倒数第二步执行。而且大多数操作,对过滤的要求都不一样,例如对于MySQL,因为涉及编码问题,所以addslashes就是不安全的。这就是为什么PHP6会取消magic_quote。4)
    那个escape,根本和正则屁关系都没有。只要知道utf-8的编码规则就行。编码规则如下:
    0000-007F | 0xxxxxxx
    0080-07FF | 110xxxxx 10xxxxxx
    0800-FFFF | 1110xxxx 10xxxxxx 10xxxxxx
    10000-10FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
    个个都说写得好,却不知道去寻找其中的问题,不去思考。现在网络上大多数错误的编程经验,就是这样出来的。如果我不在这里说,不知道还有多少人被误导。写这种总结帖是不错,但是如果没有人来挑错,那就会使得其中的错误编程思想被传播开。
      

  3.   

    而且对于set names utf8,我很怀疑这里是否有人知道这究竟代表什么。在这种论坛里,我从来没见过有人能正确描述set names的作用,因为这里根本没人知道mysql的编码层次。
      

  4.   

    谢谢surfchen指出错误....刚才我又找了看了点资料.再加上些1.mysqli.dll和mysql.dll区别
    mysqli.dll,mysqli.dll是一个允许以对象的方式或者过程操作数据库的,是php5之后加上的特性,(i)所代表的是改进,其执行速度更快.  参考链接
    另外还google了一些关于pdo的资料,php6会默认使用pdo进行数据库操作,取代mysql_*
    参考链接
    2.addslashes()与magic_quotes_gpc的关系,$data为插入数据库的数据
    --------------------------------------------------------------------------------
    magic_quotes_gpc状态  addslashes()是否使用 $data          $data在数据库的显示 
    off                  否                     test''""test   test''""test 
    on                   否                     test''""test   test''""test 
    off                  是                     test''""test   test''""test  
    on                   是                     test''""test   test\'\'\"\"test 
    --------------------------------------------------------------------------------3.关于编码
    编码这部分,曾经研究了一次,后来忘了,现在还在熬浆糊...感谢surfchen,等俺在好好的研究研究...4.疑问....
    如果说php6取消了magic_quotes_gpc,而addslashes()根据surfchen说的不安全,那过滤函字符用什么?
    php6有什么新花样?
    还是mysqli_real_escape_string()  ???? 
      

  5.   


    1:mysqli,不少服务器或主机不一定支持!当然,如果要求数据库移置性,还是用PDO可能好些
    2、还要是用的“SET NAMES utf8;”, 这个是mysql手册推荐 的,功能就是设置client,connection,result
    如果你的服务器均已设置,可不用这个语句!但如果你客户端和数据库编码不一致,要用这个!这个的作用就是告许mysql,我客户端用的是什么编码,我要结果是什么编码,连接时用什么编码!
          所有这些编码,可能和表字段的实际编码不一样,但个问题是由mysql自动转换处理的!一般不会出错,但也有可能出错,正常的,有的编码转换时,比如在一个编码里没,在另一个里有,转换必然转不出来!3、addslash*,无论是自定义,还是官方的,大多数情况下都是多余的东西。要遵循一个原则,就是过滤在倒数第二步执行。而且大多数操作,对过滤的要求都不一样,例如对于MySQL,因为涉及编码问题,所以addslashes就是不安全的。这就是为什么PHP6会取消magic_quote----------------------这个不知道安全不安全了
        
       addslash-我的理解决就是对一些引号,或mysql内部的关键词转义,否则信息不完整!不如道有何其他好办方法!
       这个东西,都是依据mysql的标准来做的!
      

  6.   

    关于“set names utf8”,可能大家还不明白我说什么。我说用mysql_set_charset()来代替mysql_query("SET NAMES UTF8");,不是说不要设置编码。mysql_set_charset()比mysql_query("SET NAMES UTF8")多一个操作。具体是什么我就不说了,上面有一句话我已经提到过了。如果不相信我,至少也要相信手册,手册里(http://cn2.php.net/mysql_set_charset)写着:
    Note: This is the preferred way to change the charset. Using mysql_query() to execute SET NAMES ..  is not reccomended. 翻译过来就是
    注意:推荐使用这种方式(指mysql_set_charset())来改变charset。使用mysql_query()来SET NAMES...是不被推荐的。
      

  7.   

    为什么取消magic_quotes_gpc呢,我来说明一下吧。首先,当magic_quotes_gpc存在的时候,我们程序员是否因此而获益呢?答案是否定的。正因为存在magic_q这个东西,导致我们在写代码的时候,不得不判断这个magic_q是否开启,然后采取不同的动作。也就是,magic_q如果存在,程序里必须处理“它开启”和“它不开启”这两种情况。而如果没有magic_q,程序只需要处理“它不开启”这一种情况了。其次,addslashes不应该作为一种统一的过滤字符函数。因为,在不同的应用里,存在不同的过滤规则。例如,在MySQL里,按照标准,是需要过滤\x00, \n, \r, \, ', "和\x1a。这里处理\n\r,是为了MySQL的log存储。而在不同编码环境下,MySQL的过滤处理又略有不同。所以说addslashes是不可以用来对进入MySQL的数据进行过滤的。 我再举个例子,html的过滤,至少要过滤<和>吧,这个就很明显不能用addslashes来处理了。关于这个问题的更深入的例子,如果有兴趣,可以阅读我这篇文章:utf8_decode的安全性。如果比较复杂,如果时间不多,就不要看了。那么mysql的数据应该用什么来过滤呢?对应如下:
    mysql: mysql_real_escape_string
    mysqli:mysqli_real_escape_string
    pdo:quote实际上,一个好的数据库类库,已经不需要程序员直接调用过滤程序了。看下面的例子:
    $sth = $dbh->prepare('SELECT name, colour, calories
        FROM fruit
        WHERE calories < ? AND colour = ?');
    $sth->execute(array(150, 'red'));这个例子,是PDO的例子。PDO引入了一个叫占位变量的概念,也就是上面的问号。上面的execute()的作用,就是把prepare里的问号,替换为150和red,并执行。在替换过程里,它自动做了quote(),也就是过滤字符。下面是我实现的一个类库的一个例子,也是引入了类似的概念。实际上,大多数优秀的数据类库都有占位变量和prepareStatement的概念的。
    $sjk->initSql('select * from wp_users where user_login=#1 limit 1');
    $sjk->setString(1,$name);
    $rs=$sjk->query();
    另外,关于php6么,当然是不会引入如同magic_quotes_gpc这样的东西了。magic_q是一个畸形的产物,源自于PHP核心开发团队的不严谨。
      

  8.   

    刚才看了一下 php 5.2.8 的 ext/mysql/php_mysql.c,1099 行:PHP_FUNCTION(mysql_set_charset)
    {
    zval *mysql_link = NULL;
    char *csname;
    int id = -1, csname_len;
    php_mysql_conn *mysql; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &csname, &csname_len, &mysql_link) == FAILURE) {
    return;
    } if (ZEND_NUM_ARGS() == 1) {
    id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
    CHECK_LINK(id);
    } ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink); if (!mysql_set_character_set(&mysql->conn, csname)) {
    RETURN_TRUE;
    } else {
    RETURN_FALSE;
    }
    }这里调用的是 mysql lib 提供的 mysql_set_character_set 函数。关于这个更底层的 mysql lib,可以看这个:http://jabberd2.xiaoka.com/ticket/177,尤其是这个说明:http://dev.mysql.com/doc/refman/5.0/en/mysql-set-character-set.html

    This function works like the SET NAMES statement, but also sets the value of mysql->charset, and thus affects the character set used by mysql_real_escape_string()
      

  9.   

    刚才看了一下 php 5.2.8 的 ext/mysql/php_mysql.c,1099 行:PHP_FUNCTION(mysql_set_charset)
    {
    zval *mysql_link = NULL;
    char *csname;
    int id = -1, csname_len;
    php_mysql_conn *mysql; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &csname, &csname_len, &mysql_link) == FAILURE) {
    return;
    } if (ZEND_NUM_ARGS() == 1) {
    id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
    CHECK_LINK(id);
    } ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink); if (!mysql_set_character_set(&mysql->conn, csname)) {
    RETURN_TRUE;
    } else {
    RETURN_FALSE;
    }
    }这里调用的是 mysql lib 提供的 mysql_set_character_set 函数。关于这个更底层的 mysql lib,可以看这个:http://jabberd2.xiaoka.com/ticket/177,尤其是这个说明:http://dev.mysql.com/doc/refman/5.0/en/mysql-set-character-set.html

    This function works like the SET NAMES statement, but also sets the value of mysql->charset, and thus affects the character set used by mysql_real_escape_string()
      

  10.   

    补充一句:大家不要认为addslashes和mysql有什么关系,addslashes只不过正好可以用在mysql这个场景下而已。当然如我上面所说,实际上addslashes和mysql所要求的过滤还是有一些区别的。
      

  11.   

    嗯,对的,mysql的那个核心结构里,有charset这个成员。mysql会根据这个charset来调用不同的charset的handler判断多字节,例如gbk就是strings/ctype-gbk.c下的ismbchar_gbk。而set names是不会去设置这个成员变量的。我上面是说mysql的c源代码,大家可以忽略。
      

  12.   

    看了一下,
    mysql_set_charset(PHP 5 >= 5.2.3)mysql_set_charset — Sets the client character set是新函数手册里不详细,这个实质是是PHP自身的函数,而不是mysql机制mysql的机制在不得不用的情况下,仍要用set names 说下简单的例子,如果你用不是php,要连mysql数据库呢?
      

  13.   

    不是php自身实现的。php的数据库实现,底层是使用一个叫libmysql的c库。其实无论是PHP,还是python,还是pecl,还是C,操作mysql几乎都是通过libmysql来实现的(当然有其他的实现,在此不表)。而libmysql里,有一个叫mysql_set_charset的函数,这个函数被PHP封装起来,成为了PHP的函数。mikespook在上面已经提到了这一点。
      

  14.   

    总结的太好了,我要好好学习php。哈哈!!
      

  15.   

    好东西啊。。对于我们这些入门PHPer帮助太大了,不然总被误导,支持下
      

  16.   

    好久不来csdn了,今天偶然看到这个好帖,顶一下。