質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.91%

サイトに乗っている通りにやってもバインドしてからのインサート実行がうまく行きません。

受付中

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 314

score 4

```php
<?php

// 変数の初期化 & 日時の取得
date_default_timezone_set('Asia/Tokyo');
$sql = null;
$res = null;
$dbh = null;
$date = date('Y-m-d H:i:s');

try {
// DBへ接続
$dbh = new PDO('mysql:host=localhost; dbname=sample; charset=utf8', 'root', 'root');
// var_dump($dbh);
if(!$dbh) {
echo "接続出来てない";
}
// // SQL作成
// $sql = "INSERT INTO sample_app (
//     user_name, email, password, role, created, updated
// ) VALUES (
//     ':user_name', ':email', ':password', ':role', ':created', ':updated'
// )";
// $stmt = $dbh->prepare($sql);
// $params = array(
//   ':user_name' => 'ユーザーネーム',
//   ':email' => 'メール',
//   ':password' => 'パス',
//   ':role' => 0,
//   ':created' => $date,
//   ':updated' => '0000-00-00 00:00:00'
// );
// $stmt->execute($params);

// // SQL実行
// $res = $dbh->query($sql);
// return $res;
$user_name = "name";
$email = "email";
$password = "pass";
$role = 0;
$updated = '0000-00-00 00:00:00';

// SQL作成
$stmt = $dbh->prepare("INSERT INTO sample_app (
user_name, email, password, role, created, updated
) VALUES (
':user_name', ':email', ':password', ':role', :created', ':updated'
)");
$stmt->bindParam(':user_name', $user_name, PDO::PARAM_STR);
$stmt->bindParam(':email', $email, PDO::PARAM_STR);
$stmt->bindParam(':password', $pass, PDO::PARAM_STR);
$stmt->bindValue(':role', $role, PDO::PARAM_INT);
$stmt->bindParam(':created', $date, PDO::PARAM_STR);
$stmt->bindParam(':updated', $updated, PDO::PARAM_STR);
$stmt->execute();
} catch(PDOException $e) {
echo $e->getMessage();
die();
}

// 接続を閉じる
$dbh = null;

?>

エラー文
Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens in /Applications/MAMP/htdocs/test.php on line 55
何度やってもどこが間違っているのかよくわかりません。
どなたかご教授ください

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • m.ts10806

    2021/01/13 06:57 編集

    コードやエラーはマークダウンのcode機能を利用してご提示ください。
    https://teratail.com/questions/238564

    >サイトに乗っている通りにやっても
    「参考した先が絶対に間違ってない」という根拠がないので、
    その参考にしたサイトURLを提示してください。間違っていれば筆者に指摘する必要があります。
    あと環境情報も。
    全て同じに整えたのなら、コードは書いたとおりに動くので「動かない」という現象は起きません。
    大抵は「通りにできていない」からできてません。コードは書いたとおりに動いています。

    キャンセル

回答 1

0

$stmt = $dbh->prepare("INSERT INTO sample_app (
user_name, email, password, role, created, updated
) VALUES (
':user_name', ':email', ':password', ':role', :created', ':updated'
)");


↑ :created シングルクォートの「閉じ」しかないように見えます。 あと、:role はPARAM_INTでバインドしてるので数値だと思いますが、シングルクォートでくくられてるので、実行時に文字列扱いになってると思います。(エラーメッセージが言ってるのはこっちぽいですね)

(訂正)
プリペアードステートメントのプレースホルダには、全てクォートは不要、が正解でした。
(m.ts10806さん、指摘ありがとうございます)

$stmt = $dbh->prepare("INSERT INTO sample_app (
user_name, email, password, role, created, updated
) VALUES (
 :user_name, :email, :password, :role, :created, :updated
)");

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2021/01/13 09:01

    https://www.php.net/manual/ja/pdostatement.bindvalue.php
    PHPマニュアルでも文字列だろうと何だろうとバインドパラメータ側にクォートはついていません。
    bindValueの第2引数で型を指定することで内部的にきちんと(エスケープされたうえで)対応されていると思って良いです。クォートが入ってしまうことでSQLインジェクションしやすくなりますし。。

    キャンセル

  • 2021/01/13 10:58

    >m.ts.10806さん
    指摘ありがとうございます!実際に動かして試しましたが、エラーにはならないですがWarningが出てInsertできませんでした。曖昧な記憶で言っちゃダメですね、、気をつけます。

    キャンセル

  • 2021/01/13 11:00

    はい。記憶は曖昧なものですし誰でもそうなので、PHPマニュアルなどで確実に、
    可能ならミニマムコード組んでみるくらいはしてもいいかなと。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.91%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • PHPに関する質問
  • サイトに乗っている通りにやってもバインドしてからのインサート実行がうまく行きません。