7
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【PHPでECサイト①】CRUD機能

Last updated at Posted at 2020-08-06

はじめに

今回は、PHPとMySQLを使ってMVCモデルでCRUD機能を実装していきます。

CRUD機能とは?

ほぼ全てのソフトウェアが有する4つの永続的な基本機能の頭文字をそれぞれ並べた用語のこと。
その4つの機能とは、Create(生成)、Read(読み取り)、Update(更新)、Delete(削除)。

バージョン

PHP:7.4.5
phpMyAdmin:5.0.2
MySQL:5.7.30

今回作成するファイル

conf / html / model / view の4つのディレクトリを作って進めます。

conf(繰り返し使用するものを定義)

  • const.php

html(controller)

  • admin.php
  • admin_insert.php
  • admin_update_stock.php
  • admin_delete.php

model

  • db.php
  • functions.php
  • items.php

view

  • admin_view.php

テーブルの作成

items.sql
CREATE TABLE `sample_items` (
    `item_id` int(11) NOT NULL,
    `name` varchar(100) NOT NULL,
    `price` int(11) NOT NULL,
    `stock` int(11) NOT NULL,
    `created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `updated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)

ALTER TABLE `sample_items`
  MODIFY `item_id` int(11) NOT NULL AUTO_INCREMENT,
  ADD PRIMARY KEY (`item_id`);

定義

const.php
<?php
// ディレクトリパス
define('MODEL_PATH', $_SERVER['DOCUMENT_ROOT'] . '/../model/');
define('VIEW_PATH', $_SERVER['DOCUMENT_ROOT'] . '/../view/');

// MySQL接続用
define('DB_HOST', 'ホスト名');
define('DB_NAME', 'データベース名');
define('DB_USER', 'ユーザ名');
define('DB_PASS', 'パスワード');
define('DB_CHARSET', 'utf8');

// URL
define('ADMIN_URL', '/admin.php');

Viewの作成

admin_view.php
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <title>商品管理</title>
  </head>

  <body>
    <h1>商品管理ページ</h1>

    <form method="post">
      <div>
        <label>名前</label>
        <input type="text" name="name">
      </div>
      <div>
        <label>価格</label>
        <input type="number" name="price">
      </div>
      <div>
        <label>在庫</label>
        <input type="number" name="stock">
      </div>
      <input type="submit" value="送信">
    </form>

    <!-- 表示 -->
    <table>
      <thead>
        <tr>
          <th>名前</th>
          <th>価格</th>
          <th>在庫</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td></td>
          <td></td>
          <td></td>
          <td></td>
        </tr>
      </tbody>
    </table>
  </body>
</html>

Create機能の実装

Modelの作成

db.phpを作成(データベース関係)

db.php
<?php

