\r\n\r\n\r\n```\r\nmain.js\r\n```ここに言語を入力\r\nコード\r\n\"use strict\";\r\n\r\n{\r\n const checkboxes= document.querySelectorAll('input[type=\"checkbox\"]');\r\n checkboxes.forEach(checkbox =>{\r\n checkbox.addEventListener(\"change\", () =>{\r\n checkbox.parentNode.submit();\r\n });\r\n });\r\n\r\n const deletes= document.querySelectorAll('.delete');\r\n deletes.forEach(span =>{\r\n span.addEventListener(\"click\", () =>{\r\n if(!confirm(\"Are you sure?\")){\r\n return;\r\n }\r\n span.parentNode.submit();\r\n });\r\n });\r\n\r\n const purge= document.querySelector('.purge');\r\n purge.addEventListener(\"click\", () =>{\r\n if(!confirm(\"Are you sure?\")){\r\n return;\r\n }\r\n purge.parentNode.submit();\r\n });\r\n}\r\n```\r\nmain.sql\r\n```ここに言語を入力\r\nコード\r\ncreate table todos(\r\n -- しっかりtodosと書いてある\r\n id int not null auto_increment,\r\n is_done bool default false,\r\n title text,\r\n primary key (id)\r\n);\r\n\r\ninsert into todos (title) values (\"aaa\");\r\ninsert into todos (title,is_done) values (\"bbb\",true);\r\ninsert into todos (title) values (\"ccc\");\r\n\r\nselect * from todos\r\n```\r\ntodo.php\r\n```ここに言語を入力\r\nコード\r\npdo = $pdo;\r\n Token::create();\r\n }\r\n\r\n public function processPost(){\r\n if ($_SERVER[\"REQUEST_METHOD\"] === \"POST\"){\r\n Token::validate ();\r\n // 下は問題点\r\n \r\n $action = filter_input(INPUT_GET, \"action\");\r\n \r\n switch ($action){\r\n case \"add\":\r\n $this->add();\r\n break;\r\n case \"toggle\":\r\n $this->toggle();\r\n break;\r\n case \"delete\":\r\n $this->delete();\r\n break;\r\n case \"purge\":\r\n $this->purge();\r\n break;\r\n default:\r\n exit;\r\n }\r\n \r\n header(\"Location:\". SITE_URL);\r\n exit;\r\n }\r\n }\r\n private function add(){\r\n $title = trim(filter_input(INPUT_POST, \"title\"));\r\n if($title === \"\"){\r\n return;\r\n }\r\n $stmt = $this->pdo->prepare(\"insert into todos(title) values (:title)\");\r\n $stmt->bindValue(\"title\", $title, \\PDO::PARAM_STR);\r\n // 上小文字ダメ絶対\r\n $stmt->execute();\r\n }\r\n \r\n private function toggle(){\r\n $id = filter_input(INPUT_POST, \"id\");\r\n if(empty($id)){\r\n return;\r\n }\r\n \r\n $stmt = $this->pdo->prepare(\"update todos set is_done = not is_done where id = :id\");\r\n $stmt->bindValue(\"id\", $id, \\PDO::PARAM_INT);\r\n $stmt->execute();\r\n }\r\n private function delete(){\r\n $id = filter_input(INPUT_POST, \"id\");\r\n if(empty($id)){\r\n return;\r\n }\r\n \r\n $stmt = $this->pdo->prepare(\"delete from todos where id = :id\");\r\n $stmt->bindValue(\"id\", $id, \\PDO::PARAM_INT);\r\n $stmt->execute();\r\n }\r\n\r\n private function purge(){\r\n $this->pdo->query(\"delete from todos where is_done=1\");\r\n }\r\n\r\n\r\n public function getAll() {\r\n // 下、今回の問題箇所\r\n $stmt= $this->pdo->query(\"select * from todos order by id desc\");\r\n // ///\r\n $todos= $stmt->fetchAll();\r\n return $todos;\r\n }\r\n}\r\n```\r\nToken.php\r\n```ここに言語を入力\r\nコード\r\nnamespace MyApp;\r\n\r\n class Token{\r\n public static function create (){\r\n if(!isset($_SESSION[\"token\"])){\r\n $_SESSION[\"token\"] = bin2hex(random_bytes(32));\r\n }\r\n }\r\n // 下がうまく作動しない\r\n public static function validate (){\r\n if (\r\n empty($_SESSION[\"token\"])||\r\n $_SESSION[\"token\"] !== filter_input(INPUT_POST, \"token\")\r\n ){\r\n exit(\"Invalid post request\");\r\n }\r\n }\r\n }\r\n```\r\nUtils.php\r\n```ここに言語を入力\r\nコード\r\n \\PDO::ERRMODE_EXCEPTION,\r\n \\PDO::ATTR_DEFAULT_FETCH_MODE => \\PDO::FETCH_OBJ,\r\n \\PDO::ATTR_EMULATE_PREPARES => false,\r\n ]\r\n );\r\n }\r\n \r\n return self::$instance;\r\n \r\n } catch(\\PDOException $e){\r\n echo $e->getMessage();\r\n exit;\r\n }\r\n }\r\n }\r\n```\r\nconfig.php\r\n```ここに言語を入力\r\nコード\r\n(mysql niログインした時の初期状態)にぺ-ストすれば解決しました\r\n\r\n\r\n main.sql\r\n ``` \r\ncreate table todos(\r\n -- しっかりtodosと書いてある\r\n id int not null auto_increment,\r\n is_done bool default false,\r\n title text,\r\n primary key (id)\r\n);\r\n\r\ninsert into todos (title) values (\"aaa\");\r\ninsert into todos (title,is_done) values (\"bbb\",true);\r\ninsert into todos (title) values (\"ccc\");\r\n\r\nselect * from todos\r\n```\r\n\r\n\r\n\r\n\r\n\r\n 初心者というのもあってmysql はログイン方法すらわかりませんでしたが\r\nまず、今回使うファイルにcdコマンドで移動して\r\ndocker-compose exec db bash\r\n次に\r\nmysql -u ユーザー名 -D データベース名 -p\r\n(今回の場合は\r\nmysql -u myappuser -p myapp ですが)\r\nその次にパスワードを聞かれるので\r\nお明日ワードを入力\r\n(今回の場合は\r\nmyapppassですが)\r\nで、\r\nmysql >(mysql niログインした時の初期状態)の状態になります。","answerCount":1,"upvoteCount":0,"datePublished":"2021-11-18T05:40:47.916Z","dateModified":"2021-11-19T03:41:28.672Z","acceptedAnswer":{"@type":"Answer","text":"`A.B`は「Aに所属(所有)するB」という意味合いです。\r\n良く「テーブルのカラム」を明示するときにも使いますね。\r\nただテーブルもどこかのデータベースに所属しています。\r\n何も明示しなければ接続しているデータベース内を探しに行きます。\r\n\r\nDSNで接続先としてmyappという名前のデータベースを指定してるのだと思いますが(提示されてないので想像)、そのデータベースmyapp内にtodosというテーブルがないという意味です。\r\nSQLファイルに書いたから勝手に実行してくれるわけではないので、使いたいデータベースに対して確実に実行してください。","dateModified":"2021-11-18T05:53:20.169Z","datePublished":"2021-11-18T05:48:07.176Z","upvoteCount":0,"url":"https://teratail.com/questions/369912#reply-501810"},"suggestedAnswer":[],"breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"https://teratail.com","name":"トップ"}},{"@type":"ListItem","position":2,"item":{"@id":"https://teratail.com/tags/PHP","name":"PHPに関する質問"}},{"@type":"ListItem","position":3,"item":{"@id":"https://teratail.com/questions/369912","name":"PHPのTodoアプリ作成,エラーについて"}}]}}}
質問するログイン新規登録

