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ログインした時の初期状態)の状態になります。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/11/18 06:52
2021/11/18 07:54
2021/11/18 22:07
2021/11/18 22:11
2021/11/19 00:19