1

この記事を読んだ後、これが実際に新しいユーザーを登録するための良い習慣なのか疑問に思いました. PHP を勉強したことのある人なら誰でもその仕組みを理解できますが、すべての投稿データを手動で処理する必要がある場合は、同じことを繰り返しているように感じます。一度に行うのが「難しい」ことでも長すぎることでもないことはわかっていますが、このコードに似たものを実装すれば、長期的にはより良い方法で処理できると思います。たとえば、1 つのフィールドをさらに追加するには、多くのコードを変更する必要があり、記事内でコピー/貼り付けを行う必要がありますが、ここでは array 内の 1 つのフィールドだけが追加されてい$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 年間で PHP を研究し、オンラインで情報を検索してきたのに、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 --"] = "";

既存のユーザーごとにデータベースに 1 人のユーザーを作成し、既存のユーザーのパスワードを示す名前を付けます。アプリケーションがユーザーのリストを公開して表示する場合、これはすべてのユーザーのパスワードを公開する効果があります。より微妙な攻撃も可能です。これは簡単な例です。

于 2012-09-04T19:14:54.897 に答える