オンラインクイズシステムを開発しています。
管理パネルには、「質問を追加」というラベルの付いたボタンがあります。ボタンをクリックするとモーダルダイアログが開き、問題文(3)、問題画像(4)、追加する問題のある試験(1)、難易度(1~5)(2)を含むクイズフォームが開きます、5 つの回答オプション (5)、および有効または無効にする 2 つのラジオ ボタン (6)。
ここではすべて問題ありません。
これは質問モーダルコンテンツの追加です
<?php
include_once '../config.php'; //includes class ExamConfig
$cfg = new ExamConfig();
$examsQuery = $cfg->db->query('SELECT id, exam FROM examinations');
$rowExams = $examsQuery->fetchAll(PDO::FETCH_ASSOC);
$diffQuery = $cfg->db->query('SELECT id, difficulty FROM DifficultyLevels');
$rowDiff = $diffQuery->fetchAll(PDO::FETCH_ASSOC);
?>
<form action="" method="post" class="form-signin" enctype="multipart/form-data" id="frm_addQuestion">
<p> This question belongs to:
<select name = "exam" id = "exam" class = "form-control">
<?php
foreach ($rowExams as $re)
{
echo '<option value="' . $re['id'] . '">' . $re['exam'] . '</option>';
}
?>
</select>
</p>
<p> Question Difficulty Level:
<select name = "difficulty" id = "difficulty" class = "form-control">
<?php
foreach ($rowDiff as $rd)
{
echo '<option value="' . $rd['id'] . '">' . $rd['difficulty'] . '</option>';
}
?>
</select>
</p>
<p> Question Text:
<input class = "form-control" type = "text" name = "question" id = "question" /> </p>
<p> Question Picture:
<input type = "file" name = "qPicture" id = "qPicture" /> </p>
<p> <strong> Option 1 (Correct Answer): </strong>
<input class = "form-control success" type = "text" name = "opt1" id = "opt1" /> </p>
<p> Option 2:
<input type = "text" class = "form-control" name = "opt2" id = "opt2" /> </p>
<p> Option 3:
<input type = "text" class = "form-control" name = "opt3" id = "opt3" /> </p>
<p> Option 4:
<input type = "text" class = "form-control" name = "opt4" id = "opt4" /> </p>
<p> Option 5:
<input type = "text" class = "form-control" name = "opt5" id = "opt5" /> </p>
<p> <input type = "radio" name = "enabled" id = "enabled" value = "1" /> Enabled </p>
<p> <input type = "radio" name = "enabled" id = "enabled" value = "0" /> Disabled </p>
<p> <a class = "btn btn-primary btn-block" type = "button" name = "btn_question_save" id = "btn_question_save" onclick="SaveQuestion();"> Save Question</a></p>
</form>
そして、これはSaveQuestion()関数を含む JS ファイルです:
function SaveQuestion() {
var request;
// abort any pending request
if (request) {
request.abort();
}
// setup some local variables
var $form = $('#frm_AddQuestion');
// let's select and cache all the fields
var $inputs = $form.find("input, select, button");
// serialize the data in the form
var serializedData = $form.serialize();
// let's disable the inputs for the duration of the ajax request
$inputs.prop("disabled", true);
// fire off the request to /QuestionSave.php
request = $.ajax({
url: "QuestionSave.php",
type: "post",
data: serializedData,
success: function(result)
{
response = result;
}
});
// callback handler that will be called on success
request.done(function(response, textStatus, jqXHR) {
if (response === "0")
{
alert('Hey!'); //record inserted
}
else if( response === "900")
{
alert('Oh noooo!'); //record not inserted
}
});
// callback handler that will be called on failure
request.fail(function(jqXHR, textStatus, errorThrown) {
// log the error to the console
console.error(
"Oops: " +
textStatus, errorThrown
);
});
// callback handler that will be called regardless
// if the request failed or succeeded
request.always(function() {
// reenable the inputs
$inputs.prop("disabled", false);
});
}
最後にこれがQuestionSave.phpのコードです
<?php
if ( !isset( $_SESSION ) )
{
session_start();
}
include_once '../config.php';
$cfg = new ExamConfig();
if ( isset( $_POST ) )
{
$imgData = fopen( $_FILES[ 'qPicture' ][ 'tmp_name' ], 'rb' );
$questionSaveQuery= $cfg->db->prepare( 'INSERT INTO questions (question, user_id, examid, difficultyid, picture, enabled) VALUES( :question, :user_id, :examid, :difficultyid, :picture, :enabled)' );
$questionSaveQuery->bindValue( ':question', $_POST[ 'question' ], PDO::PARAM_STR );
$questionSaveQuery->bindValue( ':user_id', $_SESSION[ 'user_id' ], PDO::PARAM_INT );
$questionSaveQuery->bindValue( ':examid', $_POST[ 'exam' ], PDO::PARAM_INT );
$questionSaveQuery->bindValue( ':difficultyid', $_POST[ 'difficulty' ], PDO::PARAM_INT );
$questionSaveQuery->bindValue( ':picture', $imgData, PDO::PARAM_LOB );
$questionSaveQuery->bindValue( ':enabled', $_POST[ 'enabled' ], PDO::PARAM_INT );
if ( $questionSaveQuery->execute() )
{
$lid = $cfg->db->lastInsertId();
$optionSaveQuery= $cfg->db->prepare( 'INSERT INTO options
(questionid, answer, correct) VALUES
(:qid1, :opt1, 1),
(:qid2, :opt2, 0),
(:qid3, :opt3, 0),
(:qid4, :opt4, 0),
(:qid5, :opt5, 0)' );
$optionSaveQuery->bindValue( ':qid1', $lid, PDO::PARAM_INT );
$optionSaveQuery->bindValue( ':opt1', $_POST[ 'opt1' ], PDO::PARAM_INT );
$optionSaveQuery->bindValue( ':qid2', $lid, PDO::PARAM_INT );
$optionSaveQuery->bindValue( ':opt2', $_POST[ 'opt2' ], PDO::PARAM_INT );
$optionSaveQuery->bindValue( ':qid3', $lid, PDO::PARAM_INT );
$optionSaveQuery->bindValue( ':opt3', $_POST[ 'opt3' ], PDO::PARAM_INT );
$optionSaveQuery->bindValue( ':qid4', $lid, PDO::PARAM_INT );
$optionSaveQuery->bindValue( ':opt4', $_POST[ 'opt4' ], PDO::PARAM_INT );
$optionSaveQuery->bindValue( ':qid5', $lid, PDO::PARAM_INT );
$optionSaveQuery->bindValue( ':opt5', $_POST[ 'opt5' ], PDO::PARAM_INT );
if ( $optionSaveQuery->execute() )
echo '0';
else
{
echo '901';
$DeleteLastQuestion = $cfg->db->prepare( 'DELETE FROM questions WHERE id = :id' );
$DeleteLastQuestion->bindValue( ':id', $lid, PDO::PARAM_INT );
$DeleteLastQuestion->execute();
}
}
else
echo '900';
}
?>
AJAXリクエストをバイパスしてフォームを直接送信するQuestionSave.php
と、問題なく質問が挿入されます。しかし、Ajax の方法を使用すると、次のようなエラーが発生します。
PHP 致命的なエラー: メッセージ 'SQLSTATE[23000]: 整合性制約違反: 1048 列 'picture' を null にすることはできません...
つまり、画像は転送されずQuestionSave.php
に$_FILES[ 'qPicture' ][ 'tmp_name' ]
返されますnull
。そのため、操作が中断されます。この問題を解決する方法を教えてくれる人はいますか?