1

读完这篇文章后,我想知道这是否真的是注册新用户的好习惯。每个学习过 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 的方法数据。

4

2 回答 2

2

我根本不处理 $_GET 和 $_POST。相反,我在查询中使用参数绑定

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

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;
  }
于 2012-09-04T18:44:01.833 回答
0

绝对不是一个好习惯——mysql_real_escape_string安全地包含在单引号内的数据进行转义。它不能安全地用于任何其他目的。

因此,可以通过设置精心制作的 POST 密钥将恶意内容注入到您的查询中——例如,可以设置

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

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

于 2012-09-04T19:14:54.897 回答