function get_db_connect(){
    // MySQL用のDSN文字列
    $dsn = 'mysql:dbname='. DB_NAME. ';host='. DB_HOST. ';charset='. DB_CHARSET;

    try{
      // DB接続
      $dbh = new PDO($dsn, DB_USER, DB_PASS, array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4'));
      $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
      $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
      $dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
    }catch(PDOException $e){
        exit('接続できませんでした。理由:'.$e->getMessage());
    }
    return $dbh;
}

function execute_query($db, $sql, $params = array()){
  try{
    $statement = $db->prepare($sql);
    return $statement->execute($params);
  }catch(PDOException $e){
    set_error('更新に失敗しました。');  
  }
  return false;
}

functions.phpを作成(その他機能)

functions.php
<?php

function redirect_to($url){
  header('Location:'. $url);
  exit;
}

function get_post($name){
  if(isset($_POST[$name]) === true){
    return $_POST[$name];
  };
  return '';
}  

// セッション
function get_session($name){
  if(isset($_SESSION[$name]) === true){
      return $_SESSION[$name];
  };
  return '';
}

function set_session($name, $value){
  $_SESSION[$name] = $value;
}

// エラーメッセージ
function set_error($error){
  $_SESSION['__errors'][] = $error;
}

function get_errors(){
  $errors = get_session('__errors');
  if($errors === ''){
      return array();
  }
  set_session('__errors', array());
  return $errors;
}

// メッセージ
function set_message($message){
  $_SESSION['__message'][] = $message;
}

function get_messages(){
  $messages = get_session('__message');
  if($messages === ''){
      return array();
  }
  set_session('__message', array());
  return $messages;
}

items.phpを作成(商品関係)

items.php
<?php
require_once MODEL_PATH. 'functions.php';
require_once MODEL_PATH. 'db.php';

// Create
function regist_item($db, $name, $price, $stock){
  $sql = "
    INSERT INTO
      sample_items(
        name,
        price,
        stock
      )
    VALUES(?,?,?)
  ";
  return execute_query($db, $sql, array($name, $price, $stock));
}

Viewの作成

admin_view.phpにCreate処理へ遷移するよう追記

  • 処理結果を表示できるよう追記
  • formタグにactionを追記
admin_view.php
<!-- 処理結果のメッセージ -->
<?php foreach(get_errors() as $error){ ?>
    <p><?php print $error; ?></p>
<?php } ?>
<?php foreach(get_messages() as $messages){ ?>
    <p><?php print $messages; ?></p>
<?php } ?>

<!-- 投稿フォーム -->
 <form method="post" action="admin_insert.php">
   <div>
     <label>名前</label>
     <input type="text" name="name">
   </div>
   <div>
     <label>価格</label>
     <input type="number" name="price">
   </div>
   <div>
     <label>在庫</label>
     <input type="number" name="stock">
   </div>
   <input type="submit" value="送信">
 </form>

Controllerの作成

admin.phpを作成(admin_view.php表示用)

admin.php
<?php
require_once '../conf/const.php';
require_once MODEL_PATH. 'items.php';

session_start();

include_once VIEW_PATH. 'admin_view.php';

admin_insert.phpを作成(Insert処理用)

bbs_insert.php
<?php
require_once '../conf/const.php';
require_once MODEL_PATH. 'functions.php';
require_once MODEL_PATH. 'bbs.php';

session_start();

// データベース接続
$db = get_db_connect();

// Postされたものを定義
$name = get_post('name');
$price = get_post('price');
$stock = get_post('stock');

// Insert
if(regist_item($db, $name, $price, $stock)){
    set_message('商品を登録しました。');
}else{
    set_error('商品の登録に失敗しました。');
}

redirect_to(ADMIN_URL);

Read機能の実装

Createで挿入されたデータを表示されるようにしていきます。

Modelの作成

db.phpにRead機能を追記

db.php
function fetch_all_query($db, $sql, $params = array()){
  try{
    $statement = $db->prepare($sql);
    $statement->execute($params);
    return $statement->fetchAll();
  }catch(PDOException $e){
    set_error('データ取得に失敗しました。');
  }
  return false;
}

items.phpに追記

items.php
// Read
function get_items($db){
  $sql = "
    SELECT
      item_id,
      name,
      price,
      stock
    FROM
      sample_items
  ";
  return fetch_all_query($db, $sql);
}

Viewの作成

admin_view.phpに追記

  • tableタグ内のtbodyタグに追記
admin_view.php
<tbody>
  <?php foreach($items as $item){ ?>
  <tr>
    <td><?php print($item['name']); ?></td>
    <td><?php print($item['price']); ?></td>
    <td><?php print($item['stock']); ?></td>
    <td></td>
  </tr>
  <?php } ?>
</tbody>

Controllerの作成

admin.php
<?php
require_once '../conf/const.php';
require_once MODEL_PATH. 'items.php';

session_start();

// SELECT文で選択したデータを表示させる為に追記
$db = get_db_connect();
$items = get_items($db);

include_once VIEW_PATH. 'admin_view.php';

Update機能の実装

Createで生成されたデータを変更できるようにしていきます。

Modelの作成

items.phpにUpdate機能を追記

items.php
// Update
function update_stock($db, $item_id, $stock){
  $sql = "
    UPDATE
      sample_items
    SET
      stock = ?
    WHERE
      item_id = ?
  ";
  return execute_query($db, $sql, array($stock, $item_id));
}

Viewの作成

admin_view.phpにUpdate処理へ遷移するよう追記

  • tableタグ内のtbodyに追記
bbs.php
<tbody>
  <?php foreach($items as $item){ ?>
  <tr>
    <td><?php print($item['name']); ?></td>
    <td><?php print($item['price']); ?></td>
    <td>
      <form method="post" action="admin_update_stock.php">
        <input type="number" name="stock" value="<?php print($item['stock']); ?>">
        <input type="submit" value="変更">
        <input type="hidden" name="item_id" value="<?php print($item['item_id']); ?>">
      </form>    
    </td>
    <td></td>
  </tr>
  <?php } ?>
</tbody>

Controllerの作成

admin_update_stock.phpを作成(Update処理用)

admin_update_stock.php
<?php
require_once '../conf/const.php';
require_once MODEL_PATH. 'functions.php';
require_once MODEL_PATH. 'items.php';

session_start();

// データベース接続
$db = get_db_connect();

// Postされたものを定義
$item_id = get_post('item_id');
$stock = get_post('stock');

// Update
if(update_stock($db, $item_id, $stock)){
    set_message('在庫を更新しました。');
  } else {
    set_error('在庫の更新に失敗しました。');
  }
  
redirect_to(ADMIN_URL);

Delete機能の実装

Createで生成されたデータを削除できるようにしていきます。

Modelの作成

items.phpにDelete機能を追記

items.php
// Delete
function delete_item($db, $item_id){
  $sql = "
    DELETE FROM
      sample_items
    WHERE
      item_id = ?
  ";
  return execute_query($db, $sql, array($item_id));
}

Viewの作成

admin_view.phpにDelete処理へ遷移するよう追記

  • tableタグ内のtbodyに追記
admin_view.php
<tbody>
  <?php foreach($items as $item){ ?>
  <tr>
    <td><?php print($item['name']); ?></td>
    <td><?php print($item['price']); ?></td>
    <td>
      <form method="post" action="admin_update_stock.php">
        <input type="number" name="stock" value="<?php print($item['stock']); ?>">
        <input type="submit" value="変更">
        <input type="hidden" name="item_id" value="<?php print($item['item_id']); ?>">
      </form>    
    </td>
    <td>
      <form method="post" action="admin_delete.php">
        <input type="submit" value="削除">
        <input type="hidden" name="item_id" value="<?php print($item['item_id']); ?>">
      </form>
    </td>
  </tr>
  <?php } ?>
</tbody>

Controllerの作成

admin_delete.phpを作成(Delete処理用)

bbs.php
<?php
require_once '../conf/const.php';
require_once MODEL_PATH. 'functions.php';
require_once MODEL_PATH. 'items.php';

session_start();

// データベース接続
$db = get_db_connect();

// Postされたものを定義
$item_id = get_post('item_id');

// Delete
if(delete_item($db, $item_id)){
    set_message('商品を削除しました。');
  } else {
    set_error('商品の削除に失敗しました。');
  }
  
redirect_to(ADMIN_URL);

参考

CRUD機能と7つのアクションの関係性
MVCモデルについて

7
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?