Q&A

解決済

1回答

1461閲覧

PHPのTodoアプリ作成,エラーについて

Maruco2321

総合スコア118

PHP

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

0グッド

0クリップ

投稿2021/11/18 05:40

編集2021/11/19 03:41

0

0

MacのVScodeにてPHPのTodoアプリを作成しています。データベースはMySqlを利用しています。
エラーが出たのですがこれを解決するのに詰まっている状態です。エラーの内容は下記のようになっています。
エラーの内容はテーブルのmyapp.todosなんか存在しないよ!という意味だと思うのですが下記のようにmain.sqlにはtodosというテーブルがしっかり書かれています(myapp.todosではなくtodosテーブルで作業を進めていきたいです)
どこで待ちせてしまっている結果myapptodosテーブルというないテーブルを使えという命令が出されているのでしょうか?よろしくお願いします????‍♂️
###エラー文
イメージ説明

###写真、ファイル構成
イメージ説明

###コード
index.php

コード <?php require_once(__DIR__ ."/../app/config.php"); use MyApp\Database; use MyApp\Todo; use MyApp\Utils; $pdo = Database::getInstance(); $todo = new Todo($pdo); $todo->processPost(); $todos = $todo->getAll(); ?> <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>My Todos</title> <link rel="stylesheet" href="css/styles.css"> </head> <body> <main> <header> <h1>To do list</h1> <form action="?action=purge" method="post" class="delete-form"> <span class="purge">purge</span> <input type="hidden" name="token" value="<?= Utils::h($_SESSION["token"]);?>"> </form> </header> <form action="?action=add" method="post"> <input type="text" name="title" placeholder="Type new todo."> <input type="hidden" name="token" value="<?= Utils::h($_SESSION["token"]);?>"> </form> <ul> <?php foreach($todos as $todo): ?> <li> <form action="?action=toggle" method="post"> <input type="checkbox" <?= $todo->is_done ? "checked" : ""; ?>> <input type="hidden" name="id" value="<?= Utils::h($todo->id);?>"> <input type="hidden" name="token" value="<?= Utils::h($_SESSION["token"]);?>"> </form> <span class="<?= $todo->is_done ? "done" : ""; ?>"> <?= Utils::h($todo->title); ?> </span> <form action="?action=delete" method="post" class="delete-form"> <span class="delete">x</span> <input type="hidden" name="id" value="<?= Utils::h($todo->id)?>"> <input type="hidden" name="token" value="<?= Utils::h($_SESSION["token"]);?>"> </form> </li> <?php endforeach; ?> </ul> </main> <script src="js/main.js"></script> </body> </html>

