daicat05
@daicat05

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

掲示板に画像を投稿したい。

プログラミング初心者です。

【PHP初級】画像アップロード(全5回)【PHP入門】2ちゃんねる風掲示板を作りながら学ぶPHP入門講座のコードを組み合わせて、画像が投稿できる掲示板サイトを作成しています。
ですが、画像を投稿する機能でエラーが発生しました。

エラーの意味を調べたところ、47行目の変数に値がないのと、SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'username' cannot be nullbool(false)と表示されています。
解決方法を教えてください。

実際のデータは以下の通りになります。
スクリーンショット 2024-08-25 20.24.03.png

MAMPでPHPとMySQLをやっており、PHPのバージョンは8.3.9、phpMyAdminのバージョンは5.2.1です。

発生している問題・エラー

Warning: Undefined variable $username in /Applications/MAMP/htdocs/jissen/file_upload.php on line 47
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'username' cannot be nullbool(false) データベースへの保存が失敗しました!

該当するソースコード

file_upload.php

<?php
require_once "./dbc.php";

// ファイル関連の取得
$file = $_FILES['img'];
$filename = basename($file['name']);
$tmp_path = $file['tmp_name'];
$file_err = $file['error'];
$filesize = $file['size'];
$upload_dir = 'images/';
$save_filename = date('YmdHis') . $filename;
$err_msgs = array();
$save_path = $upload_dir. $save_filename;

// コメントを取得
$comment = filter_input(INPUT_POST, 'comment', FILTER_SANITIZE_SPECIAL_CHARS);

// コメントのバリデーション
// 未入力
if (empty($comment)) {
    array_push($err_msgs, 'コメントを入力してください。');
}

// ファイルのバリデーション
// ファイルサイズが1MB未満か
if ($filesize > 1048576 || $file_err == 2) {
    array_push($err_msgs, 'ファイルサイズは1MB未満にしてください。');
}

// 拡張は画像形式か
$allow_ext = array('jpg', 'jpeg', 'png');
$file_ext = pathinfo($filename, PATHINFO_EXTENSION);

if (!in_array(strtolower($file_ext), $allow_ext)) {
    array_push($err_msgs, '画像ファイルを添付してください。');
}

if (count($err_msgs) === 0) {

//     // ファイルはあるかどうか?
    if (is_uploaded_file($tmp_path)) {
        if (move_uploaded_file($tmp_path, $save_path)) {
            echo $filename . 'を' . $upload_dir . 'アップしました。';
            // DBに保存(ユーザ名、ファイル名、ファイルパス、コメント)
            $result = fileSave($username, $filename, $save_path, $comment);
            var_dump($result);

            if ($result) {
                echo 'データベースに保存しました!';
            } else {
                echo 'データベースへの保存が失敗しました!';
            }
        } else {
            echo 'ファイルが保存できませんでした。';
        }
    } else {
        echo 'ファイルが選択されていません。';
        echo '<br>';
    }
} else {
    foreach ($err_msgs as $msg) {
        echo $msg;
        echo '<br>';
    }
}

?>

<a href="./futaba_bbs.php">戻る</a>

dbc.php

<?php

function dbc()
{
    $host = "localhost";
    $dbname = "futaba_bbs";
    $user = "root";
    $pass = "root";

    $dns = "mysql:host=$host; dbname=$dbname; charset=utf8";

    try {
        $pdo = new PDO($dns, $user, $pass,
            [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
            ]);
        return $pdo;
    } catch (PDOException $e) {
        exit($e->getMessage());
    }
}
/**
 * ファイルデータを保存
 * @param string $username ユーザー名
 * @param string $filename ファイル名
 * @param string $file_path 保存先のパス
 * @param string $comment 投稿の説明
 * @param string $postdate 日付
 * @return bool $result
 */
function fileSave($username, $filename, $save_path, $comment)
{
    $result = False;

    $sql = "INSERT INTO futaba_table (username, file_name, file_path, 
    comment) VALUE (?, ?, ?, ?)";

    try {
        $stmt = dbc()->prepare($sql);
        $stmt->bindValue(1, $username);
        // $stmt->bindValue(2, $filename);
        // $stmt->bindValue(3, $save_path);
        // $stmt->bindValue(4, $comment);
        // $stmt->bindValue(5, $postdate);
        $stmt->bindValue(2, $filename);
        $stmt->bindValue(3, $save_path);
        $stmt->bindValue(4, $comment);
        $result = $stmt->execute();
        return $result;
    } catch (\Exception $e) {
        echo $e->getMessage();
        return $result;
    }
}

