前提・実現したいこと
phpを勉強中です。todoリスト作成中でカラムを新たに追加し、createしたいがinputタグを増やすと動作しない
発生している問題・エラーメッセージ
エラーメッセージ
該当のソースコード
PHPindex
1<?php 2 3session_start(); 4 5require_once(__DIR__ . '/config.php'); 6require_once(__DIR__ . '/functions.php'); 7require_once(__DIR__ . '/Todo.php'); 8 9// get todos 10$todoApp = new \MyApp\Todo(); 11$todos = $todoApp->getAll(); 12 13 14// var_dump($todos); 15// exit; 16 17?> 18<!DOCTYPE html> 19<html lang="ja"> 20<head> 21 <meta charset="utf-8"> 22 <title>My Todos</title> 23 <link rel="stylesheet" href="styles.css"> 24</head> 25<body> 26 <div id="container"> 27 <h1>Todos</h1> 28 <form action="" id="new_todo_form"> 29 <input type="text" id="new_todo" placeholder="What needs to be done?"> 30 <input type="text" id="new_tag" placeholder="必要事項">←追加 31 </form> 32 <ul id="todos"> 33 <?php foreach ($todos as $todo) : ?> 34 <li id="todo_<?= h($todo->id); ?>" data-id="<?= h($todo->id); ?>"> 35 <input type="checkbox" class="update_todo" <?php if ($todo->state === '1') { echo 'checked'; } ?>> 36 <span class="todo_title <?php if ($todo->state === '1') { echo 'done'; } ?>"><?= h($todo->title); ?></span> 37 <span class="todo_title <?php if ($todo->state === '2') { echo 'done'; } ?>"><?= h($todo->tag); ?></span> 38 <div class="delete_todo">x</div> 39 </li> 40 <?php endforeach; ?> 41 <li id="todo_template" data-id=""> 42 <input type="checkbox" class="update_todo"> 43 <span class="todo_title"></span> 44 <div class="delete_todo">x</div> 45 </li> 46 </ul> 47 </div> 48 <input type="hidden" id="token" value="<?= h($_SESSION['token']); ?>"> 49 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> 50 <script src="todo.js"></script> 51</body> 52</html>
todo.php <?php // CSRF対策 // Token発行してSessionに格納 // フォームからもTokenを発行、送信 // Check namespace MyApp; class Todo { private $_db; public function __construct() { $this->_createToken(); try { $this->_db = new \PDO(DSN, DB_USERNAME, DB_PASSWORD); $this->_db->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); } catch (\PDOException $e) { echo $e->getMessage(); exit; } } private function _createToken() { if (!isset($_SESSION['token'])) { $_SESSION['token'] = bin2hex(openssl_random_pseudo_bytes(16)); } } public function getAll() { $stmt = $this->_db->query("select * from todos order by id desc"); return $stmt->fetchAll(\PDO::FETCH_OBJ); } public function post() { $this->_validateToken(); if (!isset($_POST['mode'])) { throw new \Exception('mode not set!'); } switch ($_POST['mode']) { case 'update': return $this->_update(); case 'create': return $this->_create(); case 'delete': return $this->_delete(); } } private function _validateToken() { if ( !isset($_SESSION['token']) || !isset($_POST['token']) || $_SESSION['token'] !== $_POST['token'] ) { throw new \Exception('invalid token!'); } } private function _update() { if (!isset($_POST['id'])) { throw new \Exception('[update] id not set!'); } $this->_db->beginTransaction(); $sql = sprintf("update todos set state = (state + 1) %% 2 where id = %d", $_POST['id']); $stmt = $this->_db->prepare($sql); $stmt->execute(); $sql = sprintf("select state from todos where id = %d", $_POST['id']); $stmt = $this->_db->query($sql); $state = $stmt->fetchColumn(); $this->_db->commit(); return [ 'state' => $state ]; } private function _create() { if (!isset($_POST['title']) || $_POST['title'] === '') { throw new \Exception('[create] title not set!'); } //////////////調べて試した部分/////////////////////////////////////////////////////////// $sql = "insert into todos (title,tag,created ) values (:title,:tag,now() )"; $sql->bindParam(':title',PDO::PARAM_STR); $sql->bindParam(':tag',PDO::PARAM_STR); $stmt = $this->_db->prepare($sql); // $stmt->execute([':title' => $_POST['title']]); // $stmt->execute([':tag' => $_POST['tag']]); $stmt->execute(); // $stmt->execute(array(':title' =>$key,':tag' =>$value)); ///////////////////////////////////////////////////////////////////////////////////// return [ 'id' => $this->_db->lastInsertId() ]; } private function _delete() { if (!isset($_POST['id'])) { throw new \Exception('[delete] id not set!'); } $sql = sprintf("delete from todos where id = %d", $_POST['id']); $stmt = $this->_db->prepare($sql); $stmt->execute(); return []; } }
todo.js $(function() { 'use strict'; $('#new_todo').focus(); // update $('#todos').on('click', '.update_todo', function() { // idを取得 var id = $(this).parents('li').data('id'); // ajax処理 $.post('_ajax.php', { id: id, mode: 'update', token: $('#token').val() }, function(res) { if (res.state === '1') { $('#todo_' + id).find('.todo_title').addClass('done'); } else { $('#todo_' + id).find('.todo_title').removeClass('done'); } }) }); // delete $('#todos').on('click', '.delete_todo', function() { // idを取得 var id = $(this).parents('li').data('id'); // ajax処理 if (confirm('are you sure?')) { $.post('_ajax.php', { id: id, mode: 'delete', token: $('#token').val() }, function() { $('#todo_' + id).fadeOut(800); }); } }); // create $('#new_todo_form').on('submit',function() { // titleを取得 var title = $('#new_todo').val(); var tag = $('#new_tag').val(); // ajax処理 $.post('_ajax.php', { title: title, tag: tag, mode: 'create', token: $('#token').val() }, function(res) { // liを追加 var $li = $('#todo_template').clone(); $li .attr('id', 'todo_' + res.id) .data('id', res.id) .find('.todo_title').text(title); $('#todos').prepend($li.fadeIn()); $('#new_todo').val('').focus(); }); return false; }); });
試したこと
todo.jsに追加したIDなどを記載したり、todo。phpにも追加したカラムを追加しようと調べ、自分なりに施した
補足情報(FW/ツールのバージョンなど)
PHP 7.1.23 バージョン
言語 php sql sequel pro
コード VScode
学習ツール ドットインストール
「なぜコードを書いているか」 =>複数パラメータに値を入れるやり方を知るため。それができれば追加カラムを使い、中間テーブルの勉強をするため
ここにより詳細な情報を記載してください。