ホームページ  >  記事  >  バックエンド開発  >  大きな問題があります - PDO (2)、rub-pdo_PHP チュートリアル

大きな問題があります - PDO (2)、rub-pdo_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-12 09:03:151098ブラウズ

大きなrub-PDO(2)をゲットしました、rub-pdo

こんにちは

昨日も213時でした。ルームメイトが3時過ぎまで寝なかったことが客観的に影響しましたが、根本的な理由は昨夜勉強したくなかったということです。今日から始めましょう。 PDO と AJAX の学習は 3 ~ 4 日以内に終える予定です。また怠けてしまわないように、皆さんも何もすることがなかったら叱りに来てください。

1、PDO

2. PDOオブジェクトの使用(2)

2.2 エラーメッセージ

errorCode()—エラー番号;

errorInfo() - エラーメッセージ

栗をください

/*

* PDO エラー メッセージ
*/

$pdo=新しい PDO('mysql:host=localhost;dbname=imooc','root','');

$pdo->exec('imooc_pdoを使用');

$resultd=$pdo->exec('id=13のユーザーから削除');

var_dump($resultd);
$insert='ユーザーを挿入(ユーザー名,パスワード,電子メール) value("Knga","'.md5('king').'","shit@shit.com")';
$result1=$pdo->exec($insert) ;
var_dump($result1);

if ($result1==false)

{ echo "エラーが発生しました";
echo $pdo->errorCode();
print_r($pdo->errorInfo());
}
エラーメッセージを見てください

配列 ( [0] => 23000 [1] => 1062 [2] => Duplicata du champ 'Knga' pour la clef 'username' )

0 はエラーの種類、1062 はコード、2 はエラー メッセージです (これは、ユーザー名が一意のキーに設定されているためですが、ID 番号はまだ増加しているためです)。

2.3 query() はクエリを実装します

ステートメントを実行

し、PDOstatement オブジェクトを返します。

--栗をください

/*

* PDOクエリ

*/

$pdo=新しい PDO('mysql:host=localhost;dbname=imooc','root','');

$pdo->exec('imooc_pdoを使用');

$insert='select * from user';

$result1=$pdo->query($insert);


var_dump($result1); // ステートメントオブジェクトを表示
foreach ($result1 as $row) { //出力結果を表示します(戻り状況に従って)
print_r($row);}
if ($result1==false) {
echo "エラーが発生しました";
echo $pdo->errorCode ();
print_r($pdo->errorInfo());
}

SQL ステートメントに問題がある場合、ステートメント オブジェクトは false になり、その後の出力もエラー メッセージになります。

SQL ステートメントは正しいが、クエリのコンテンツが存在しない場合、ステートメント オブジェクトは OK であり、出力は空です。

もちろん、この方法の方が見栄えが良くなります: foreach ($result1 as $row){ //出力結果を表示します(戻り状況に従って)

// print_r($row);echo "
";

echo 'Number:'.$ row[' id'];echo "
";

echo 'ユーザー名:'.$row['ユーザー名'];echo "
";

echo 'パスワード:'.$ row[ 'パスワード'];echo "
";
echo 'Email:'.$row['email'];echo "
";
echo "


}

もちろん、クエリの追加、削除、変更は問題ありません。

2.4 クエリを実装するための prepare() メソッドとexecute() メソッド

推奨クエリ方法は条件付きクエリを実現できます。

prepare() - 実行する SQL ステートメントを準備し、PDOstatement オブジェクトを返します。 execute()—準備されたステートメントを実行し、

true または false を返します

; つまり、上記はペアです。

--例を挙げてください

/*

* PDOprepare&executeメソッド*/

$pdo=新しい PDO('mysql:host=localhost;dbname=imooc','root','');


$pdo->exec('imooc_pdoを使用');

$insert='select * from user where username="king"';

$result=$pdo->prepare($insert);

var_dump($result);


$result1=$result->execute();//プリペアドステートメントの実行ですvar_dump($result1);

