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

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

新規登録して質問してみよう
ただいま回答率
85.35%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

2715閲覧

MYSQL Call to a member function prepare() on nullを解決したい

kotouharuto

総合スコア38

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2020/07/01 09:03

編集2020/07/01 11:12

実現したいこと

prepare()でCall to a member function prepare() on nullが出てしまっているので、そちらを解決して、削除し処理を完成させたいです。

現状

現在MYSQL練習として簡単なtodoリストを作成しているのですが、todoを完了した時に、そのデータを削除するための処理でこのエラーが出てしまい、エラー文で検索をかけたりしたのですが、いまいち解決にたどり着けないので質問させていただいた次第です。

該当のソースコード

php

1//index.phpです 2require_once "DBconnect.php"; 3try { 4 $pdo->beginTransaction(); 5 $sql = "INSERT INTO todo (todo) VALUES (:todo)"; 6 $stmh = $pdo->prepare($sql); 7 $stmh->bindValue(':todo', $_POST['todo'], PDO::PARAM_STR); 8 $stmh->execute(); 9 $pdo->commit(); 10} catch (PDOException $Exception) { 11 $pdo->rollBack(); 12 print 'エラー:' .$Exception->getMessage(); 13} 14?> 15<div class="usermessage"> 16 <table border="1"> 17 <h1>やること</h1> 18 <?php 19 require_once "DBconnect.php"; 20 $sql = "SELECT * FROM todo WHERE 1"; 21 $stmh = $pdo->prepare($sql); 22 $stmh->execute(); 23 24 while(1) 25 { 26 $row = $stmh->fetch(PDO::FETCH_ASSOC); //1レコード取り出し 27 if($row == false) //データがもうない場合 28 { 29 break; //ループから脱出 30 } 31 ?> 32 <h3><?=htmlspecialchars($row['todo'], ENT_QUOTES)?></h3> <!-- データベースのデータを表示 --> 33 <a class="btn btn-outline-primary" href=index.php?id=". $row['id'] ." > 完了 </a> 34 <?php 35 } //whileの閉じタグ 36 $pdo = null; 37 ?> 38</div> 39 40<?php 41//削除処理 42try { 43 44 $stmh = $pdo->prepare('DELETE FROM todo WHERE id = :id'); //この文でエラーが出ています 45 $stmh->execute(array(':id' => $_POST['id'])); 46} catch(PDOException $Exception) { 47 echo 'エラーが発生しました。:' . $Exception->getMessage(); 48}

php

1//DBconnect.phpです 2$user = "root"; 3$password = "root"; 4$host = "localhost"; 5$dbname = "todolist"; 6$dbtype = "mysql"; 7 8$dsn = sprintf( 9 "%s:host=%s;dbname=%s;charset=utf8", 10 $dbtype, 11 $host, 12 $dbname, 13); 14 15try { 16 $pdo = new PDO($dsn, $user, $password); 17 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 18 $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 19} catch (PDOException $Exception) { 20 die('エラー:' .$Exception->getMessage()); 21}

エラーが発生している、
$stmh = $pdo->prepare('DELETE FROM todo WHERE id = :id');の$pdoが悪いのはわかっているのですが、僕が確認したところだと問題はなかったです。

以上です。
わかる方がいらしたらご回答よろしくお願いします。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ロジックを整理した方が良いです。

パッと見問題点

  • 否応なしに登録処理が実行されようとしている
  • 否応なしに削除処理が実行されようとしている
  • 1ファイルコードで関数もないのに何度もDBconnect.phpを読み込んでいる
  • 削除後に何もしてないので、「削除した後の一覧」が取得できない
  • POST送信されなくても$_POSTが参照される

要は「適切に接続し、適切に閉じる」ことができれば、今回の問題は起きないと言えます。
なんとなく接続し、なんとなく閉じているために起きています。
きちんとメリハリをつけて、意図や意味を説明できるロジックを心がけましょう。


蛇足:
あと、DBconnect.phpのコードが提示されてないので確認してください。
PDOちゃんとエラーを出力されるような設定しているか。
PHPでデータベースに接続するときのまとめ#接続後にオプションを指定
きちんと設定されてないと、catchで捕捉してくれません。

投稿2020/07/01 10:56

編集2020/07/01 11:04
m.ts10806

総合スコア80875

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kotouharuto

2020/07/01 11:53

ご回答ありがとうございます。 確かにコードを見直してみると、自分でもおかしいと思う点がありました。 あやふやで理解しているところはきちんと理解する気をつけます。 失礼いたしました、ただいまDBconnect.php公開いたしましたのでご確認ください。
m.ts10806

2020/07/01 11:58

