So, I got a CSV file that I correctly import in PHP.
function csv_to_array($filename='', $delimiter=';')
{
if(!file_exists($filename) || !is_readable($filename))
return FALSE;
$header = NULL;
$data = array();
if (($handle = fopen($filename, 'r')) !== FALSE)
{
while (($row = fgetcsv($handle, 1000, $delimiter)) !== FALSE)
{
if(!$header)
$header = $row;
else
$data[] = array_combine($header, $row);
}
fclose($handle);
}
return $data;
}
echo '<pre>';
$product_csv = csv_to_array("$underfolder/$value");
print_r($product_csv);
echo '</pre>';
This works and give show as result:
Array (
[0] => Array
(
[Name] => product name xyz
[Description] => der trefa a as sadfse
[TAGS] => tag1 tag2 tag3
[360] => yes
[VR] => no
)
)
But how I echo a VALUE of $product_csv? Like if I want to print out "product name xyz"? I tried with echo $product_csv["0"]['Name'] but without any results...
var_dump(array_keys($product_csv[0])); gives me:
array(5) { [0]=> string(7) "Name" [1]=> string(11) "Description" [2]=> string(4) "TAGS" [3]=> int(360) [4]=> string(2) "VR" }
As you can see in your var_dump(array_keys($product_csv[0])); output: string(7) "Name", there must be 3 invisible characters as Name is only 4 characters not 7.
Attempt to trim them by replacing:
$header = $row;
With:
$header = array_map('trim', $row);
It could very well be a Byte Order Mark (BOM). If you are creating this file then check the editor to see if it saves it with a BOM, and if possible disable it.
Related
My query gives me a result in an array :
$donnnes =
Table ( [0] => Table ( [sku_code] => A1101_0090_TU [SKU_EAN] => 9346799868270 ) )
My .txt file create itself well but fills up like this :
MMXC1_|9346799868270|0|0
MMXC1_| |0|1
MMXC1_| |1|4
...
Only the first line is completely filled, in the others there is nothing between the two pipes '|' after "MMXC1_" while in my var_dump($data_final); all the data is there, where does my error come from?
$resultat = mysqli_query($bdd, "SELECT trim(concat(concat(SKU_ITEM_VARIANT,'_'),trim(SKU_SIZE)))as sku_code , SKU_EAN FROM dwh_dev.dwh_d_sku");
while ($donnees[] = mysqli_fetch_assoc($resultat)) {
}
print_r($donnees); //Array ( [0] => Array ( [sku_code] => A1101_0090_TU [SKU_EAN] => 9346799868270 )
$constante = "MMXC1_";
$temp2 = array_column($donnees, 'SKU_EAN', 'sku_code');
if (($handle = fopen("$nomcsv", "r")) !== FALSE) {
$firstLine = true;
while (($data = fgetcsv($handle, 1000000, ";")) !== FALSE)
{
if(!$firstLine) {
$SKU_EAN = $temp2[$data[6].'_'.$data[7].'_'.$data[8]];
var_dump($SKU_EAN); //A1101_0090_TU A1104_0090_TU
// Create line here and immediately add it to `$data_final`
$data_final[] = $constante.'|'.$SKU_EAN.'|'.$data[12].'|'.$data[13];
var_dump($data_final); // array(1) { ["A1101_0090_TU"]=> string(13) "9346799868270" } array(1) { [0]=> string(26) "MMXC1_|9346799868270|0|0" } array(2) { [0]=> string(26) "MMXC1_|9346799868270|0|0" [1]=> string(13) "MMXC1_||0|0" }
}
$firstLine = false;
}
}
$cheminfile = "//alcyons/IT/PhotoShoot/retail/CSV/TXT_Finaux/MMX".date('His').".txt";
$fp = fopen("$cheminfile", "w");
fputcsv($fp, $data_final, "\n");
fclose($fp);
Why are you using fputcsv on a .txt file? use fwrite instead.
replace
fputcsv($fp, $data_final, "\n");
with
foreach($data_final as $data){
fwrite($fp,$data."\n");
}
I am trying to upload/import CSV into SQL server with some basic validation such as CSV headers should contain 'SecurityID' and 'SecurityID' value can NOT be NULL and has NUMERIC value. I'm having some issue validating headers part and stuck. Below is my code from functions.php. For clarity I've removed DB insert/update code as I am not getting that far.
if(isset($_POST["Import"])){
$filetempname=$_FILES['file']['tmp_name'];
$filename=$_FILES['file']['name'];
$filetype = $_FILES['file']['type'];
$csv_mimetypes = array(
'text/csv',
'text/plain',
'application/csv',
'text/comma-separated-values',
'application/excel',
'application/vnd.ms-excel',
'application/vnd.msexcel',
'text/anytext',
'application/octet-stream',
'application/txt',
);
$expectedHeaders = array(
'SecurityID'
);
$requiredFields = array(
'SecurityID'
);
$firstLine = true;
if (in_array($_FILES['file']['type'],$csv_mimetypes))
{
if($_FILES["file"]["size"] > 0)
{
$file = fopen($filetempname, "r");
#echo $file;
while (($getData = fgetcsv($file, 10000, ",")) !== FALSE)
{
foreach($getData as $row)
{
if($firstLine)
{
var_dump($expectedHeaders);
//Set the headers:
$firstLine = false;
var_dump($getData);
$headers = array_flip($getData);
// Validate the headers:
if($headers !== $expectedHeaders)
{
echo "Invalid headers. Aborting import.";
}
Continue;
}
foreach($requiredFields as $requiredKey)
{
$value = $row[$headers[$requiredKey]];
// '0' will also match as empty(), although it is a valid value:
if(empty($value) && $value != '0' && is_numeric($value))
{
echo "Row {$requiredKey} may not be empty or has to be numeric. Aborting import.";
}
}
fclose($file);
}
}
}
}
else
{
echo "<script type=\"text/javascript\">
alert(\"Invalid File:Please Upload CSV File.\");
window.location = \"indexd.php\"
</script>";
}
}
Trying to upload/validate CSV I get below errors. IIS webserver logs doesn't give me anything..:
Invalid headers. Aborting import.
var_dump($getData); gives me below:
array(15) {
[0]=> string(14) "DataProviderID"
[1]=> string(8) "FamilyID"
[2]=> string(10) "FamilyName"
[3]=> string(10) "SecurityID"
[4]=> string(4) "Name"
[5]=> string(10) "PrimaryRic"
[6]=> string(13) "Administrator"
[7]=> string(16) "IsAdminEULocated"
[8]=> string(21) "IsAdminOnEsmaRegister"
[9]=> string(25) "IsBenchmarkOnEsmaRegister"
[10]=> string(26) "IsBenchmarkOnAdminRegister"
[11]=> string(23) "HasEUListedFundTracking"
[12]=> string(25) "HasEUListedFutureOrOption"
[13]=> string(20) "IsAdminPre2016Active"
[14]=> string(24) "IsBenchmarkPre2018Active"
}
var_dump($expectedHeaders); gives me below:
array(1) {
[0]=> string(10) "SecurityID"
}
My CSV file for testing is as below:
DataProviderID,FamilyID,FamilyName,SecurityID,Name,PrimaryRic,Administrator,IsAdminEULocated,IsAdminOnEsmaRegister,IsBenchmarkOnEsmaRegister,IsBenchmarkOnAdminRegister,HasEUListedFundTracking,HasEUListedFutureOrOption,IsAdminPre2016Active,IsBenchmarkPre2018Active
2,MSCI,MSCI Main Indices - Americas,17912,NORTH AMERICA IMI-664176,.dMINA000I0PUS,MSCI Limited,1,1,0,99,99,99,99,1
I included some var_dump's so you could see what your code does. When something doesn't work as expected ALWAYS verify your variables ("Does it hold the value I expect it does?"):
// [...]
$expectedHeaders = array(
'SecurityID'
);
var_dump($expectedHeaders);
// Will print array(
// 0 => (string) 'SecurityID'
// )
// [...] while foreach etc
//Set the headers:
$firstLine = false;
var_dump($getData);
// Will print array(
// 0 => (string) 'DataProviderID'
// 1 => (string) 'FamilyID'
// 2 => (string) 'FamilyName'
// 3 => (string) 'SecurityID'
// etc
// );
$headers = array_flip($getData);
var_dump($headers);
// Will print array(
// (string) 'DataProviderID' => 0
// (string) 'FamilyID' => 1
// (string) 'FamilyName' => 2
// (string) 'SecurityID' => 3
// etc
// )
// Validate the headers:
if($headers !== $expectedHeaders)
{
// Will always get into this if, because as you can see
// from the var_dumps, $expectedHeaders will never be
// equal to $headers - nor equal to $getData
echo "Invalid headers. Aborting import.";
}
A possible solution for your if-statement below. array_intersect will give the values that are both in $getData as in $expectedHeaders. If $getData contains more headers, those are wiped-out by array_intersect resulting in the same count (assuming order doesn't matter). If $getData has missing headers, the count of that intersection will be less than the count of $expectedHeaders.
if (
count(array_intersect($getData, $expectedHeaders))
!= count($expectedHeaders)
) {
// Wrong CSV format error
}
This question already has answers here:
UTF-8 all the way through
(13 answers)
Closed 7 years ago.
I get the error:
Notice: Undefined index: marca
When I'm trying to do this:
echo $data[0]['marca'];
But if I print the array, like this:
print_r($data[0]);
The output is:
Array ( [marca] => Jack&co [stock] => 10 [nome] => JW0114M2 [codice] => JW0114M2 [caratteristiche] => JW0114M2 Classe articolo: orologio da polso Sesso: unisex Movimento: quarzo Bracciale: acciaio Tipologia: cronografo [prezzo al pubblico €] => 99,00 [sconto %] => 75 [prezzo orologistock €] => 25,00 [img] => http://orologistock.it/virtual_img/ )
//^^^^^ See the element exists!
So why can't I access the array element?
EDIT:
The output from the source code with var_dump($data[0]); is:
array(9) { ["marca"]=> string(7) "Jack&co" ["stock"]=> string(2) "10" ["nome"]=> string(8) "JW0114M2" ["codice"]=> string(8) "JW0114M2" ["caratteristiche"]=> string(117) "JW0114M2 Classe articolo: orologio da polso Sesso: unisex Movimento: quarzo Bracciale: acciaio Tipologia: cronografo " ["prezzo al pubblico €"]=> string(5) "99,00" ["sconto %"]=> string(2) "75" ["prezzo orologistock €"]=> string(5) "25,00" ["img"]=> string(35) "http://orologistock.it/virtual_img/" }
I'm getting my array from a .csv file:
function csv_to_array($filename='', $delimiter=';')
{
if(!file_exists($filename) || !is_readable($filename))
return FALSE;
$header = NULL;
$data = array();
if (($handle = fopen($filename, 'r')) !== FALSE)
{
while (($row = fgetcsv($handle, 1000, $delimiter)) !== FALSE)
{
if(!$header){
$header = $row;
}
else{
if(count($row) == 9)
$data[] = array_combine($header, $row);
}
}
fclose($handle);
}
return $data;
}
$data= csv_to_array($_FILES['data']['tmp_name']);
Encoding of file was wrong, change encoding to UTF-8 solved the Problem.
I am trying to split an array if one of the lines has an empty value. My array is being exported to a csv and has multiple lines of data, if the data is not complete it will be sent to a uncomplete csv and if it is complete it will be sent a complete csv.
This is what my array structure looks like the blank field on the first line is on email (this line should be split out of the array:
array(2) {
[0]=> array(6) {
["Username"]=> string(47) " STARRY NIGHT CINEMA - RISE OF THE GUARDIANS "
["Email"]=> string(0) ""
["Location"]=> string(1) "1"
["Type"]=> int(1)
["Title"]=> string(47) " STARRY NIGHT CINEMA - RISE OF THE GUARDIANS "
["Description"]=> string(491) "the Tooth Fairy"
}
[1]=> array(6) {
["Username"]=> string(26) "Maui Nui Botanical Gardens"
["Email"]=> string(18) "info#mnbg.org"
["Location"]=> string(1) "1"
["Type"]=> int(1)
["Title"]=> string(26) "Maui Nui Botanical Gardens"
["Description"]=> string(50) "Conserving Hawaiian Plants & Cultural Heritage"
}
}
Writing to my csv:
$fp = fopen('entries.csv', 'w');
foreach ($entries as $fields) {
fputcsv($fp, $fields);
}
fclose($fp);
if (!copy("http://www.simonstaton.co.uk/entries.csv", "entries.csv")) {
echo ("failed to copy file");
};
I have no idea where to start with this and as to what function I should use so any advice is greatly appreciated.
Simon
To separate the entries by complete or incomplete you can open two files for writing. One to contain each.
// filenames
$fn_complete = 'entries.csv';
$fn_incomplete = 'incomplete_entries.csv';
// file pointers
$fp_complete = fopen($fn_complete, 'w');
$fp_incomplete = fopen($fn_incomplete, 'w');
// write CSVs
foreach ($entries as $fields) {
if (in_array('', $fields))
fputcsv($fp_incomplete, $fields);
else
fputcsv($fp_complete, $fields);
}
fclose($fp_complete);
fclose($fp_incomplete);
if (!copy('http://www.simonstaton.co.uk/' . $fn_complete, $fn_complete)) {
echo ('failed to copy file ' . $fn_complete);
};
if (!copy('http://www.simonstaton.co.uk/' . $fn_incomplete, $fn_incomplete)) {
echo ('failed to copy file ' . $fn_incomplete);
};
You can check if any of the values in your array is empty like this:
in_array('', $array)
so it then you can do a simple if
if(in_array('', $array)) {
//Do whatever you have to do to slip your array. I don't understand exactly what you want the end result to look like .
}
First pack your CSV data into an array using fgetcsv(). Then use a loop to search for "".
Exemplar:
$row = 1;
if (($resource = fopen("example.csv", "r")) !== false) {
while (($data = fgetcsv($resource, 1000, ",")) !== false) {
$num = count($data);
$row++;
for ($c=0; $c < $num; $c++) {
if ($data[$c] == "") {
// operate
}
}
}
fclose($handle);
}
By the way, don't use the split() function. Use preg_split().
http://php.net/manual/en/function.fputcsv.php
how can I get everything from a repeated index and the other in an array? see:
$Produtos = Array( 'Guitarra' , // repeats
'Bateria' , // repeats
'Piano' ,
'Baixo' ,
'Guitarra' , // repeats
'Violão' ,
'Caixas de Som' ,
'Bateria' , // repeats
'Sanfona' );
Reviewed are the indices that are repeated, as I do to get what's between them?
I wish to return:`
Array
(
[0] => Array(
[0] => Piano
[1] => Baixo
[1] => Array(
[0] => Violão
[1] => Caixas de Som
[2] => Array(
[0] => Sanfona
) )
It can be solved like this:
<?php
<?php
$Produtos = Array( 'Guitarra' , // repeats
'Bateria' , // repeats
'Piano' ,
'Baixo' ,
'Guitarra' , // repeats
'Violão' ,
'Caixas de Som' ,
'Bateria' , // repeats
'Sanfona' );
$countedProducts = array_count_values($Produtos);
$c = 0;
foreach ($Produtos as $product)
{
if ($countedProducts[$product] > 1)
{
if (count($novosProdutos))
{
$c++;
}
}else{
$novosProdutos[$c][] = $product;
}
}
print '<pre>';
var_dump($novosProdutos);
print '</pre>';
?>
Output:
array(3) {
[0]=>
array(2) {
[0]=>
string(5) "Piano"
[1]=>
string(5) "Baixo"
}
[1]=>
array(2) {
[0]=>
string(7) "Violão"
[1]=>
string(13) "Caixas de Som"
}
[2]=>
array(1) {
[0]=>
string(7) "Sanfona"
}
}
I have understood in the meantime, what you really wanted to have as an result. I changed it now, and it work also with multiple repeations and starts always from zero.
$finalProducts = array();
$currentKey = 0;
$wordCount = array_count_values($Produtos);
foreach($Produtos as $val) {
if($wordCount[$val] > 1) {
$currentKey++;
}
elseif(strlen($currentKey) > 0) {
$finalProducts[$currentKey][] = $val;
}
}
$finalProducts = array_values($finalProducts);
<?php
function array_between_duplicates($ary)
{
// first, tally up all the values
// we need to know how many times each value repeats
$count = array_count_values($ary);
// next, we want only the values that are not repeated.
// This can be done by filtering the array for values
// present 2+ times
$between = array_filter($count, create_function('$a','return $a==1;'));
// now that we have the unique values, swap the keys
// and value locations using array_keys
$swap = array_keys($between);
// and then intersect the new array with the original
// array so we can get back their original key values.
$intersect = array_intersect($ary, $swap);
var_dump($intersect);
// now, in order to get the nested groups we will use
// skipped keys as a sign that the in-between values
// were repeats. So, iterate over the array and break
// out these groups
$result = array(); $group = array();
foreach ($ary as $key => $value)
{
if (!array_key_exists($key, $intersect) && count($group) > 0)
{
$result[] = $group;
$group = array();
}
if (array_search($value,$intersect) !== false)
$group[] = $value;
}
if (count($group) > 0)
$result[] = $group;
// return the result
return $result;
}
var_dump(array_between_duplicates($Produtos));
Results in:
array(3) {
[0]=>
array(2) {
[0]=>
string(5) "Piano"
[1]=>
string(5) "Baixo"
}
[1]=>
array(2) {
[0]=>
string(7) "Violão"
[1]=>
string(13) "Caixas de Som"
}
[2]=>
array(1) {
[0]=>
string(7) "Sanfona"
}
}
DEMO