print_r($result->fetchAll());//結果はステートメントオブジェクトにのみ出力できます

if ($result1==false) { echo "エラーが発生しました"; echo $pdo->errorCode();

print_r($pdo->errorInfo());

}

ここでこの特殊な状況に事前に対処するように注意してください。そうすれば、ターゲットが誰であるかを把握しやすくなります。


-- 出力形式を選択します

配列出力、すべてまたはインデックス配列を関連付けるには、パラメーターとメソッドという 2 つの異なる方法があります。

header('content-type:text/html;charset=utf-8');
try{
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root' ,'root');
$sql='select * from user';
$stmt=$pdo->prepare($sql);
$res=$stmt->execute();
// if( $res){
// while($row=$stmt->fetch(PDO::FETCH_ASSOC)){//連想配列の出力のみが必要です
// print_r($row);
// echo ' < ;hr/>';
// }
// }
// $rows=$stmt->fetchAll(PDO::FETCH_ASSOC);
// print_r($rows);
echo '


' stmt->fetchAll();
print_r($rows);}catch(PDOException $e){ echo $e->getMessage();
}

通常、配列にインデックスを付けたいと考えます。

2.5 データベース接続プロパティを設定する
setAttribute()—データベース接続属性を設定します;

getAttribute()—データベース接続属性を取得します;

--例を挙げてください

$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','');

echo "自動コミット".$pdo->getAttribute(PDO::ATTR_AUTOCOMMIT);echo "


";

//pdo はオブジェクトなので、プロパティを取得することを覚えておいてください。そして、その中には多くの属性値が設定されており、これが属性を取得するための前提となります。

echo "デフォルトのエラー処理モード:".$pdo->getAttribute(PDO::ATTR_ERRMODE);echo "


";
$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT, 0) ;
echo "オートコミット".$pdo->getAttribute(PDO::ATTR_AUTOCOMMIT);echo "
";

次に、大量の属性情報を取得してみます:
$attrArr=array(

'AUTOCOMMIT','ERRMODE','CASE','PERSISTENT','SERVER_INFO','SERVER_VERSION');foreach ($attrArr as $attr){

echo "PDO::ATTR_ $attr: ";

echo $pdo->getAttribute(constant("PDO::ATTR_$attr"))."
";
}

一部は利用できず、エラーメッセージが表示されますが、問題ありません。


3. PDOstatement オブジェクトの使用

SQLインジェクションを防ぐための3.1 quote()メソッド

--SQL インジェクション

まず、この単純な SQL インジェクションを説明するための例を示します (実際にはよく理解していません - Baidu http://baike.baidu.com/link?url=jiMtgmTeePlWAqdAntWbk-wB8XKP8xS3ZOViJE9IVSToLP_iT2anuUaPdMEM0b-VDknjolQ8BdxN8ycNLohup_)

いわゆる SQL インジェクションとは、Web フォームの送信に SQL コマンドを挿入したり、ページ リクエストのドメイン名やクエリ文字列を入力したりして、最終的にサーバーをだまして悪意のある SQL コマンドを実行させることです。

そのため、フォームが必要で、データベースにデータなどのクエリを実行し、ルールの抜け穴を悪意を持って利用して、ページが予期していなかった大量のデータを取得する必要があります。栗は以下の通りです

例はログインです。ログインにはユーザー名、パスワードなどが必要で、データベース内の情報と比較する必要があります。 まずは

ログインページです


$stmt=$pdo->query($sql);

echo $stmt->rowCount() ;//結果セットのステートメントオブジェクトの行数を表示します
} catch (PDOException $e) {
echo $e->getMessage();
} 次に、ブラウザでlogin.htmlを開き、データベースにユーザー名とパスワードを入力し、「ログイン」をクリックすると、1を取得します。

間違った情報を入力すると、通常は 0 が返されます;

注:

「'または 1=1#」などのユーザー名と任意のパスワードを入力すると