/**
 * ファイルデータを取得
 * @return array $fileData
 */
function getAllFile()
{
    $sql = "SELECT * FROM futaba_table";

    $fileData = dbc()->query($sql);

    return $fileData;
}

function h($s)
{
    return htmlspecialchars($s, ENT_QUOTES, "UTF-8");
}

futaba_bbs.php

<?php
require_once "./dbc.php";
$files = getAllFile();


date_default_timezone_set("Asia/Tokyo");

$comment_array = array();
$pdo = null;
$stmt = null;
$error_message = array();

// DB接続
try {
    $pdo = new PDO('mysql:host=localhost;dbname=futaba_bbs', "root", "root");
} catch (PDOException $e) {
    echo $e->getMessage();
}

// フォームを打ち込んだとき
if (!empty($_POST["submitButton"])) {

    // 名前のチェック
    if (empty($_POST["username"])) {
        echo "名前を入力してください";
        $error_message["username"] = "名前を入力してください";
    }
    // コメントのチェック
    if (empty($_POST["comment"])) {
        echo "コメントを入力してください";
        $error_message["comment"] = "コメントを入力してください";
    }



    if (empty($error_message)) {
        $post_date = date("Y-m-d H:i:s");

        try {
            $stmt = $pdo->prepare("INSERT INTO `futaba_table` (`username`, `comment`, `post_date`) VALUES (:username, :comment, :current_date);");
            $stmt->bindParam(':username', $_POST['username'], PDO::PARAM_STR);
            $stmt->bindParam(':comment', $_POST['comment'], PDO::PARAM_STR);
            $stmt->bindParam(':current_date', $post_date, PDO::PARAM_STR);

            $stmt->execute();
        } catch (PDOException $e) {
            echo $e->getMessage();
        }
    }
}


// DBからコメントデータを取得する
$sql = "SELECT `id`, `username`, `comment`, `post_date` FROM `futaba_table`;";
$comment_array = $pdo->query($sql);


// DBの接続を閉じる
$pdo = null;
?>

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ふたば掲示板</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <h1 class="title">ふたば掲示板</h1>
    <hr>
    <div class="boardWrapper">
        <section>
            <?php foreach ($comment_array as $comment) : ?>
                <article>
                    <div class="Wrapper">
                        <div class="nameArea">
                            <span>名前:</span>
                            <p class="username"><?php echo $comment["username"]; ?></p>
                            <time>
                                <p class="post_date"><?php echo $comment["post_date"]; ?>
                            </time>
                        </div>
                        <p class="comment">
                        <p class="comment"><?php echo $comment["comment"]; ?></p>
                    </div>
                </article>
            <?php endforeach; ?>
        </section>
        <form enctype="multipart/form-data" action="./file_upload.php" class="formWrapper" method="POST">
            <div>
                <input type="submit" value="送信" name="submitButton">
                <label for="">名前</label>
                <input type="text" name="username">
            </div>
            <div>
                <textarea class="commentTextArea" name="comment" id="comment"></textarea>
            </div>
            <div class="file-up">
                <input type="hidden" name="MAX_FILE_SIZE" value="1048576" />
                <input name="img" type="file" accept="image/*" />
            </div>
        </form>
    </div>
        <?php foreach($files as $file): ?>
            <img src="<?php echo "{$file['file_path']}"; ?>" alt="">
        <?php endforeach; ?>
</body>

</html>
0

1Answer

エラーメッセージについてですが、

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'username' cannot be null

ここまでがfileSave()の中のecho $e->getMessage();で出力されたエラーであり、

bool(false)

この部分はvar_dump($result);の出力と思われます。

さてエラーメッセージが示す状況ですが、テーブルのNULL列を見るとusernameは「いいえ」となっているので、値のないデータを追加することはできません。SQLSTATE[23000]: ~のエラーはそれを示しています。
直接的な原因としては変数$usernameに値がない(未定義)なのことでしょう。file_upload.phpを検索すると、事前に値が代入されていないことがわかります。
よって、まずは変数$usernameに必要な値を入れることが解決策になります。

2Like

Your answer might help someone💌