Create php MVC application. Upload CSV file

Home » Tutorials » PHP+MySQL » Create php MVC application. Upload CSV file
One of subscribers asked me to shoe CSV file uploading and handling it in our app. In this lesson we’ll upload CSV file, read data from it and record data from file to application database
While uploading any type of file to the server we must notice several key concepts:

  • You need attribute enctype with multipart/form-data value to html form
  • Input with type “file” mus be in html form. Other types are not prohibited
  • While sending file to the server you can access to it from super global array – $_FILES. But html form still must have method post attribute.
  • While uploading file you must notice your server settings – file must be large, php script needs time to upload and handle it. That’s why you should check max execution time setting. Moreover, file uploading operation can fail, if its size more than server settings. That’s why you should check upload_max_filesize and post_max_size settings.
  • File don’t upload to the desired folder at once. It uploads to the temporary directory. You must upload file from temporary directory to your server desired directory using move_uploaded_file function.

Code lesson (config.php)

<?php

/*Общие константы приложения*/

session_start();
define("ROOT", $_SERVER['DOCUMENT_ROOT']);
define("CONTROLLER_PATH", ROOT . "/controllers/");
define("MODEL_PATH", ROOT . "/models/");
define("VIEW_PATH", ROOT . "/views/");
define("UPLOAD_FOLDER", ROOT. "/uploads/");

require_once('db.php');
require_once('route.php');
require_once MODEL_PATH . 'Model.php';
require_once VIEW_PATH . 'View.php';
require_once CONTROLLER_PATH . 'Controller.php';

Routing::buildRoute();

Code lesson (ProductsController.php)

<?php

class ProductsController extends Controller {

    private $pageTpl = "/views/products.tpl.php";

    public function __construct() {
        $this->model = new ProductsModel();
        $this->view = new View();
    }

    public function index() {
        if(!$_SESSION['user']) {
            header("Location: /");
        }
        $this->pageData['products'] = $this->model->getAllProducts();
        $this->pageData['title'] = "Товары";
        $this->view->render($this->pageTpl, $this->pageData);

        if($_FILES) {
            if($_FILES['csv']['type'] != 'text/csv' || $_FILES['csv']['type'] == '') {
                $this->pageData['errors'] = "Ошибка! Возможно данный файл имеет некорректный формат";
            } else {
                if(move_uploaded_file($_FILES['csv']['tmp_name'],UPLOAD_FOLDER.$_FILES['csv']['name'])) {
                    $file = fopen(UPLOAD_FOLDER.$_FILES['csv']['name'], "r");
                    $row = 1;
                    while($data = fgetcsv($file, 200, ";")) {
                        if($row == 1) {
                            $row++;
                            continue;
                        } else {
                            $this->model->addFromCSV($data);
                        }
                    }
                    fclose($file);
                    $this->model->getAllProducts();    
                }
            }
        }

    }

}

 ?>

Code lesson (ProductsModel.php)

<?php

class ProductsModel extends Model {

    public function getAllProducts() {
        $result = array();
        $sql = "SELECT * FROM products";
        $stmt = $this->db->prepare($sql);
        $stmt->execute();
        while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
            $result[$row['id']] = $row;
        }
        return $result;
    }

    public function addFromCSV($data) {
        $sql = "INSERT INTO products(name, price) VALUES(:name, :price)";

        $stmt = $this->db->prepare($sql);
        $stmt->bindValue(":name", $data[0], PDO::PARAM_STR);
        $stmt->bindValue(":price", $data[1], PDO::PARAM_INT);
        $stmt->execute();

    }


}

 ?>

Code lesson (products.tpl.php)

<!DOCTYPE html>
<html lang="ru">
<head>

    <meta charset="utf-8">
    <base href="http://cabinet.codetogether.ru/cabinet/products">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title><?php echo $pageData['title']; ?></title>

    <!-- Bootstrap Core CSS -->
    <link href="/css/bootstrap.min.css" rel="stylesheet">

    <!-- MetisMenu CSS -->
    <link href="/css/admin/metisMenu.min.css" rel="stylesheet">

    <!-- Custom CSS -->
    <link href="/css/admin/sb-admin-2.css" rel="stylesheet">

    <!-- Morris Charts CSS -->
    <link href="/css/admin/morris.css" rel="stylesheet">

    <!-- Custom Fonts -->
    <link href="/css/font-awesome.min.css" rel="stylesheet" type="text/css">

    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
        <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
        <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->

</head>

