🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
MySQL

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

PDO

PDO(PHP Data Objects)はPHPのデータベース抽象化レイヤーです。

PHP

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

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

XAMPP

XAMPP(ザンプ)は、ウェブアプリケーションの実行に必要なフリーソフトウェアをパッケージングしたApacheディストリビューションです。 XAMPPひとつインストールするだけで、Apache、MySQL、PHP、Perlなどのソフトウェアと、 phpMyAdminなどの管理ツール、SQLiteなどのソフトウェアやライブラリモジュールなどを利用することが可能です。

Q&A

解決済

3回答

1418閲覧

検索システム:エラー 解決手段が分かりません

Sakuya1127

総合スコア1

MySQL

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

PDO

PDO(PHP Data Objects)はPHPのデータベース抽象化レイヤーです。

PHP

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

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

XAMPP

XAMPP(ザンプ)は、ウェブアプリケーションの実行に必要なフリーソフトウェアをパッケージングしたApacheディストリビューションです。 XAMPPひとつインストールするだけで、Apache、MySQL、PHP、Perlなどのソフトウェアと、 phpMyAdminなどの管理ツール、SQLiteなどのソフトウェアやライブラリモジュールなどを利用することが可能です。

0グッド

0クリップ

投稿2021/02/08 17:46

編集2021/02/09 05:03

イメージ説明

前提・実現したいこと

MySQLに保存したカードデータの中から該当カードを検索する事の出来る
カード検索システムを作成したいと思っています([メ]と打てばどちらの名前が出てくるようにしたいです。)
テーブルが存在していないエラーだという事は何となく理解できるのですが解決手段が分かりません。

発生している問題・エラーメッセージ

Eroor:SQLSTATE[42S02]: Base table or view not found: 1146 Table 'cardfolder.name' doesn't exist

該当のソースコード

sample_search_form.html

1 2<!DOCTYPE html> 3<html lang="en"> 4<head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>検索フォーム</title> 8</head> 9<body> 10 <h1>カード検索</h1> 11 <form method="post" action="sample_search.php"> 12 <input type="text" name="yourname"> 13 <input type="submit" value="検索する"> 14 </form> 15</body> 16</html>

sample_search.php

1 2<?php 3header("Content-type: text/html; charset=utf-8"); 4$errors = array(); 5if(empty($_POST)){ 6 header("Location: sample_search_form.html"); 7 exit(); 8}else{ 9 if(!isset($_POST['yourname']) ||$_POST['yourname'] ===""){ 10 $errors['name'] = "名前が入力されていません"; 11 } 12} 13 14if(count($errors) === 0){ 15 $dsn = 'mysql:host=localhost;dbname=cardfolder;charset=utf8'; 16 $user = 'root'; 17 $pass = 'root'; 18 19 try{ 20 $dbh = new PDO($dsn,$user,$pass); 21 $statemant = $dbh->prepare("SELECT * FROM name WHERE name LIKE (:name) "); 22 23 if($statemant){ 24 $yourname = $_POST['yourname']; 25 $like_yourname = "%".$yourname."%"; 26 $statemant->bindValue(':name',$like_yourname,PDO::PARAM_STR); 27 28 if($statemant->execute()){ 29 $row_count = $statemant->rowCount(); 30 while($row = $statemant->fetch()){ 31 $rows[] = $row; 32 } 33 }else{ 34 $errors['error'] = "検索失敗しました。"; 35 } 36 37 $dbh = null; 38 } 39 40 }catch(PDOException $e){ 41 print('Eroor:'.$e->getMessage()); 42 $errors['error'] = "データベースに接続失敗しました。"; 43 } 44} 45 46?> 47 48<!DOCTYPE html> 49<html lang="en"> 50<head> 51 <meta charset="UTF-8"> 52 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 53 <title>検索結果</title> 54</head> 55<body> 56 <?php if(count($errors) === 0): ?> 57 <p><?=htmlspecialchars($yourname,ENT_QUOTES,'UTF-8')."で検索しました。"?></p> 58 <p><?=$row_count?>件です。</p> 59 60 <table border='1'> 61 <tr><td>id</td><td>name</td></tr> 62 63 <?php 64 foreach($rows as $row){ 65 ?> 66 <tr> 67 <td><?=$row['id']?></td> 68 <td><?=htmlspecialchars($row['name'],ENT_QUOTES,'UTF-8')?></td> 69 </tr> 70 <?php 71 } 72 ?> 73 74 <?php elseif(count($errors) > 0): ?> 75 <?php 76 foreach($errors as $value){ 77 echo "<p>".$value."</p>"; 78 } 79 ?> 80 <?php endif; ?> 81</body> 82</html>