、データベース内のすべてのデータを簡単に取得できます。これは、SQL ステートメント自体の規則によるものです。

そのため、ユーザーが入力した情報を

フィルタリングする必要があり、ユーザーの操作をすべて信頼する必要はありません。

--対処方法

echo $pdo->quote($username);

この文を書いてから上記のチートコードを使用すると、出力にはさらに一重引用符が含まれ、自動的に次のコードが追加されます:

「または 1=1#」

ただし、これを行うと、$username への呼び出しが引用符付きで自動的に追加されるため、次の SQL ステートメントはそれに応じて変更されます。

$username=$pdo->quote($username);

$pdo->exec('use imooc_pdo');
$sql="select * from user where username={$username} andpassword='{ $パスワード}'";

簡単に言うと、

ユーザー名をタグ付けする データベースがある場合にはこれを警戒する必要があるようです。

ただし、この方法の使用はお勧めしません。

準備+実行の前処理方法を使用することをお勧めします

3.2 準備されたステートメントでのプレースホルダーの使用

インジェクションを非常に適切に防止し、一度コンパイルして複数回実行することでシステムのオーバーヘッドを削減できます。

--プレースホルダー: (名前付きパラメータ) (推奨)

header('content-type:text/html;charset=utf-8');

$username=$_POST['username'];
$password=$_POST['password'];
try {
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','');
$pdo->exec('use imooc_pdo');
$sql="select *ユーザーから
ここで、username=:username およびpassword=:$password
"; $stmt=$pdo->prepare($sql);
$stmt->execute(array(":username"=> $username,":password"=>$password));
//$stmt=$pdo->query($sql); echo $stmt->rowCount();//結果セットを表示しますステートメント オブジェクト内の行数

} catch (PDOException $e) {

echo $e->getMessage();

}

対応する SQL ステートメント、対応する実行、および渡す必要があるパラメーターも対応している必要があります。

--プレースホルダー?

$sql="ユーザー名 =? およびパスワード =? のユーザーから * を選択";

$stmt=$pdo->prepare($sql);
$stmt->execute(array($username, $パスワード));
気分?方法はもっとシンプルで、入力プレースホルダー + 前処理 + SQL ステートメントでの実行 (複数のデータを渡すには配列を使用) の 3 つのポイントだけです。

3.3 bindingParam() メソッドはパラメータをバインドします

パラメータを変数名にバインドします。

/*

* バインディングパラメータ
*/

header('content-type:text/html;charset=utf-8');

try {

$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','');
$pdo->exec('use imooc_pdo');

$sql="ユーザー(ユーザー名,パスワード,電子メール)の値を挿入(:ユーザー名,:パスワード,:電子メール)";
$stmt=$pdo- >prepare($sql); $username="Wid";$password="123";$email="324@qq.com" //パラメータを定義します

$stmt->bindParam(":username ", $username,PDO::PARAM_STR);
$stmt->bindParam(":password",$password);
$stmt->bindParam(":email",$email);
$stmt->execute(); $res=$pdo->query("select * from user");
foreach ($res as $row){ // 出力結果を表示します (戻り値に従って)状況)
// print_r($row);echo "
";
echo 'number:'.$row['id'];echo "
";
echo 'ユーザー名:' .$row['ユーザー名'];echo "
";
echo 'パスワード:'.$row['パスワード'];echo "
";
echo 'メール:' .$row['email'];echo "
";
echo "


";
}


} catch (PDOException $e) {

echo $e->getMessage();

}

実際、これは、わずかに反復的な操作を実行するために毎回 SQL ステートメントを変更する必要を避けるためです。

もちろんプレースホルダーを変更することもできます

// $sql="insert user(username,password,email) value(?,?,?)";


// $stmt->bindParam(1,$username);
とにかく、

実際: プレースホルダーのほうがわかりやすいでしょうか?混乱するだろう。

3.4 bindingValue() はバインディングパラメータを実装します

値をパラメータにバインドします。

/*

* バインドパラメータ

*/

