简体   繁体   中英

LOAD DATA INFILE doesn't upload CSV data into MySQL table with no error

Update:

I attempted to execute the query generated by PHP script in phpMyAdmin's SQL tab and got:

#7890 - Can't find file 'C:wamp    mpphpB4C4.tmp'.

It cut path between C:wamp and tmp file name. Could it be I'm escaping file path incorrectly?: $file = $_FILES['csv']['tmp_name'];


I'm writing this cool webapp using PHP and MySQL. One of its functions is to upload contents of a CSV file into a table in my database called suites.

CSV file looks like this:

1230,Cool Business,,1
3612,Not-so-cool Business Ltd.,John Smith,0

Column meanings from left to right in this CSV go as such: Suite number, Name of the business operating at this suite, Primary contact(optional), Did I already go there?(0 - no, 1 - yes; optional also).

The database table, named suites, has the following structure:

suite_id (primary), location_id (foreign referencing locations table), suite , business , contact , visited

As you may have already guessed by now I'm trying to insert only the last 4 columns of the suites table with the above CSV example.

I attempt to do that with the following PHP code:

<?php

/**
 * Class registration
 * handles the user registration
 */
class SuiteCSV
{
    /**
     * @var object $db_connection The database connection
     */
    private $db_connection = null;
    /**
     * @var array $errors Collection of error messages
     */
    public $errors = array();
    /**
     * @var array $messages Collection of success / neutral messages
     */
    public $messages = array();

    /**
     * the function "__construct()" automatically starts whenever an object of this class is created,
     * you know, when you do "$registration = new Registration();"
     */
    public function __construct()
    {
        if(isset($_POST["add_suite_csv"])){
            $this->addSuiteCSV();
        }
    }

    /**
     * handles the entire registration process. checks all error possibilities
     * and creates a new user in the database if everything is fine
     */ 
    private function addSuiteCSV()
    {
        if (empty($_POST['suite_location_csv'])) {
            $this->errors[] = "Must select location of suite";
        }else{

        // create a database connection
        $this->db_connection = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);

        if (!$this->db_connection->set_charset("utf8")) {
                $this->errors[] = $this->db_connection->error;
        }

        if (!$this->db_connection->connect_errno) {
            $suite_location_csv = $this->db_connection->real_escape_string(strip_tags($_POST['suite_location_csv'], ENT_QUOTES));
            if ($_FILES['csv']['size'] > 0) {
                $file = $_FILES['csv']['tmp_name'];
                $query = <<<eof
LOAD DATA INFILE '$file'
INTO TABLE sales.suites
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\r\n'
(suite,business,contact,visited)
SET location_id = $suite_location_csv
eof;

                $query_add_suite_csv = $this->db_connection->query($query);

                if ($query_add_suite_csv) {
                    $this->messages[] = "CSV has been uploaded.";
                } else {
                    $this->errors[] = "Sorry, I couldn't upload this CSV. Try again.";
                }

                var_dump($query_add_suite_csv);


            }else{
                $this->errors[] = "Must select CSV file for upload";
            }
        }else{
            $this->errors[] = "Database connection error";
        }
    }
}
}

$suite_location in this case is a value that user will select from a drop down menu on the upload form, which in turn is populated with another PHP script when page is loaded. Values of $suite_location are location_id values in locations table which has a foreign key in suite table.

So, the user picks a location, selects a CSV file and uploads it to the suites table.

Nothing is happening though. There are no errors. I've looked at LOAD DATA INFILE documentation and tried to apply what I've understood from it, but still doesn't seem to work.

Form snippet:

<form class="form-horizontal" method="post" action="admin_add_location.php" enctype="multipart/form-data" name="addsuitecsv">
    <div class="form-group">
        <label class="control-label">Select Locations:</label>
        <div class="">
            <select size="6" name="suite_location_csv">
                    <?php $location->getLocations(); ?>
            </select>
        </div>
        <label class="control-label">Choose your file:</label>
        <div class="">
            <input name="csv" type="file" id="csv" />
        </div>
        <button class="btn btn_success" name="add_suite_csv" type="submit"><span class="glyphicon glyphicon-upload" ></span>Import CSV</button>
    </div>
</form>

Add View PHP:

<?php
    // include the configs / constants for the database connection
    require_once("config/db.php");

    // load the login class
    require_once("classes/Login.php");

    // create a login object. when this object is created, it will do all login/logout stuff automatically
    // so this single line handles the entire login process. in consequence, you can simply ...
    $login = new Login();

    // only administrators can see
    if ($login->isUserLoggedIn() == true && $_SESSION['user_group'] == 0) {
        require_once("classes/Location.php");
        $location = new location();
        require_once("classes/Suite.php");
        $suite = new Suite();
        require_once("classes/SuiteCSV.php");
        $suitecsv = new SuiteCSV();
        include("includes/header.php");
        include("views/admin_add_location_view.php");
        include("views/admin_add_suite_view.php");
        include("views/admin_add_suite_csv_view.php");
        include("includes/footer.php");
    }else{
        echo "<h1>Access denied</h1>";
        include("views/go_back_view.php");
    }
?>

Changing:

$file = $_FILES['csv']['tmp_name'];

to:

$file = addslashes($_FILES['csv']['tmp_name']);

fixed the issue and CSV now gets uploaded.

Basically I had to escape slashes in the file path.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM