Reputation: 461
I'm trying to get a CSV imported into a MySQL database, where each new line should represent a new row in the database.
Here is what I have so far in the CSV:
1one, 1two, 1three, 1four
2one, 2two, 2three, 2four
And in the application:
$handle = fopen($_FILES['filename']['tmp_name'], "r");
$data = fgetcsv($handle, 1000, ",");
$sql = "INSERT INTO tbl (col1, col2, col3, col4) VALUES (?, ?, ?, ?)";
$q = $c->prepare($sql);
$q->execute(array($data[0],$data[1],$data[2],$data[3]))
The problem is that only the first four values are being inserted, clearly due to the lack of a loop.
I can think of two options to solve this:
1) Do some "hacky" for loop, that remembers the position of the index, and then does n+1 on each of the inserted array values.
2) Realise that fgetcsv is not the function I need, and there is something better to handle new lines!
Thanks!
Upvotes: 1
Views: 263
Reputation: 76395
Why would you need a script for this? You can do this in 1 simple query:
LOAD DATA LOCAL INFILE '/data/path/to/file.csv' INTO your_db.and_table
FIELDS TERMINATED BY ', ' /* included the space here, bc there's one in your example*/
LINES TERMINATED BY '\n' /* or, on windows box, probably by '\r\n'*/
(`col1`, `col2`, `col3`, `col4`);
That's all there is to it (in this case, mysql manual will provide more options that can be specified like OPITIONALLY ENCLOSED BY
etc...)
Ok, as far as injection goes: while inserting it's -to the best of my knowledge- impossible to be an issue. The data is at no point used to build a query from, MySQL just parses it as varchar data and inserts the data (it doesn't execute any of it). The only operation it undergoes is a cast, type cast to int or float if that turns out to be required.
What could happen is that the data does contain query strings that could do harm when you start selecting data from your table. You might be able to set your MySQL server to escape certain characters for this session, or you could just run a str_replace('``','``',$allData);
or something in your script.
Bottom line is: I'm not entirely sure, but the risk of injection should be, overall, rather small.
A bit more can be found here
When it comes to temp files, since you're using $_FILES['filename']['tmp_name']
, you might want to use your own temp file: file_put_contents('myLoadFile.csv',file_get_contents($_FILES['filename']['tmp_name']));
, and delete that file once you're done. It could well be that it's possible to use the tempfile directly, but I haven't tried that, so I don't know (and not going to try today :-P).
Upvotes: 1
Reputation: 26765
while ($data = fgetcsv($handle, 1000, ",")){
//process each $data row
}
You may also wish to set auto_detect_line_endings
to true in php.ini, to avoid issues with Mac created CSVs.
Upvotes: 2