質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.35%
さくらのレンタルサーバ

さくらのレンタルサーバとは、格安サーバーで知られるさくらインターネット社の提供する共有レンタルサーバー。Webサイトの構築から簡単なプログラミングまで幅広く利用することができ、プランが多いことも特徴です。

INSERT

INSERTとは、行を追加する、コンピュータのデータベース言語SQLにおけるデータ操作言語(DML)ステートメントの1つである

MySQL

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

PHP

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

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

解決済

1回答

1166閲覧

ajaxでレコードを新規追加できなくなった

Nishin

総合スコア30

さくらのレンタルサーバ

さくらのレンタルサーバとは、格安サーバーで知られるさくらインターネット社の提供する共有レンタルサーバー。Webサイトの構築から簡単なプログラミングまで幅広く利用することができ、プランが多いことも特徴です。

INSERT

INSERTとは、行を追加する、コンピュータのデータベース言語SQLにおけるデータ操作言語(DML)ステートメントの1つである

MySQL

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

PHP

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

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

0クリップ

投稿2021/12/30 10:49

youtube動画のタイトルやurl等を同画面のモーダルで登録し、テーブルに一覧表示したものから選択すると、テーブル下にビデオフレームが表示されて閲覧できるアプリを作成しています。

現在起こっている問題

 ajaxを使った処理のうち、新規登録処理だけができなくなり、処理実行後に表示されるアラートに「登録に失敗しました」と表示される状態が続いています。

以前は他のCRUD機能と同様に新規登録処理も正しく行われており、登録処理後はテーブルがリロードされて、レコードが追加された状態で表示されるようになっていました。
この新規登録処理に関わるファイルは、次の通りです。

PHP

1./db.php 2 3<?php 4$dsn = (私のDBアドレス); 5$dbname = (私のDB名); 6$username = (ユーザー名); 7$password = (パスワード); 8$connection = new PDO( 'mysql:host='.$dsn.';dbname='.$dbname, $username, $password );

PHP