試したこと

変数が未定義と言う事だったので(isset($errors)===0)にして見ましたが、別の行にて同じエラーが発生してしまい、解決策が分かりませんでした。

補足情報(FW/ツールのバージョンなど)

xamppを用いてApache、MySQLを導入し、VScodeでコードの方を入力しています。
エラーが起きているコードは下のPHPの方です。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2021/02/09 01:04

「MySQLに保存したカードデータの中から該当カードを検索する」とありますが、全くデータ構造が伝わらないのでPDO経由でのデータベースアクセスを検証することができません。CREATE TABLE文など構造がわかるものを質問文中に示すことはできますか?
退会済みユーザー

退会済みユーザー

2021/02/09 04:30

伝わってないようなのでもう一度。「1146 Table 'cardfolder.name' doesn't exist」というエラーメッセージを見ると、では正しいテーブル名やカラム名はなんだろう、そこに答えがあるはずって考えるのですが、サンプルデータよりもデータの構造がわかるものとしてもっとも確実なのはCREATE TABLE文によるもので、次にはphpMyAdminであれば「表示」タブのとなりに「構造」があるのでその場面のスクリーンショットなのではないかと思うのですが。 https://qiita.com/neneta0921/items/80169f34886fd8ec8264
Sakuya1127

2021/02/09 05:05

申し訳ございません。 初心者故に勘違いしておりました。 構造の方のスクリーンショットを載せさせていただきました。
m.ts10806

2021/02/09 06:34

phpMyAdminでしたらエクスポート機能でテーブル定義のSQL(CREATE TABLE)を得られます。そちらを提示されたほうが回答者としては手元で再現できるので助かります。 スクリーンショットを提示する要件は基本的には画面レイアウトを伝えたいときです。
guest

回答3

0

ベストアンサー

テーブルの構造を示す画像の提供、ありがとうございます。
ですが、これではテーブル名がわかりません。(カラム名とデータ型はわかるのでありがたいですが。)

$statemant = $dbh->prepare("SELECT * FROM name WHERE name LIKE (:name) ");
FROM nameはテーブル名を示すところです。
テーブル名がnameではなくcardfolderであるならば、
FROM cardfolderで有るべきです。

ですが、気になるのがもう一箇所、

$dsn = 'mysql:host=localhost;dbname=cardfolder;charset=utf8';
dbname=cardfolderでは、データベース名がcardfolderでないといけなくなります。
作ってあるデータベース名と食い違うのではないでしょうか。
正しいデータベース名を使ってください。


あと本筋とずれる、気になるところ。

php

1<?php 2header("Content-type: text/html; charset=utf-8");

header()関数を書いてもいいんですが、php.ini等でサイト全体的に設定しておくべきものなので、
ファイル個別に、都度記述するのは無駄です。
(昔は特定のページだけ別エンコーディングを使うなんてことがあったので、参考資料が古いのかも。)

php

1if(empty($_POST)){ 2 header("Location: sample_search_form.html"); 3 exit(); 4}

先にheader()関数でHTTP応答ヘッダー出力に干渉した後にLocation: ヘッダーを出力するのはおかしいので、
この点からも、header("Content-type: text/html; charset=utf-8");は要らない、
もしくはこのif()よりも後に出力することをおすすめします。


php

1$dsn = 'mysql:host=localhost;dbname=cardfolder;charset=utf8';

テーブルの構造を示す画像から察するに、charset=utf8mb4じゃないかと。
mysqlにおけるutf8とutf8mb4の違いは、
emojiなども含めたすべてのUTF-8エンコーディング文字列を扱えるよう、
最大4バイトまで駆使したマルチバイト文字列を使うってことです。

ちなみに、phpにおいてはutf-8でmysqlでいうutf8mb4エンコーディングのを扱えるようになっています。
表記が違っても気にしない。

php

1$dbh = new PDO($dsn,$user,$pass);

