kamehameha
@kamehameha (ペンギン)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

PHPフォームCRUD処理実装

解決したいこと

PHPの問い合わせフォームとDB接続の勉強をしています。
①問い合わせに一覧を表示。削除・編集用のリンク作成。
②編集ページはフォームに既存の入力値を最初から表示し、バリデーション行う。
③削除時はJavaScriptによる確認のポップアップ表示
④問い合わせを送信したら、内容をDBに新規登録するようにする
⑤SQLインジェクション・トランザクション実装
を行う勉強をしています。
[contact.php]が作成した問い合わせフォームです。
[contacts.php,db.php,update_form.php,contacts_update.php]
がDB関連です。

編集ページを作成しているのですがこのようなエラーが出ました。調べてアロー演算子などを試したのですができませんでした。

おかしい所などもありましたら、
詳しい方教えていただけると幸いです。
よろしくお願いします。

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

出ているエラーメッセージを入力
```Fatal error: Uncaught Error: Cannot use object of type Contacts as array in /Applications/MAMP/htdocs/2022年度_4_サーバサイド基礎1(PHP)_20220423/4-4_info_forms/FormSamples/contacts.php:61 Stack trace: #0 /Applications/MAMP/htdocs/2022年度_4_サーバサイド基礎1(PHP)_20220423/4-4_info_forms/FormSamples/contacts_update.php(7): Contacts->contactsValidate(Object(Contacts)) #1 {main} thrown in /Applications/MAMP/htdocs/2022年度_4_サーバサイド基礎1(PHP)_20220423/4-4_info_forms/FormSamples/contacts.php on line 61

Fatal error: Uncaught Error: Cannot use object of type Contacts as array in /Applications/MAMP/htdocs/2022年度_4_サーバサイド基礎1(PHP)_20220423/4-4_info_forms/FormSamples/contacts.php:42 Stack trace: #0 /Applications/MAMP/htdocs/2022年度_4_サーバサイド基礎1(PHP)_20220423/4-4_info_forms/FormSamples/contacts_update.php(8): Contacts->contactsUpdate(Object(Contacts)) #1 {main} thrown in /Applications/MAMP/htdocs/2022年度_4_サーバサイド基礎1(PHP)_20220423/4-4_info_forms/FormSamples/contacts.php on line 42

例)

NameError (uninitialized constant World)


または、問題・エラーが起きている画像をここにドラッグアンドドロップ

### 該当するソースコード
```言語名
ソースコードを入力
```[db.php]
<?php

Class Db
{
  protected $table_name;


  //1.データベース接続
  protected function dbConnect() {
    $dsn = 'mysql:host=localhost;dbname=resort;charset=utf8';
    $user = 'root';
    $pass = 'root';

    try {
      $dbh = new PDO($dsn,$user,$pass,[
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
      ]);
    }catch(PDOException $e) {
      echo '接続失敗'. $e->getMessage();
      exit();
    };
    
    return $dbh;
  
  }
  //2.データを取得する
  public function getAll() {
    $dbh = $this->dbConnect();
    //1.SQLの準備
    $sql = 'SELECT * FROM contacts';
    //2.SQLの実行
    $stmt = $dbh->query($sql);
    //3.SQLの結果を受け取る
    $result = $stmt->fetchAll(\PDO::FETCH_ASSOC);
    return $result;
    $dbh = null;
  }
  // //取得したデータを表示
  // $contactsDate = getAllContacts();


  public function getById($id) {
    if(empty($id)) {
      exit('IDが不正です。');
    }
      
    $dbh = $this->dbConnect();
    //SQL準備
    $stmt = $dbh->prepare('SELECT * FROM contacts Where id = :id');
    $stmt->bindValue(':id',(int)$id,PDO::PARAM_INT);

    //SQL実行
    $stmt->execute();

    //結果を取得
    $result = $stmt->fetch(PDO::FETCH_ASSOC);

    if(!$result) {
      exit('ありません。');
    }
    return $result;
  }


}
?>

[contacts.php]
<?php
require_once('db.php');

Class Contacts extends Db
{

    protected $table_name = 'contacts';
    public function contactsCreate($contacts) {
        $sql = "INSERT INTO
                $this->table_name(name, kana, tel, email, body)
            VALUES
                (:name, :kana, :tel, :email, :body)";
                
            $dbh = $this->dbConnect();
            $dbh->beginTransaction();
        try {
            $stmt = $dbh->prepare($sql);
            $stmt->bindValue(':name',$contacts['name'], PDO::PARAM_STR);
            $stmt->bindValue(':kana',$contacts['kana'], PDO::PARAM_STR);
            $stmt->bindValue(':tel',$contacts['tel'], PDO::PARAM_STR);
            $stmt->bindValue(':email',$contacts['email'], PDO::PARAM_STR);
            $stmt->bindValue(':body',$contacts['body'], PDO::PARAM_STR);
            $stmt->execute();
            $dbh->commit();
            echo '登録完了';
        } catch(PDOException $e) {
            $dbh->rollBack();
            exit($e);
        }
    }
    
    public function contactsUpdate($contacts){
        $sql = "UPDATE $this->table_name SET
            name = :name, kana = :kana, tel = :tel, email = :email, body = :body, created_at = :created_at
        WHERE
            id = :id";

        $dbh = $this->dbConnect();
        $dbh->beginTransaction();
        try {
            $stmt = $dbh->prepare($sql);
            $stmt->bindValue(':name',$contacts['name'], PDO::PARAM_STR);
            $stmt->bindValue(':kana',$contacts['kana'], PDO::PARAM_STR);
            $stmt->bindValue(':tel',$contacts['tel'], PDO::PARAM_STR);
            $stmt->bindValue(':email',$contacts['email'], PDO::PARAM_STR);
            $stmt->bindValue(':body',$contacts['body'], PDO::PARAM_STR);
            $stmt->bindValue(':id',$contacts['id'], PDO::PARAM_INT);
            $stmt->execute();
            $dbh->commit();
            echo '編集完了';
        } catch(PDOException $e) {
            $dbh->rollBack();
            exit($e);
        }
    }


    
    //バリデーション
    public function contactsValidate($contacts) {
        if (empty($contacts['name'])) {
            exit('氏名は必須入力です。');
        }
        if (empty($contacts['kana'])) {
            exit('フリガナは必須入力です。');
        }
        if (empty($contacts['tel'])) {
        
        }else if(!preg_match('/^[0-9]+$/',$contacts['tel'])) {
            exit('電話番号は0から9の数字のみでご入力ください。');
            }
        if (empty($contacts['email'])) {
            exit('メールアドレスは正しくご入力ください。');
        }
        if (empty($contacts['body'])) {
            exit('お問い合わせ内容は必須入力です。');
        }
    }
    
}


?>

[update_form.php]
<?php 
require_once('contacts.php');

$contacts = new Contacts();
$result = $contacts->getById($_GET['id']);


$id = $result['id'];
$name = $result['name'];
$kana = $result['kana'];
$tel = $result['tel'];
$email = $result['email'];
$body = $result['body'];
$created_at = $result['created_at'];

?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>BlogForm</title>
</head>
<body>
    <h2>編集フォーム</h2>
    <form action="contacts_update.php" method="POST">
        <input type="hidden" name="id" value="<?php echo $id ?>">
        <p>id:</p>
        <input type="text" name="id" value="<?php echo $id ?>">
        <p>名前:</p>
        <input type="text" name="name" value="<?php echo $name ?>">
        <p>カナ:</p>
        <input type="text" name="kana" value="<?php echo $kana ?>">
        <p>電話番号:</p>
        <input type="text" name="tel" value="<?php echo $tel ?>">
        <p>メール:</p>
        <input type="text" name="email" value="<?php echo $email ?>">
        <p>送信日時:</p>
        <input type="text" name="created_at" value="<?php echo $created_at ?>">
        <p>問い合わせ:</p>
        <input type="text" name="body" value="<?php echo $body ?>">
        <br>
        <!-- <p>カテゴリ:</p>
        <select name="category">
            <option value="1">日常</option>
            <option value="2">プログラミング</option> -->
        <!-- </select> -->
        <!-- <br>
        <input type="radio" name="publish_status" value="1" checked>公開
        <input type="radio" name="publish_status" value="2">非公開 -->
        <br>
        <input type="submit" value="送信">
    </form>
    
</body>
</html>


「phpの問い合わせフォームです[contact.php]」
<?php
  session_start();
  //送信ボタン押したら確認画面へ

  //各項目必須・文字数チェック
  $error = '';
  if(isset($_POST['submit'])){
    $_SESSION['name'] = $_POST['name'];
    $_SESSION['kana'] = $_POST['kana'];
    $_SESSION['email'] = $_POST['email'];
    $_SESSION['tel'] = $_POST['tel'];
    $_SESSION['body'] = $_POST['body'];
    //氏名
    if(empty($_POST['name'])){
      $error .= "氏名は必須入力です。\\n";
    }else if(mb_strlen($_POST['name']) > 10){
      $error .= "氏名は10文字以内でご入力ください。\\n";
    }
    //ふりがな
    if(empty($_POST['kana'])) {
      $error .= "フリガナは必須入力です。\\n";
    }else if(mb_strlen($_POST['kana']) > 10){
      $error .= "フリガナは10文字以内でご入力ください。\\n";
    }
    //電話番号
    $tel = $_POST['tel'];
    if(empty($_POST['tel'])) {

    }else if(!preg_match('/^[0-9]+$/',$tel)) {
      $error .= "電話番号は0から9の数字のみでご入力ください。\\n";
    }
    //メールアドレス
    if(empty($_POST['email'])) {
      $error .= "メールアドレスは正しくご入力ください。\\n";
    }else if( !filter_var($_POST['email'],FILTER_VALIDATE_EMAIL)) {
      $error .= "メールアドレスは正しくご入力ください。\\n";
    }
    //お問い合わせ内容
    if(empty($_POST['body'])) {
      $error .= "お問い合わせ内容は必須入力です。";
    }

    if(isset($_POST['submit']) && $error !== '') {
      echo "<script>alert('$error');</script>";
    }else{
      header('location:confirm.php');
      exit();
    }
  }
  session_destroy(); //セッションを破棄するうやつ。
?>



 <?php include "header.php"?>

<section>
  <div id="contact_box">
    <h2><b>お問い合わせ</b></h2>
    <form action="contact.php" method="post" > 
      <h3>下記の項目をご記入の上送信ボタンを押してください</h3>
      <p>送信頂いた件につきましては、当社より折り返しご連絡を差し上げます。</p>
      <p>なお、ご連絡までに、お時間を頂く場合もございますので予めご了承ください。</p>
      <p><span class="required">*</span>は必須項目となります。</p>
      <dl>
        <dt><label for="name">氏名</label><span class="required">*</span></dt>
        <?php if(isset($_POST['submit'])) { if(empty($_POST['name']) || mb_strlen($_POST['name']) > 10) { echo '<span style="color:#FF0000;">氏名は必須入力です。10文字以内でご入力ください。</span>';}}?>

        <dd><input type="text" name="name" id="name" placeholder="山田太郎" ></dd>
        <dt><label for="kana">フリガナ</label><span class="required">*</span></dt>
        <?php if(isset($_POST['submit'])) { if(empty($_POST['kana']) || mb_strlen($_POST['kana']) > 10) { echo '<span style="color:#FF0000;">フリガナは必須入力です。10文字以内でご入力ください。</span>';}}?>
        
        <dd><input type="text" name="kana" id="kana" placeholder="ヤマダタロウ" ></dd>
        <dt><label for="tel">電話番号</label></dt>
       

        <dd><input type="text" name="tel" id="tel" placeholder="09012345678" ></dd>
        <dt><label for="email">メールアドレス</label><span class="required">*</span></dt>
        <?php if(isset($_POST['submit'])) { if(empty($_POST['email']) || !filter_var($_POST['email'],FILTER_VALIDATE_EMAIL)) { echo '<span style="color:#FF0000;">メールアドレスは正しくご入力ください。</span>';}}?>
        <dd><input type="text" name="email" id="email" placeholder="test@test.co.jp" ></dd>
      </dl>
      <h3><label for="body">お問い合わせ内容をご記入ください<span class="required">*</span></label></h3>
      <?php if(isset($_POST['submit'])) { if(empty($_POST['body'])) { echo '<span style="color:#FF0000;">お問い合わせは必須入力です。</span>'; }} ?>


      <dl>
        <dd><textarea name="body"></textarea></dd>
        <dd><button type="submit" class="send" name="submit">送 信</button></dd></dl>
    </form>
  </div>
</section>

<?php

require_once('contacts.php');

$contacts = new Contacts();
$contactsDate = $contacts->getAll();

$dsn = 'mysql:host=localhost;dbname=resort;charset=utf8';
$user = 'root';
$pass = 'root';
try {
  $dbh = new PDO($dsn,$user,$pass,[
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
  ]);

  //1.SQLの準備
  $sql = 'SELECT * FROM contacts';
  //2.SQLの実行
  $stmt = $dbh->query($sql);
  //3.SQLの結果を受け取る
  $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
  // var_dump($result);
  $dbh = null;
}catch(PDOException $e){
  echo '接続失敗'. $e->getMessage();
  exit();
}
?>

<!DOCTYPE html>
<html lang="en">
<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>
</head>
<body>
  <table>
    <tr>
      <th>ID</th>
      <th>名前</th>
      <th>カナ</th>
      <th>電話番号</th>
      <th>メール</th>
      <th>問い合わせ</th>
      <th>送信日時</th>
    </tr>
     <?php foreach($result as $column): ?> 
      <tr>
        <td><?php echo $column['id'] ?></td>
        <td><?php echo $column['name'] ?></td>
        <td><?php echo $column['kana'] ?></td>
        <td><?php echo $column['tel'] ?></td>
        <td><?php echo $column['email'] ?></td>
        <td><?php echo $column['body'] ?></td>
        <td><?php echo $column['created_at'] ?></td>
        <td><a href="/detail.php?id=<?php echo $column['id'] ?>">詳細</a></td>
        <td><a href="/update_form.php?id=<?php echo $column['id'] ?>">編集</a></td>
      </tr>
    <?php endforeach; ?>
  </table>
  
</body>
</html>

[contacts_update.php]
<?php
require_once('contacts.php');

$contacts = $_POST;

$contacts = new Contacts();
$contacts->contactsValidate($contacts);
$contacts->contactsUpdate($contacts);


?>


### 自分で試したこと
エラーコードコピーし調べた
アロー演算子を使ったりした。
0

1Answer

Cannot use object of type Contacts as array
Contacts 型のオブジェクトを配列として使用できない

まずエラーメッセージを翻訳するとこのとおりですね。
それをふまえたうえで、ここが問題での箇所です。

contacts_update.php
$contacts = $_POST; // ①
$contacts = new Contacts(); // ②
$contacts->contactsValidate($contacts); // ③
$contacts->contactsUpdate($contacts); // ③

①で変数$contactsに配列を入れていますが、②で上書きしてContactsクラスのオブジェクトになっています。
そのContactsクラスのオブジェクトを③でcontactsValidateメソッドやcontactsUpdateメソッドの引数として渡しており、それぞれのメソッドで$contacts['name']のように配列として扱っています。Contactsクラスは配列として扱えるようにはなっていないのでエラーになります。

変数名の重複を解消すれば先に進めると思いますよ。

0Like

Comments

  1. @kamehameha

    Questioner

    とても分かりやすくありがとうございます。
    しっかり謎が解けました。

  2. @kamehameha

    Questioner

    すみません、謎が解けたと思っていたのですが全然ダメでどのようにしたらよろしいのでしょうか?>_<
  3. 「全然ダメ」というのはどいう状況でしょうか?
    原因と解決方法は示したつもりなので、何に引っかかっているのか説明いただかなくては答えようがなく・・・
  4. @kamehameha

    Questioner

    すみません
    $contacts = $_POSTは変えずに➂などで使ってる$contactsを$contactなどに変更すればよろしいのでしょうか?
  5. 名称が重複していて上書きしているのが問題なので、変更するのはどちらでも構いません。

    プログラミングは変数の中身に何が入っているのか、それがどのように処理されるのかを把握していく必要があります。
    大事なのは実際にどうなっているのかを確認することです。
    var_dumpメソッドは変数の中身を確認するのに便利です。

    https://www.php.net/manual/ja/function.var-dump.php

Your answer might help someone💌