main.js

コード "use strict"; { const checkboxes= document.querySelectorAll('input[type="checkbox"]'); checkboxes.forEach(checkbox =>{ checkbox.addEventListener("change", () =>{ checkbox.parentNode.submit(); }); }); const deletes= document.querySelectorAll('.delete'); deletes.forEach(span =>{ span.addEventListener("click", () =>{ if(!confirm("Are you sure?")){ return; } span.parentNode.submit(); }); }); const purge= document.querySelector('.purge'); purge.addEventListener("click", () =>{ if(!confirm("Are you sure?")){ return; } purge.parentNode.submit(); }); }

main.sql

コード create table todos( -- しっかりtodosと書いてある id int not null auto_increment, is_done bool default false, title text, primary key (id) ); insert into todos (title) values ("aaa"); insert into todos (title,is_done) values ("bbb",true); insert into todos (title) values ("ccc"); select * from todos

todo.php

コード <?php namespace MyApp; class Todo{ private $pdo; public function __construct($pdo){ $this->pdo = $pdo; Token::create(); } public function processPost(){ if ($_SERVER["REQUEST_METHOD"] === "POST"){ Token::validate (); // 下は問題点 $action = filter_input(INPUT_GET, "action"); switch ($action){ case "add": $this->add(); break; case "toggle": $this->toggle(); break; case "delete": $this->delete(); break; case "purge": $this->purge(); break; default: exit; } header("Location:". SITE_URL); exit; } } private function add(){ $title = trim(filter_input(INPUT_POST, "title")); if($title === ""){ return; } $stmt = $this->pdo->prepare("insert into todos(title) values (:title)"); $stmt->bindValue("title", $title, \PDO::PARAM_STR); // 上小文字ダメ絶対 $stmt->execute(); } private function toggle(){ $id = filter_input(INPUT_POST, "id"); if(empty($id)){ return; } $stmt = $this->pdo->prepare("update todos set is_done = not is_done where id = :id"); $stmt->bindValue("id", $id, \PDO::PARAM_INT); $stmt->execute(); } private function delete(){ $id = filter_input(INPUT_POST, "id"); if(empty($id)){ return; } $stmt = $this->pdo->prepare("delete from todos where id = :id"); $stmt->bindValue("id", $id, \PDO::PARAM_INT); $stmt->execute(); } private function purge(){ $this->pdo->query("delete from todos where is_done=1"); } public function getAll() { // 下、今回の問題箇所 $stmt= $this->pdo->query("select * from todos order by id desc"); // /// $todos= $stmt->fetchAll(); return $todos; } }

Token.php

コード namespace MyApp; class Token{ public static function create (){ if(!isset($_SESSION["token"])){ $_SESSION["token"] = bin2hex(random_bytes(32)); } } // 下がうまく作動しない public static function validate (){ if ( empty($_SESSION["token"])|| $_SESSION["token"] !== filter_input(INPUT_POST, "token") ){ exit("Invalid post request"); } } }

Utils.php

コード <?php namespace MyApp; class Utils{ public static function h($str){ return htmlspecialchars($str,ENT_QUOTES, "utf-8"); } }

Database.php

コード <?php namespace MyApp; class Database{ private static $instance; public static function getInstance(){ try{ if(!isset(self::$instance)){ self::$instance = new \PDO( DSN, DB_USER, DB_PASS, [ \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_OBJ, \PDO::ATTR_EMULATE_PREPARES => false, ] ); } return self::$instance; } catch(\PDOException $e){ echo $e->getMessage(); exit; } } }

config.php

コード <?php session_start(); define("DSN", "mysql:host=db;dbname=myapp;charset=utf8mb4"); define("DB_USER", "myappuser"); define("DB_PASS", "myapppass"); // define("SITE_URL", "http://localhost:8562"); define("SITE_URL", "http://".$_SERVER["HTTP_HOST"] ); spl_autoload_register(function($class){ $prefix = "MyApp\"; if(strpos($class, $prefix) === 0){ $fileName = sprintf(__DIR__. "/%s.php", substr($class, strlen($prefix))); if(file_exists($fileName)){ require($fileName); }else{ echo "File not found:".$fileName; exit; } } });

###追記
docker-compose.yml

コード --- version: "3.8" services: db: build: ./mysql environment: TZ: "Asia/Tokyo" MYSQL_ROOT_PASSWORD: rootpass MYSQL_DATABASE: myapp MYSQL_USER: myappuser MYSQL_PASSWORD: myapppass volumes: - db-data:/var/lib/mysql php: build: ./php depends_on: - db ports: - 8562:8000 volumes: - ./work:/work volumes: db-data:

###解決方法
最初の段階でまずMYSQLにログインして、その後main.sqlの内容全てをそのままコピペして
mysql >(mysql niログインした時の初期状態)にぺ-ストすれば解決しました

main.sql

create table todos( -- しっかりtodosと書いてある id int not null auto_increment, is_done bool default false, title text, primary key (id) ); insert into todos (title) values ("aaa"); insert into todos (title,is_done) values ("bbb",true); insert into todos (title) values ("ccc"); select * from todos

初心者というのもあってmysql はログイン方法すらわかりませんでしたが
まず、今回使うファイルにcdコマンドで移動して
docker-compose exec db bash
次に
mysql -u ユーザー名 -D データベース名 -p
(今回の場合は
mysql -u myappuser -p myapp ですが)
その次にパスワードを聞かれるので
お明日ワードを入力
(今回の場合は
myapppassですが)
で、
mysql >(mysql niログインした時の初期状態)の状態になります。

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

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

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

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

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

guest

回答1

0

ベストアンサー

A.Bは「Aに所属(所有)するB」という意味合いです。
良く「テーブルのカラム」を明示するときにも使いますね。
ただテーブルもどこかのデータベースに所属しています。
何も明示しなければ接続しているデータベース内を探しに行きます。

DSNで接続先としてmyappという名前のデータベースを指定してるのだと思いますが(提示されてないので想像)、そのデータベースmyapp内にtodosというテーブルがないという意味です。
SQLファイルに書いたから勝手に実行してくれるわけではないので、使いたいデータベースに対して確実に実行してください。

投稿2021/11/18 05:48

編集2021/11/18 05:53
m.ts10806

総合スコア80890

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

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

Maruco2321

2021/11/18 06:52

SQLファイルに書いたから勝手に実行してくれるわけではないので、使いたいデータベースに対して確実に実行してください。 ↑なるほど!自分の認識が間違っていたようです。それを参考に解決できそうなので作業を進めていきたいと思います。ありがとうぎざいました????‍♂️
m.ts10806

2021/11/18 07:54

可能なら解決できてから質問解決済みにしていただきたく。
Maruco2321

2021/11/18 22:07

実は解決しようと思いましたが、 DSNで接続先としてmyappという名前のデータベースを指定してるのだと思いますが、 ↑これはおそらくその通りだと思います。追記にも載せましたが config.phpに define("DSN", "mysql:host=db;dbname=myapp;charset=utf8mb4"); と記述しているからです。ただ、 そのデータベースmyapp内にtodosというテーブルがないという意味 ↑これに関して、データベースmyapp内にtodosというテーブルを作るためにはどうすればいいのかで止まってしまっているのが現状です。何か解決策等あればご教示いただけると助かります
Maruco2321

2021/11/18 22:11

↑config.phpではないですね docker-compose.ymlのMYSQL_DATABASE: myappの方だと思います。訂正します
m.ts10806

2021/11/19 00:19

何かしらコマンドとかツールででMySQLに接続してmyappというデータベースにアクセスしてテーブル作れば良いだけかと。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.29%

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

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

質問する

関連した質問