<body>

    <div id="wrapper">

        <!-- Navigation -->
        <nav class="navbar navbar-default navbar-static-top" role="navigation" style="margin-bottom: 0">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="index.html">Кабинет</a>
            </div>
            <!-- /.navbar-header -->

            <ul class="nav navbar-top-links navbar-right">
                <!-- /.dropdown -->
                <li class="dropdown">
                    <a class="dropdown-toggle" data-toggle="dropdown" href="#">
                        <i class="fa fa-user fa-fw"></i> <i class="fa fa-caret-down"></i>
                    </a>
                    <ul class="dropdown-menu dropdown-user">
                        <li><a href="#"><i class="fa fa-user fa-fw"></i> Профиль</a>
                        </li>
                        <li class="divider"></li>
                        <li><a href="/cabinet/logout"><i class="fa fa-sign-out fa-fw"></i> Выйти</a>
                        </li>
                    </ul>
                    <!-- /.dropdown-user -->
                </li>
                <!-- /.dropdown -->
            </ul>
            <!-- /.navbar-top-links -->

            <div class="navbar-default sidebar" role="navigation">
                <div class="sidebar-nav navbar-collapse">
                    <ul class="nav" id="side-menu">

                        <li>
                            <a href="/cabinet"><i class="fa fa-area-chart"></i> Статистика</a>
                        </li>
                        <li>
                            <a href="/cabinet/products"><i class="fa fa-cart-plus"></i> Товары</a>
                        </li>
                        <li>
                            <a href="/cabinet/users"><i class="fa fa-user-o"></i> Пользователи</a>
                        </li>
                    </ul>
                </div>
                <!-- /.sidebar-collapse -->
            </div>
            <!-- /.navbar-static-side -->
        </nav>

        <div id="page-wrapper">
            <div class="row">
                <div class="col-lg-12">
                    <h1 class="page-header"><?php echo $pageData['title']; ?></h1>
                </div>
                <!-- /.col-lg-12 -->
            </div>
            <!-- /.row -->
            <!-- /.row -->
            <div class="row">
                <div class="col-lg-12">
                    <!-- /.panel -->
                    <div class="panel panel-default">
                        <div class="panel-heading">
                            <i class="fa fa-bar-chart-o fa-fw"></i> Товары
                        </div>


                        <!-- /.panel-heading -->
                        <div class="panel-body" data-ng-app="products" data-ng-controller="productsController">
                            <div class="row">
                                <div class="col-lg-12">
                                    <div data-ng-view></div>
                                    <div class="table-responsive">
                                        <table class="table table-bordered table-hover table-striped">
                                            <thead>
                                                <tr>
                                                    <th>id товара</th>
                                                    <th>Наименование товара</th>
                                                    <th>Цена</th>
                                                </tr>
                                            </thead>
                                            <tbody>
                                                <?php
                                                    foreach ($pageData['products'] as $key => $value) { ?>
                                                        <tr>
                                                            <td><?php echo $value['id']; ?></td>
                                                            <td><a href="#<?php echo $value['id']; ?>"><?php echo $value['name']; ?></a></td>
                                                            <td><?php echo $value['price']; ?></td>
                                                        </tr>
                                                    <?php } ?>
                                            </tbody>
                                        </table>
                                    </div>
                                    <!-- /.table-responsive -->
                                </div>
                                <!-- /.col-lg-4 (nested) -->
                                <!-- /.col-lg-8 (nested) -->
                            </div>
                            <!-- /.row -->
                        </div>
                        <!-- /.panel-body -->
                    </div>
                    <!-- /.panel -->
                    <!-- /.panel -->
                </div>
                <!-- /.col-lg-8 -->
            </div>
            <!-- /.row -->
            <div class="row">
                <div class="col-lg-12">
                    <h2>Загрузить CSV файл с товарами</h2>
                    <form class="form-horizontal" method="post" enctype="multipart/form-data">
                        <label for="exampleInputFile">Загрузите CSV файл</label>
                        <input type="file" name="csv">
                        <button class="btn btn-default">Загрузить</button>
                    </form>
                </div>
            </div>
        </div>
        <!-- /#page-wrapper -->

    </div>
    <!-- /#wrapper -->

    <!-- jQuery -->
    <script src="/js/jquery.js"></script>

    <!-- Angular -->
    <script src="/js/angular.min.js"></script>

    <!-- Angular Route -->
    <script src="/js/angular-route.js"></script>

    <!-- Bootstrap Core JavaScript -->
    <script src="/js/bootstrap.min.js"></script>

    <!-- Metis Menu Plugin JavaScript -->
    <script src="/js/admin/metisMenu.js"></script>

    <!-- Custom Theme JavaScript -->
    <script src="/js/admin/sb-admin-2.js"></script>

    <script src="/js/admin/app.js"></script>

</body>

</html>

0 Comments

Submit a Comment

Your email address will not be published. Required fields are marked *


The reCAPTCHA verification period has expired. Please reload the page.

Pin It on Pinterest

Share This