1

我打算将现有的 Intranet 系统转换为 CodeIgniter。我一直使用 UTF-8,因此它可以处理各种不同的字符,这对于系统来说是必不可少的(输出发票、地址标签等)。

我决定在输入时自动替换一些字符,因为它们最终会使系统用户感到困惑。

  • 单引号和双引号。替换为正常的撇号/引号
  • En dash 和 em dash,替换为正常的连字符
  • 省略号,替换为三个句号

至少这些标点符号现在都被一致地使用和存储了。

在这个系统中,要存储在数据库中的数据总是由 POST 接收,所以我在每次页面加载时在 POST 数组上运行以下函数......

function nasty_chars_replace(&$var) {

    $trans_table = array(
        chr(0xe2).chr(0x80).chr(0x9a) => '\'', //SINGLE LOW-9 QUOTATION MARK
        chr(0xe2).chr(0x80).chr(0x9e) => '"', //DOUBLE LOW-9 QUOTATION MARK
        chr(0xe2).chr(0x80).chr(0xa6) => '...', //HORIZONTAL ELLIPSIS
        chr(0xe2).chr(0x80).chr(0x98) => '\'', //LEFT SINGLE QUOTATION MARK
        chr(0xe2).chr(0x80).chr(0x99) => '\'', //RIGHT SINGLE QUOTATION MARK
        chr(0xe2).chr(0x80).chr(0x9c) => '"', //LEFT DOUBLE QUOTATION MARK
        chr(0xe2).chr(0x80).chr(0x9d) => '"', //RIGHT DOUBLE QUOTATION MARK
        chr(0xe2).chr(0x80).chr(0x93) => '-', //EN DASH
        chr(0xe2).chr(0x80).chr(0x94) => '-' //EM DASH
    );

    foreach ($trans_table as $utf8_code => $replace) {
        $var = str_replace($utf8_code, $replace, $var);
    }

    return trim($var);
}
array_walk_recursive($_POST, 'nasty_chars_replace');

是否有一种方法可以在 CodeIgniter 中全局对所有 POST 数据(如果 POST 存在)执行类似操作?

有没有其他人做这样的事情?
是否有任何其他容易混淆的字符我应该考虑“清理”(而不是这样清理)以保持数据一致性?
编辑:这甚至是个好主意吗?

编辑 2:我应该说我也trim()所有 POST 数据以及删除前导/尾随空格。因此,如果有人决定只用空格填充输入,验证可能会失败。

4

2 回答 2

1

很好地回答您的部分问题 - 如果您使用 CI 的输入类,它会为您执行安全过滤......当调用新控制器时会自动调用安全过滤功能。

所以如果你使用$this->input->post()而不是 $_POST.... 它

过滤 GET/POST/COOKIE 数组键,只允许字母数字(和一些其他)字符。

Input 类能够自动过滤输入以防止跨站点脚本攻击。如果您希望过滤器在每次遇到 POST 或 COOKIE 数据时自动运行,您可以通过打开 application/config/config.php 文件并设置它来启用它:

$config['global_xss_filtering'] = TRUE;

或仅在需要时使用 TRUE 作为第二个参数。

$this->input->post(NULL, TRUE); // returns all POST items with XSS filter 

所以我想你可以扩展核心 Input 类

class MY_Input extends CI_Input {

    function __construct()
    {
        parent::__construct();
    }
}

并在此处添加您的自定义函数以替换某些字符并修剪值。然后这个 Input 类为您预处理全局输入数据以确保安全性和数据库一致性。

希望能帮助到你

于 2012-09-19T14:58:17.817 回答
0

如果您想在所有 POST 数据上运行它而不需要每次都调用该函数,请考虑将其放在控制器的构造函数中,或者放在控制器父级的构造函数中。

在控制器的构造函数中:

class Home extends CI_Controller{
    function __construct(){
        parent::__construct();
        if(!empty($_POST)) array_walk_recursive($_POST, 'nasty_chars_replace');
    }

    function index(){
        //typically a GET request, nasty_chars_replace will not execute.
    }

    function post_here1(){
        //will be nasty char cleaned.
    }

    function post_here2(){
        //will be nasty char cleaned.
    }

}

现在您可以想象,这必须写在所有控制器的构造函数中。如果您只想编写一次,请考虑首先从基类扩展您的控制器并将其写入父类的构造函数中:

在父控制器的构造函数中:

class MY_Controller extends CI_Controller{
    function __construct(){
        parent::__construct();
        if(!empty($_POST)) array_walk_recursive($_POST, 'nasty_chars_replace');
    }
}

...然后回到home.php

class Home extends MY_Controller{
    function __construct(){
        parent::__construct();
    }

    function index(){
        //typically a GET request, nasty_chars_replace will not execute.
    }

    function post_here1(){
        //will be nasty char cleaned.
    }

    function post_here2(){
        //will be nasty char cleaned.
    }
}

我鼓励您查看 Phil Sturgeon 的Keeping It Dry帖子,了解有关如何使用此基类继承的更多信息。

于 2012-09-19T15:45:30.583 回答