这种处理POST和GET数据的方式是一种很好的做法吗?

时间:2012-09-04 18:40:49

标签: php performance post scalability

阅读此article之后,我想知道这是否实际上是用于注册新用户的良好做法。每个研究过PHP的人都可以看到它是如何工作的,但我只是想重复自己,如果我必须手动处理所有的帖子数据。我知道一次做起来并不困难也不太长,但我认为如果你实现了与此代码类似的东西,那么从长远来看它可以更好地处理。例如,要添加更多单个字段,您必须更改大量代码,在文章中进行复制/粘贴,但这里只是数组$ValidFields中的一个字段。你觉得怎么样?

function registerUser()
{
// Only place (apart of the mysql table, obviously) to add new fields of all the script.
$ValidFields = array ("name","lastname","email","password");
$tablename="users";                  // If oop, this could be done in the __construct()
foreach ($_POST as $key => $value)
  if(in_array($key,$ValidFields))
    {
    $key=mysql_real_escape_string($key);
    if ($key=="password") $value=md5($value);
    else $value=mysql_real_escape_string($value);
    if (!$mysql)  // If there is nothing inside
      {
      $mysql="INSERT INTO ".$tablename." (".$key;
      $endmysql=") VALUES ('".$value."'";
      }
    else
      {
      $mysql.=", ".$key;
      $endmysql.=", '".$value."'";
      }
    }
$mysql=$mysql.$endmysql.")";
return $mysql;
}

在函数

之后测试添加此代码
$_POST['name']="testname";
$_POST['lastname']="testlastname";
$_POST['email']="teste'mail";       // Checking MySQL injection (;
$_POST['password']="testpassword";
$_POST['CakePHP']="is_a_lie";       // "Hello world" is too mainstream
echo registerUser();

返回的字符串实际上是:

INSERT INTO users (name, lastname, email, password) VALUES ('testname', 'testlastname', 'teste\'mail', 'testpassword')

注意!我知道我不应该使用mysql _ ,这只是一个说明性的脚本。每个人都应该使用php5(PDO,MYSQLi等)中的许多语句。我专注于可扩展性和性能。可以再现类似的过程以创建HTML表单。此外,它应该与类相似。

我只是想知道为什么,在这么多年里PHP已经开发出来并在1年内我一直在研究它并在网上搜索信息,我还没有看到任何类似的和也许处理POST或GET数据的更有效方式。

2 个答案:

答案 0 :(得分:2)

我根本不处理$ _GET和$ _POST。相反,我在查询中使用了parameter binding

所以我的插页看起来像这样:

public function Insert( $table, array $bind )
  {
    $this->fetch = function( $sth, $obj )  { return $obj->lastID = $obj->lastInsertId(); };
    $this->sql = array();
    $this->bindings = array();

    $columns = implode( ", ", array_keys( $bind ) );
    $values  = ':' . implode( ", :", array_keys( $bind ) );

    foreach ( $bind as $column => $value )
      $this->bindings[] = array( 'binding' => $column, 'value' => $value );


    $this->sql['insert'] = "INSERT INTO " . $table . " (" . $columns . ")  VALUES (" . $values . ")";

    return $this;
  }

执行看起来像这样:

  public function Execute()
  {
    $sth = $this->prepare( implode( ' ', $this->sql ));
    if( !$sth )
      return false;

    foreach ( $this->bindings as $bind ) 
      if( $bind['binding'] ) {
        if( isset( $bind['type'] ))
          $sth->bindValue( ':' . $bind['binding'], $bind['value'], $bind['type'] );
        else
          $sth->bindValue( ':' . $bind['binding'], $bind['value'] );
      }

    if( $sth->execute() ) {
      $lambda = $this->fetch;
      return $lambda( $sth, $this );
    }
    else 
      return false;
  }

答案 1 :(得分:0)

绝对不是一个好的做法 - mysql_real_escape_string 安全,可以安全地包含安全包含在单引号内的数据。它不能安全地用于任何其他目的。

因此,可以通过设置精心设计的POST密钥将恶意内容注入您的查询 - 例如,可以设置

$_POST["name) SELECT CONCAT(name, CHAR(58), password) FROM users --"] = "";

在数据库中为每个现有用户创建一个用户,其名称指示现有用户的密码。如果您的应用程序公开显示用户列表,则会产生公共所有用户密码的效果。更多细微的攻击也是可能的;这只是一个简单的例子。