悪くはないけど、PDO()4つ目のdriver_optionsにて、エラー発生時に例外をスローするように与えておくと良いかも。

php

1$dbh = new PDO($dsn, $user, $pass, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);

php

1$statemant = $dbh->prepare("SELECT * FROM name WHERE name LIKE (:name) ");

LIKEにかっこは要らないです。SQLの文法を公式ドキュメントなどで改めてチェックしてみてください。


php

1$row_count = $statemant->rowCount();

PDOStatement::rowCount
によると、〈直近の SQL ステートメントによって作用した行数を返す〉とあり、
なんとなくSELECT文によって抽出されたレコード数が得られそうな雰囲気を感じますが、違います。
UPDATE文あるいはINSERT文によって影響を受けたレコード数を得るのが主な目的で、
SELECT文についてはフェッチモードがバッファクエリであればバッファ上でカウントしてくれるけど、
普通はそこまで意識して使わないので、
PDOStatement::setFetchModeを組み合わせないと狙った効果が得られません。

よって、
本当に一致した件数を取得したいときは、「SELECT count(*) ~」なクエリーを実行して取得する方法をおすすめします。


最後に、インデント量を揃えて規則性をもたせて、
「,」や「.」付近に適切に空白を挟んでコードを読みやすくすることをおすすめします。
VScodeなどphpコードを整形してくれるようなエディタはいくつかあるので、
そういうのを活用するのも良いです。

それと、データベースアクセス周りは、
ベテランでも何度も読み返すこちらの記事を是非。
PHPでデータベースに接続するときのまとめ - Qiita

投稿2021/02/09 06:12

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

Sakuya1127

2021/02/09 06:24

ものすごく丁寧な解説ありがとうございます。 根本的に呼び出すデータ名の部分がカラム名の方を記載しているものとなっていました。訂正後は起動するようにはなりました。 しかし、訂正箇所は多く見られるのが理解出来たため、修正していこうと思います。 何度も質問回答していただき、改めてありがとうございました。
guest

0

データベース名、テーブル名、カラム名の3つの要素がごっちゃになってるような気がします。スクリーンショットから見る限り(カラム名だけの情報しかなく正直足りないのですが)はnameはカラム名のように見えますが、

SELECT * FROM name WHERE name LIKE (:name)

というSQL文はnameというテーブルの中にnameというカラムがあるような書き方になっています。そんなややこしいテーブル名を付ける気がしないのでおそらく間違ってると思います。

cardfolderというのはデータベース名として扱っているようですが、これも本当に正しいですか? もしかしてこれはテーブル名がcardfolderだったりしませんか? そうするとデータベース名はこの情報だけでは何かは分かりませんけど。

phpMyAdmin上で確認できますので、今一度3要素をしっかり確認してから、データベースの接続の箇所とSQL文を正しく書き直してみるといいと思います。

投稿2021/02/09 06:03

編集2021/02/09 06:05
AbeTakashi

総合スコア4853

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

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

Sakuya1127

2021/02/09 06:28

3要素確認した所、データテーブルを記載する箇所にカラム名を記載していました。 訂正後、動いてくれました。 ありがとうございます。
guest

0

cardfolderという名のDBにnameというテーブルを作れば良いのでは。
まずはDB内のテーブル確認から。
ただ、本当にnameというテーブルを指定したかったのかどうかはこの内容ではわかりませんし、
設計次第です。

あとPDOStatement::rowCountは注意が必要です。

関連する PDOStatement によって実行された直近の SQL ステートメントが SELECT 文の場合、いくつかのデータベースは文によって返された 行数を返すかも知れません。**しかしながら、 この振る舞いは全てのデータベースで保証されていません。 さまざまな場所で使用するアプリケーションでは、 これに頼ってはいけません。 **

別途SQLでcount()するか、同じSQLで全件数を取得する機能(MySQLの場合FOUND_ROWS()またはSQL_CALC_FOUND_ROWS )を利用してください。

投稿2021/02/08 21:14

m.ts10806

総合スコア80875

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

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

退会済みユーザー

退会済みユーザー

2021/02/09 01:05

加えて、MySQLだとテーブル名やカラム名にバッククォートを打ったほうが安全かも?
m.ts10806

2021/02/09 01:08

確実に必要なシーンに出会ったことがないのですが、明示のためにはあったほうがいいかもしれませんね。 フォローありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問