前提・実現したいこと
PHPでカレンダーと連携したTodoリストを作成中です。
ドットインストールの「PHPのDatetimeクラスでカレンダーを作ろう」と、「PHPでtodo管理アプリを作ろう」を参考に進めています。カレンダーの日付にDatetimeから取得したリンク(~/index_todo.php?s=年月日8桁)を作り、そこからTodo管理アプリにとべるようになっています。
Todo管理画面でsubmitをしたときに、URLのパラメータからデータベースのdateの値を取得したいです。$_GET['s']としてurlの値の取得ができるかと試しましたが以下のようなエラーメッセージが表示されました。
どうすればsubmit時にURLのパラメータからdateを取得できるでしょうか。
ご回答お願い致します。
発生している問題・エラーメッセージ
PHP Notice: Undefined index: s in /home/vagrant/work_1_php/Todo/Todo.php on line 105
該当のソースコード
<Todo.php>
<sql> ``` create table todos ( id int not null auto_increment primary key, state tinyint(1) default 0, /* 0:not finished, 1:finished */ title text, date date ); ```<?php namespace MyApp; // var_dump($_GET['s']); // exit; 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() { $sql = sprintf("select * from todos where date = %d order by id desc", $_GET['s']); $stmt = $this->_db->query($sql); 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 _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 []; } private function _create() { if (!isset($_POST['title']) || $_POST['title'] === '') { throw new \Exception('[create] title not set!'); } $sql = "insert into todos (title, date) values (:title, :date)"; $stmt = $this->_db->prepare($sql); $stmt->execute([':title' => $_POST['title'], ':date' => $_GET['s']]); return [ 'id' => $this->_db->lastInsertId() ]; } }
<index_todo.php>
<?php session_start(); require_once(__DIR__ . '/config.php'); require_once(__DIR__ . '/functions.php'); require_once(__DIR__ . '/Todo.php'); // get todos $todoApp = new \MyApp\Todo(); $todos = $todoApp->getAll(); // var_dump($todos); // exit; ?> <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>Todos</title> <link rel="stylesheet" href="todo_styles.css"> </head> <body> <div id="container"> <h1>Todos</h1> <form action="#" id="new_todo_form"> <input type="text" id="new_todo"> </form> <ul id="todos"> <?php foreach ($todos as $todo) : ?> <li id="todo_<?= h($todo->id); ?>" data-id="<?= h($todo->id); ?>"> <input type="checkbox" class="update_todo" <?php if($todo->state === '1') { echo 'checked'; } ?>> <span class="todo_title <?php if($todo->state === '1') { echo 'done'; } ?>"> <?= h($todo->title); ?></span> <div class="delete_todo">×</div> </li> <?php endforeach; ?> <li id="todo_template" data-id=""> <input type="checkbox" class="update_todo"> <span class="todo_title"></span> <div class="delete_todo">×</div> </li> </ul> </div> <input type="hidden" id="token" value="<?= h($_SESSION['token']); ?>"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <script src="todo.js"></script> </body> </html>
<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(); // ajax処理 $.post('_ajax.php', { title: title, 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; }); });
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/12/10 08:15
2019/12/10 08:37
2019/12/10 13:25