AJLX Posted August 30, 2017 Share Posted August 30, 2017 Hi Guys, I have an array that looks like this: Array([0] => Array([0] => Header1[1] => Header2[2] => Header3[3] => Header4[4] => Header5[5] => Header6[6] => Header7)[1] => Array([0] =>value1[1] =>Value2[2] =>Value3[3] => Value4[4] => Value5[5] => Value6[6] =>Value7)[2] => Array([0] =>value1[1] =>Value2[2] =>Value3[3] => Value3[4] => Value4[5] => Value5[6] => Value6) It has come from a CSV file. Basically, I only need to use some of the columns, the rest can be unset/deleted. Is there a way that I can easily make an array that just has for example "header1" and "header5" and the corresponding values "value1" and "value5"? I don't know what order the columns are going to be in, so I need to somehow do it by name. I think I know the concept of what to do, I just lack the php knowledge to actually do it! I think I need to: Step 1:Loop through the array and get the array keys that match up to the headers above Step 2:reload through the array unsetting based on the array keys found in step 1 I've tried looking into array_intersect and array_diff but I can't work out how these would help. Thanks for reading! Quote Link to comment Share on other sites More sharing options...
requinix Posted August 30, 2017 Share Posted August 30, 2017 What's your code to read the CSV file? It'll be easier to just change that to work how you want. Quote Link to comment Share on other sites More sharing options...
benanamen Posted August 30, 2017 Share Posted August 30, 2017 This sounds like an XY problem. What exactly is it you are doing? And I don't mean your attempt at it. Quote Link to comment Share on other sites More sharing options...
Sepodati Posted August 30, 2017 Share Posted August 30, 2017 (edited) If you don't need them, don't put them into the array in the first place. I agree with the above, too. What's the real problem you're trying to solve / system you're trying to create? Maybe there's a better way to do this from the very start. -John Edited August 30, 2017 by Sepodati Quote Link to comment Share on other sites More sharing options...
requinix Posted August 30, 2017 Share Posted August 30, 2017 I wanted to see code first but if this is how the thread is going, $csv = array( explode(",", "h2,h4,h1,h3"), explode(",", "r1c2,r1c4,r1c1,r1c3"), explode(",", "r2c2,r2c4,r2c1,r2c3"), explode(",", "r3c2,r3c4,r3c1,r3c3") ); /* $h = fopen("file.csv", "rt"); */ /* $header = fgetcsv($h); */ $header = array_shift($csv); /* while (!feof($h)) { */ /* $row = fgetcsv($h); */ foreach ($csv as $row) { $hrow = array_combine($header, $row); echo "c1 = ", $hrow["h1"], "\n"; } Quote Link to comment Share on other sites More sharing options...
AJLX Posted August 30, 2017 Author Share Posted August 30, 2017 Hi All, Thanks for the response so far. This is from a file that built about a year ago, I've come to update it. The original code uploaded the file, put it into an array, and then deleted the file. The more I think about it, the more I think that's a pointless step? The CSV sent from a previous page. The aim of the code is to take the data from a .csv file, extract the columns that I want, and store them into a database, for retrieval later. I know the names of the columns that I want to keep, but the maker of the software version keeps updating how they export the data, and adding columns which I can ignore. My current upload code is below. I think it was taken from a tutorial that I found ages ago. Now that I know a little bit more about PHP(!) I'm trying to understand more efficient ways of working! $target_dir = "csv/"; $target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]); $uploadOk = 1; $imageFileType = pathinfo($target_file,PATHINFO_EXTENSION); // Check if image file is a actual or fake image if(isset($_FILES["fileToUpload"])) { // Check file size if ($_FILES["fileToUpload"]["size"] > 500000) { exit ("Sorry, your file is too large."); $uploadOk = 0; } // Allow certain file formats if($imageFileType != "csv" ) { exit ("Sorry, only CSV files are allowed."); $uploadOk = 0; } // Check if $uploadOk is set to 0 by an error if ($uploadOk == 0) { exit ("Sorry, your file was not uploaded."); // if everything is ok, try to upload file } else { if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) { echo "The file ". basename( $_FILES["fileToUpload"]["name"]). " has been uploaded."; $file = basename($_FILES["fileToUpload"]["name"]); } else { exit ("Sorry, there was an error uploading your file."); } } ini_set('auto_detect_line_endings', TRUE); $rows = array_map('str_getcsv', file('csv/'.$file)); echo "<pre>"; print_r($rows); echo "</pre>"; $header = array_shift($rows); // Strip out the colum headers from the CSV $csv = array(); //print_r($rows); foreach ($rows as $row) { //loop through, manually unset the rows that I don't want, and format, and assign variables to the rows that I want to keep } Once again- Thanks! Quote Link to comment Share on other sites More sharing options...
requinix Posted August 30, 2017 Share Posted August 30, 2017 Instead of the file+array_map, do a normal fopen/fgetcsv/fclose loop - which also replaces the foreach. And there's another way to get values that might work better for you. $h = fopen('csv/'.$file, 'rt'); $header = array_flip(fgetcsv($h)); 0=>header1 becomes header1=>0 while (!feof($h)) { $line = fgetcsv($h); $value1 = $line[$header["header1"]]; $value3 = $line[$header["header3"]]; // etc } fclose($h); Quote Link to comment Share on other sites More sharing options...
AJLX Posted August 30, 2017 Author Share Posted August 30, 2017 Hi Lazy Administrator, Thanks for your help (and patience!) so far. The code you posted doesn't seem to work for me. If I Print_R the $header array, that contains all of the headers, and looks as I expect it should. However, when I Print_R the $line array, the keys are numbered, they don't have the same titles as the header array, so therefore the: $value1 = $line[$header["header1"]]; comes back with an undefined index error. I thought that I could use array_combine to put the headers back into where I think they should be: $h = fopen('csv/'.$file, 'rt'); $header = fgetcsv($h); $flip_header = array_flip(fgetcsv($h)); //0=>header1 becomes header1=>0 while (!feof($h)) { $line = fgetcsv($h); $new = array_combine($header,$line); print_r($new); $unit = $new[$flip_header["Unit"]]; } fclose($h); Now the array looks how I think it should but still doesn't work. Therefore I clearly don't understand how it should look/work! Thanks! Quote Link to comment Share on other sites More sharing options...
requinix Posted August 30, 2017 Share Posted August 30, 2017 Well with that code, you would have to do $unit = $line[$flip_header["Unit"]];The alternative with array_combine would be to ignore $flip_header entirely (it turns names into numbers) and $unit = $new["Unit"];But I recommend the $flip_header one. Quote Link to comment Share on other sites More sharing options...
AJLX Posted August 30, 2017 Author Share Posted August 30, 2017 Hi Lazy Administrator, I'm still struggling with this one! I'm onto about my 10th generation of code which looks like this: $h = fopen('csv/'.$file, 'rt'); $header =fgetcsv($h); //0=>header1 becomes header1=>0 while (!feof($h)) { $line = fgetcsv($h); $new_arr = array_combine($header,$line); print_r($new_arr); echo $new_arr["Unit"]; //print_r(array_keys($new_arr)); } fclose($h); That gives me the following output: The Array key "Unit" exists, but for some reason doesn't seem to get found. I tried running print_r(array_keys($new_array) to try and investigate the array keys a bit further, with this result I've played about with adding some spaces to the word Unit to see if that would help, but it doesn't seem to make a difference. It's getting late here, and I'm getting the feeling I've done something that's super simple, but stupid! Quote Link to comment Share on other sites More sharing options...
requinix Posted August 31, 2017 Share Posted August 31, 2017 That output did not come from print_r(array_keys($new_arr)). What does var_dump($new_arr) show? Quote Link to comment Share on other sites More sharing options...
AJLX Posted August 31, 2017 Author Share Posted August 31, 2017 That output did not come from print_r(array_keys($new_arr)). What does var_dump($new_arr) show? The bottom screenshot clearly doesn't! I must have uploaded the wrong file. I'll leave it there to keep the thread complete. Here is the ACTUAL output, and the the Var_dump afterwards. There's weird characters being exported in the channel column, but as far as I can tell, that's the only key that's effected. I should be able to clean that up easy enough. Any ideas? Many thanks Quote Link to comment Share on other sites More sharing options...
requinix Posted August 31, 2017 Share Posted August 31, 2017 Take a look at some of those values: string(1) "" string(7) "O/W" string(3) "0"Weird, right? What is the file encoding of the CSV? What does print_r(array_combine($header, array_map("bin2hex", $header)));output? And please, don't take a screenshot: do a View Source of the page and copy/paste the formatted text into a [code] in a post. Quote Link to comment Share on other sites More sharing options...
AJLX Posted August 31, 2017 Author Share Posted August 31, 2017 Hi Requinix, The file is natively exported as a UTF-16. I re-saved it as a UTF-8 and it all works perfectly. Does PHP have the ability to be able to convert the file for me? Quote Link to comment Share on other sites More sharing options...
requinix Posted August 31, 2017 Share Posted August 31, 2017 Assuming you're using UTF-8 in the rest of your application then yes. Try adding stream_filter_append($h, "convert.iconv.utf-16.utf-8");after the fopen(). Does it work now? Does the first header "Channel" still have the two >s (the UTF-16 BOM)? Quote Link to comment Share on other sites More sharing options...
AJLX Posted August 31, 2017 Author Share Posted August 31, 2017 That works perfectly- Thanks for your help- I've learnt lots! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.