header('content-type:text/html;charset=utf-8');
try {
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','');
$pdo->exec('use imooc_pdo');
$sql="ユーザー(ユーザー名,パスワード,電子メール)の値を挿入(:ユーザー名,:パスワード,:電子メール)";
// $sql="ユーザーを挿入(ユーザー名,パスワード,電子メール) 値(?,?,?)";
$stmt=$pdo->prepare($sql);

//假设電子メールパラメータ不变
$stmt-> bindValue(":email", 'shit@shit.com');
$username="Wade";$password="123";
$stmt->bindParam(":username", $username,PDO::PARAM_STR);
$stmt->bindParam(":password" ,$パスワード);
$stmt->execute();
$res=$pdo->query("select * from user");
foreach ($res as $row){ //查看输出结果(基底回帰情况)
// print_r($row);echo "
";
echo '编号:'.$row['id'];echo "
";
echo '用户名:' .$row['ユーザー名'];echo "
";
echo '秘密:'.$row['パスワード'];echo "
";
echo '邮箱:' .$row['email'];echo "
";
echo "


";
}


} catch (PDOException $e) {
echo $e->getMessage();
}

用途は、特定の値が固定されない場合に、量を固定できるパラメータ値です。

3.5 bindingColumn() メソッド決定パラメータ

php オブジェクトに一列を追加します。

$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','');

$pdo->exec('use imooc_pdo');

$sql="ユーザーから * を選択";
$stmt=$pdo->prepare($sql);
$stmt->execute();
//制御输出

$stmt->bindColumn(2, $username);
$stmt->bindColumn(3,$password);
$stmt->bindColumn(4,$email);
while ($stmt->fetch(PDO::FETCH_BOUND)){
echo '用户名:'.$username.'-密码:'.$password.'-邮箱:'.$email.'


'; }

ここでの使用方法は、

出力結果を制御し、出力形式の制御を行うことです。

当然のことながら、結果は底部の列に集中しており、その後の各列が何であるかを確認できます: echo '結果集中の列数:'.$stmt->columnCount().'


';

print_r($stmt->getColumnMeta(2));

3.6 fetchColumn()从結果集中取一列

前述の getColumnMeta() メソッドは、PHP のこのバージョンでは実際に実行される関数であり、将来のバージョンでは失われる可能性があります。 $stmt->execute();

print_r($stmt->fetchColumn(3));

この方法は、毎回の実行でタンパク質痛が発生する場所にあるため、最初の行を指定するだけでよく、一行目であるかどうかはわかりません。 3.7 debugDumpParams()打印一条预处理语句

bindParam でのこの方法:

$stmt->debugDumpParams();

結果は一大堆:

SQL: [71] insert user(username,password,email) value(:username,:password,:email) Params: 3 Key: Name: [9] :username paramno=-1 name=[9] ":username " is_param=1 param_type=2 キー: 名前: [9] :password paramno=-1 name=[9] ":password" is_param=1 param_type=2 キー: 名前: [6] :email paramno=-1 name= [6] ":email" is_param=1 param_type=2 は、つまり、事前処理時に発生する可能性のある詳細な状況です。 説明はデバッグのために作成された方法です。

3.8 nextRowset() メソッドすべての結果を取り出します

たとえば、mysql の保存プロセス (以前の mysql の博文を参照してください) に使用され、次に多数の結果の集合が取得され、その後、その集合が操作されます。

実際には、一歩下に移動することを指します。

例私懒了,不想敲了。。。。

虽然很多,就此吧。 二日間、次の日を過ごしましたが、まだ痛みがあり、正確には生きていませんでした。

http://www.bkjia.com/PHPjc/1082310.html

www.bkjia.com

tru​​e

http://www.bkjia.com/PHPjc/1082310.html

技術記事

我了大擦-PDO(二)、擦-pdo こんにちは昨天又213了、虽然有室友3点多才睡觉的客影响、但是昨晚不想学东西是本因。今天搞起。打算3、4日...

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。