1./youtubeAdmin/index.php 2 3<html> 4<?php 5 include('../db.php'); 6 include('function.php'); 7?> 8<head> 9 <title>My Admin Page</title> 10 <!-- ajaxやbootstrapに必要な部分。省略 --> 11</head> 12 13<body> 14 <input type="hidden" id="theme" value=<?php echo $theme ?>> 15 <div align="center"> 16 <div id="adminLinks"></div> 17 </div> 18 <div class="container box"> 19 <h1 id="title" align="center"></h1> 20 <br> 21 <div class="table-responsive"> 22 <br> 23 <div align="right"> 24 <button type="button" id="add_button" data-toggle="modal" data-target="#userModal" class="btn btn-info btn-lg">新規追加</button> 25 </div> 26 <br> 27 <br> 28 <table id="user_data" class="table table-bordered table-striped"> 29 <!-- テーブルの表示に関わる記述。一覧表示は出来ている為。記述量の関係上、省略 --> 30 </table> 31 </div> 32 </div> 33 <div id="tubeFrame" align="center"></div> 34 <div id="userModal" class="modal fade"> 35 <div class="modal-dialog"> 36 <form method="post" id="user_form" enctype="multipart/form-data"> 37 <div class="modal-content"> 38 <div class="modal-header"> 39 <button type="button" class="close" data-dismiss="modal">×</button> 40 <h4 class="modal-title">新規追加</h4> 41 </div> 42 <div class="modal-body"> 43 <label for=<?php echo $column[1] ?>><?php echo $td[1] ?></label> 44 <input type="text" name=<?php echo $column[1] ?> id=<?php echo $column[1] ?> class="form-control" placeholder=<?php echo $td[1]."を入力" ?>> 45 <br> 46 <table id="tube_genre" class="table table-bordered table-striped"> 47 <thead> 48 <tr><th class="nowrap"><?php echo $td[1]."候補" ?></th></tr> 49 </thead> 50 <tbody> 51 <?php 52 $genre_result = get_statement("SELECT DISTINCT genre FROM $table WHERE LENGTH(genre) > 0"); 53 foreach ($genre_result as $genre_row) { 54 echo "<tr><td><span class='info info_genre'>".$genre_row["genre"]."</span></td></tr>"; 55 } 56 ?> 57 </tbody> 58 </table> 59 <label for=<?php echo $column[2] ?>><?php echo "動画".$td[2] ?></label> 60 <input type="text" name=<?php echo $column[2] ?> id=<?php echo $column[2] ?> class="form-control" placeholder=<?php echo "動画".$td[2]."を入力" ?>> 61 <br> 62 <label for=<?php echo $column[3] ?>><?php echo "動画URL" ?></label> 63 <input type="text" name=<?php echo $column[3] ?> id=<?php echo $column[3] ?> class="form-control" placeholder=<?php echo "動画URLを入力" ?>> 64 <br> 65 <label for=<?php echo $column[4] ?>><?php echo $td[3] ?></label> 66 <input type="text" name=<?php echo $column[4] ?> id=<?php echo $column[4] ?> class="form-control" placeholder=<?php echo $td[3]."を入力" ?>> 67 <br> 68 <table id="tube_channel" class="table table-bordered table-striped"> 69 <thead> 70 <tr><th class="nowrap"><?php echo $td[3]."候補" ?></th></tr> 71 </thead> 72 <tbody> 73 <?php 74 $channel_result = get_statement("SELECT DISTINCT channel FROM $table WHERE LENGTH(channel) > 0"); 75 foreach ($channel_result as $channel_row) { 76 echo "<tr><td><span class='info info_channel'>".$channel_row["channel"]."</span></td></tr>"; 77 } 78 ?> 79 </tbody> 80 </table> 81 <br> 82 <label for=<?php echo $column[5] ?>><?php echo $td[4]."フラグ" ?></label><span> </span> 83 <select name=<?php echo $column[5] ?> id=<?php echo $column[5] ?> class="form-select form-select-sm" aria-label=".form-select-sm"> 84 <option value="1">公開 </option> 85 <option value="0">非公開 </option> 86 </select> 87 <br> 88 </div> 89 <div class="modal-footer"> 90 <input type="hidden" name="user_id" id="user_id"> 91 <input type="hidden" name="operation" id="operation"> 92 <input type="submit" name="action" id="action" class="btn btn-success" value="新規追加"> 93 <button type="button" class="btn btn-default" data-dismiss="modal">閉じる</button> 94 </div> 95 </div> 96 </form> 97 </div> 98</div> 99<script type="text/javascript" language="javascript"> 100 function _(query){ return document.querySelector(query) } 101 102 const theme = _("#theme").value; 103 document.title = theme; 104 _("#title").innerText = theme; 105 106 $('#add_button').click(function(){ 107 $('#user_form')[0].reset(); 108 $('.modal-title').text("新規追加"); 109 $('#action').val("新規追加"); 110 $('#operation').val("Add"); 111 }); 112 113 var user_data = $('#user_data').DataTable({ 114 "language": { 115 "url": "http://cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/Japanese.json" 116 }, 117 "processing": true, 118 "serverSide": true, 119 "order": [], 120 "ajax": { 121 url:"fetch.php", 122 type:"POST" 123 }, 124 "columnDefs": [ 125 { "targets": [0], "width": "10%" }, 126 { "targets": [2,3], "width": "30%" }, 127 ] 128 }); 129 130 create_soloTable("#tube_genre"); 131 create_soloTable("#tube_channel"); 132 133 function create_soloTable(target){ 134 $(target).DataTable({ 135 "language": { 136 "url": "http://cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/Japanese.json" 137 }, 138 "info": false, 139 "paging:": true, 140 'pagingType': 'full_numbers', 141 "lengthMenu": [ 5, 10 ], 142 }); 143 } 144 145 $(document).on('submit', '#user_form', function(event){ 146 147 event.preventDefault(); 148 var input_1 = document.querySelector('#<?php echo $column[1] ?>').value.trim(); 149 var input_2 = document.querySelector('#<?php echo $column[2] ?>').value.trim(); 150 var input_3 = document.querySelector('#<?php echo $column[3] ?>').value.trim(); 151 var input_4 = document.querySelector('#<?php echo $column[4] ?>').value.trim(); 152 var input_5 = document.querySelector('#<?php echo $column[5] ?>').value.trim(); 153 var match_3 = /^https://www.youtube/.test(input_3); 154 155 var alert_message = ""; 156 if(input_2.length < 1 || input_3.length < 1){ 157 alert_message += "入力されていない箇所があります。"; 158 } 159 160 if(alert_message == ""){ 161 if(confirm("レコードを登録しても、よろしいですか?")){ 162 $.ajax({ 163 url:"insert.php", 164 method:'POST', 165 data:new FormData(this), 166 contentType:false, 167 processData:false, 168 success:function(data){ 169 if(data > 0){ 170 alert("登録が完了しました。"); 171 }else{ 172 alert("登録に失敗しました。"); 173 } 174 $('#user_form')[0].reset(); 175 $('#userModal').modal('hide'); 176 user_data.ajax.reload(); 177 } 178 }); 179 } 180 }else{ 181 alert(alert_message); 182 } 183 }); 184 185</script> 186</body> 187</html>

PHP

1./youtubeAdmin/insert.php 2 3<?php 4include('../db.php'); 5include('function.php'); 6//session_start(); 7 8$column_1 = htmlspecialchars($_POST[$column[1]], ENT_QUOTES, 'UTF-8'); 9$column_2 = htmlspecialchars($_POST[$column[2]], ENT_QUOTES, 'UTF-8'); 10$column_3 = htmlspecialchars($_POST[$column[3]], ENT_QUOTES, 'UTF-8'); 11$column_4 = htmlspecialchars($_POST[$column[4]], ENT_QUOTES, 'UTF-8'); 12$column_5 = htmlspecialchars($_POST[$column[5]], ENT_QUOTES, 'UTF-8'); 13 14if(isset($_POST["operation"])){ 15 if($_POST["operation"] == "Add"){ 16 $statement = $connection->prepare(" 17 INSERT INTO ".$table." (" 18 .$column[1].", ".$column[2].", ".$column[3].", " 19 .$column[4].", ".$column[5].") VALUES (:" 20 .$column[1].", :".$column[2].", :".$column[3].", :" 21 .$column[4].", ".$column[5].")"); 22 $result = $statement->execute( 23 array( 24 ':'.$column[1] => $column_1, 25 ':'.$column[2] => $column_2, 26 ':'.$column[3] => $column_3, 27 ':'.$column[4] => $column_4, 28 ':'.$column[5] => $column_5 29 ) 30 ); 31 $strlen_err = 0; 32 if(mb_strlen($column_1)>64 || mb_strlen($column_2)>99 || mb_strlen($column_4) > 64){ 33 $strlen_err++; 34 } 35 if(!empty($result) && $strlen_err == 0){ 36 echo 1; 37 }else{ 38 //$_SESSION["result"]["insert"] = $result; 39 echo 0; 40 } 41 } 42

PHP

1./youtubeAdmin/function.php 2 3$theme = "『GoogTube』管理ページ"; 4$td = array("視聴", "グループ", "タイトル", "チャンネル名", "公開"); 5 6$table = "youtube"; 7$column = array("id", "genre", "sight", "url", "channel", "public_flg"); 8 9function get_statement($query){ 10 include('../db.php'); 11 $statement = $connection->query($query); 12 return $statement; 13} 14 15function get_total_all_records($target){ 16 include('../db.php'); 17 $countQuery = "SELECT COUNT(id) FROM ".$target." "; 18 $countStatement = $connection->prepare($countQuery); 19 $countStatement->execute(); 20 $countResult = $countStatement->fetch(); 21 return $countResult[0]; 22}

insert.phpでは、新規登録に成功していた時と同様に、各カラムに対応する入力値には変数$column1~6を使用しております。
最後に画面内での新規登録が成功した事を確認した時から、insert.phpの記述は編集していない筈です。

やってきたこと

$_SESIONを使って、insert.phpでの登録時の情報をindex.phpに引き継いで確認してみました。
(両ファイルでコメントアウトしている$_SESSIONとvar_dumpの記述がその名残)
その結果、セッション内の、新規登録処理の情報は「false」になっているのが確認されたのですが、何故このような結果になってしまったのかが掴めない状態が続いてしまっています。

思い当たること

一度、さくらレンタルサーバーのDBで、このyoutubeテーブルのTRUNCATE処理を行って、すべてのレコード消去後、消去前にテーブルに表示されていたレコードのうち必要なものを、SQLのクエリ入力欄で直接記述しました。
この事が原因で当問題が発生しているのかは、それともコード記述はじめ他に原因があるのか、早急な特定と修正を必要としています。

皆様お忙しいところ恐縮ですが、ご回答ご教示の程、よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

自己解決

./youtubeAdmin/insert.phpの、

PHP

1 INSERT INTO ".$table." (" 2 .$column[1].", ".$column[2].", ".$column[3].", " 3 .$column[4].", ".$column[5].") VALUES (:" 4 .$column[1].", :".$column[2].", :".$column[3].", :" 5 .$column[4].", ".$column[5].")");

の箇所で、".$column[5]."の前に「:」を付けていなかった事が原因でした。

「:」を付けた上で再度更新し改めて登録処理を走らせてみたところ、今度は問題なく登録されてくれました。
お騒がせ致しました。申し訳ございません・・・

投稿2021/12/30 17:30

Nishin

総合スコア30

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

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

m.ts10806

2021/12/31 08:29 編集

そもそも ・DBに入れるデータにHTMLエスケープしている ・入力値をそのままDBに突っ込んでいる ・エラーハンドリングしていない かなり危ない実装です。
Nishin

2021/12/31 12:52

杜撰かつ危険なコードを記述してしまい、お目汚し失礼しました。 しかし、ご指摘ありがとうございます。もし今後、外部にも提供するウェブサービスをPHPで自力で制作する場合の参考とさせて頂きます。 まずはCRUD処理を滞りなく行える事に重きを置いて各ファイルを作成してきたのですが、以後のフェーズではセキュリティ対策の見直しに入ります。 ご指摘の事項では、3番目から1番目に順番に盛り込んでいこうと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問