いえ、DBconnect.phpはあくまで「ちゃんと設定されているかの確認」だけしてもらえればよかったです。 で、最初のinsertでエラー出てないということになりますかね。 となると、DBのテーブル定義も見直す必要があると思います。 todoカラムがnull OKになってませんか?
kotouharuto

2020/07/01 12:15 編集

そうだったのですね。 はい、todoカラムの方確認しましたらnull OKになっていました。こちらはNOTに指定しまって大丈夫ですか?
m.ts10806

2020/07/01 12:11

ケースバイケースですが、「必須項目」ならNOT NULLに指定して、本来は登録前にバリデーションもした方が良いです。 ケースバイケースと言うか、「設計次第」ですね。 コード先行だと途中からどうこうが難しくなってロジックが意味をなさなくなるので、要件をしっかりかためて、設計してから取り掛かるべきと思います。 それがどんな簡易なアプリケーションでも。
kotouharuto

2020/07/01 12:21

確かにそうですね。 一から作るときはきちんと設計した上で取り掛かろうと思います。 この度は非常に参考になるアドバイスをありがとうございました!
m.ts10806

2020/07/01 12:23 編集

目の前の問題解決だけを優先すると、結局今回のようにロジックのまずさから出るエラーに悩むことになりますよ。整理するなら、早い方が良いです。 「ここまで作ったからもったいない」は通じません。あくまでプログラムは書いた通りに動くので。 スクラップ&ビルドも1つの技術的な選択肢ですよ。
kotouharuto

2020/07/01 22:00

はい、宣言元からしっかりと確認してみます。
m.ts10806

2020/07/01 22:01

あれ、伝わってなかった。
kotouharuto

2020/07/01 22:05

いえ、十分伝わっています。 伝わったのですが、どうかえせばいいかわからなくなったので、文がおかしくなってしまいました。 失礼しました。
m.ts10806

2020/07/01 22:51

では、あまりむずかしい言葉や表現を使わなくて良いので、自身が受け取ったものをそのまま表現してください。
kotouharuto

2020/07/02 05:43

はい、了解しました。 ありがとうございます。
guest

0

ベストアンサー

Call to a member function prepare() on null
を素直に読むと、null上でprepare()が実行されているという事です。

$stmh = $pdo->prepare('DELETE FROM todo WHERE id = :id'); //この文でエラーが出ています
と言うのがわかっているのであれば、$pdoに何かを代入しているところに問題があるのでしょう。

で、$pdoでコード内を検索してみると

$pdo = null;
$pdoがnullになっていますから、問題は多分ここでしょうね。
コメントアウトすれば動くと思いますよ。

お勧めというかデバッグ方法

PHP xdebug に使用しているIDEの名前を加えて検索してみて、デバッグ環境を整えることを最優先にすることをお勧めします。

投稿2020/07/01 09:31

編集2020/07/01 10:41
tanat

総合スコア18727

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kotouharuto

2020/07/01 10:16

ご回答ありがとうございました。 自分の記入漏れで申し訳ないのですが、$pdoでエラーが起きているというとこはわかっていて、$pdoの宣言元を確認したのですが、特に問題が確認できないので質問しました。 必要そうなので、そちらのコードの方も記載します、失礼いたしました。 わざわざありがとうございます! そちらのことについても調べさせていただきます!
tanat

2020/07/01 10:37

回答の $pdo = null; が原因なので、これをコメントアウトすればいけると思いますよ
kotouharuto

2020/07/01 12:10

ありがとうございます。 そちらの方コメントアウトしたら、Call to a member function prepare() on nullは消えたのでひとまずベストアンサーにさせていただきます!
tanat

2020/07/01 12:38

コメントとソースの印象からだと、 - コード1行1行の意味を把握しきれていない - デバッグの仕方を知らない - そのため、原因確認時に思い込みが入ってしまったり、勘に頼っている のであと一歩のところで原因にたどり着けない様に見受けられました。(責めている訳ではありません) 例えば今回のケースだと、 - xdebugを使ってブレークポイントを全行に仕掛けて$pdoがどのタイミングでnullになってしまっているかを確認するとか - var_dump(is_null($pdo))の様な検証コードを仕掛けてどのタイミングでnullになっているか確認する という方法を知っていれば 「$pdoでエラーが起きているというとこはわかっていて、$pdoの宣言元を確認したのですが、特に問題が確認できないので質問しました。」 という結論にはならなかったと思います。 ですので、xdebugを導入するとともに、 `PHP デバッグ 方法`などで、デバッグの仕方を学ばれるのが近道かと思いますよ。
kotouharuto

2020/07/01 22:02

ありがとうございます。 確かにそうでしたね、僕の方でも作ることを第一に考えてしまい確認作業を省いてしまっていました。 デバック方法を学んで出直してきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問