Setting value in array inside foreach loop PHP - php

Hello I am setting a key value pair in an array in a foreach loop
e.g
array(2) {
[0]=>
array(1) {
["resourceType"]=>
string(4) "File"
["resourceName"]=>
string(4) "Test"
[1]=>
array(1) {
["resourceType"]=>
string(4) "File"
["resourceName"]=>
string(4) "Test"
}
I am doing this via a foreach loop
foreach ($output as $data) {
$resourceType = strpos($data, "d");
if ($resourceType) {
$ftpArray[]['resourceType'] = "Folder";
} else {
$ftpArray[]['resourceType'] = "File";
}
$resourceName = strrchr($data, " ");
$resourceName = trim($resourceName);
if ($resourceName != ".." && $resourceName != "." && $resourceName != "") {
$ftpArray[]['resourceName'] = $resourceName;
}
}
But the output is this
[0]=>
array(1) {
["resourceType"]=>
string(4) "File"
}
[1]=>
array(1) {
["resourceType"]=>
string(4) "Test"
}
[2]=>
array(1) {
["resourceType"]=>
string(4) "File"
}
[3]=>
array(1) {
["resourceName"]=>
string(9) ".htaccess"
}
Rather than the example I gave at the start of the question. How can I get the array to fill in key values pairs like the first example.

Make an tmp array
foreach ($output as $data) {
$a = array();
if (strpos($data, "d")) {
$a['resourceType'] = "Folder";
} else {
$a['resourceType'] = "File";
}
$resourceName = trim(strrchr($data, " "));
if ($resourceName != ".." && $resourceName != "." && $resourceName != "") {
$a['resourceName'] = $resourceName;
}
$ftpArray[] = $a;
}
Each calling of $ftpArray[] = 'x' adds new item to the array. It does not metter if you add there some second dimension key.

You want to add a datastructure to a array. This, create the datastructure, do your stuff and add it to the array:
foreach ($output as $data) {
$struct = array('resourceType' = > '', 'resourceName' => '');
// do stuff, on the struct
$resourceType = strpos($data, "d");
if ($resourceType) {
$struct['resourceType'] = "Folder";
} else {
$struct['resourceType'] = "File";
}
$resourceName = strrchr($data, " ");
$resourceName = trim($resourceName);
if ($resourceName != ".." && $resourceName != "." && $resourceName != "") {
$struct['resourceName'] = $resourceName;
}
$ftpArray[] = $struct;
}
Notice that there is a sub tile difference with the previous answer, as the structure is always created.

Each [] operation on array adds a new element to the loop, so you would need to create a temporary value and then add it to the loop:
$element = array();
// set the data here
$output_array[] = $element
And second thing with that script string positions start with 0, so if you need to know that character was not found when using strpos you should check the return value with === or !== for FALSE.

Related

How to exclude NULL results in a .txt file and display them in php?

I read a csv file that contains these values :
; ;WH;391;M;9353970157191;A1124;0010;TU;1; ;7/1/2019;0;0;
; ;WH;391;M;9353970157214;A1119;0090;TU;1; ;7/1/2019;0;0;
....
At the end I get a .txt file which is like this:
MMXC1_|A0391|9353970395487|0|0
MMXC1_|A0391| |1|0 //$SKU_EAN NULL
MMXC1_|A0391|9353970394879|4|2
...
But sometimes the $SKU_EAN is NULL because it doesn't have a corresponding sku_code
I would like to exclude lines where the $SKU_EAN is NULL from my .txt file and display them on the screen with the sku_code, and the number of the corresponding line in the csv file, how can I do that?
$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)) {
// var_dump($donnees); //array(1) { [0]=> array(2) { ["sku_code"]=> string(13) "A1101_0090_TU" ["SKU_EAN"]=> string(13) "9346799868270" } } array(2) { [0]=> array(2) { ["sku_code"]=> string(13) "A1101_0090_TU" ["SKU_EAN"]=> string(13) "9346799868270" }....
}
$constante = "MMXC1_";
$temp = array_column($datas_mag, 'MAGCOD', 'MAGAS400');
$temp2 = array_column($donnees, 'SKU_EAN', 'sku_code');
if (($handle = fopen("$nomcsv", "r")) !== FALSE) {
$firstLine = true;
while (($data = fgetcsv($handle, 1000000, ";")) !== FALSE)
{
if(!$firstLine) {
$EAN = 'A'.$temp[$data[3]];
$SKU_EAN = $temp2[$data[6].'_'.$data[7].'_'.$data[8]];
var_dump($SKU_EAN); //string(13) "9353970395487" string(13) "9346799046166" NULL NULL string(13) "9346799046756"...
$data_final[] = $constante.'|'.$EAN.'|'.$SKU_EAN.'|'.$data[12].'|'.$data[13];
var_dump($data_final); //array(1) { [0]=> string(30) "MMXC1_|A0391|9353970395487|0|0" }
}
$firstLine = false;
}
}
$cheminfile = "//alcyons/IT/PhotoShoot/retail/CSV/TXT_Finaux/MMX".date('His').".txt";
$fp = fopen("$cheminfile", "w");
foreach($data_final as $data){
fwrite($fp,$data."\n");
}
fclose($fp);
Try this
I've assumed that your comment around $SKU_EAN are individual example values, so adding the following line should skip the iteration where this value is null.
if(is_null($SKU_EAN)) continue;
Full code:
$i = 1;
while(($data = fgetcsv($handle, 1000000, ";")) !== FALSE) {
$i++;
if(!$firstLine) {
$EAN = 'A'.$temp[$data[3]];
$SKU_EAN = $temp2[$data[6].'_'.$data[7].'_'.$data[8]];
if(is_null($SKU_EAN)) {
echo 'Can\'t find SKU_EAN for iteration number: ' . $i . '<br />';
continue;
}
$data_final[] = $constante.'|'.$EAN.'|'.$SKU_EAN.'|'.$data[12].'|'.$data[13];
}
$firstLine = false;
}

How can I split a huge array into chunks?

I am parsing about 500.000 entries into an array $properties:
$properties = array();
$handle = fopen($file_path, "r");
if ($handle) {
while (($str = fgets($handle)) !== false) {
if (strlen($str) && $str[0] == '#') {
$pdate = substr($str, 1);
$date = rtrim($pdate);
$formatted = DateTime::createFromFormat('* M d H:i:s T Y',$date);
}
$str = rtrim ($str, "\n");
$exp = explode ('=', $str);
if(count($exp) == 2){
$exp2 = explode('.', $exp[0]);
if( count($exp2) == 2 ) {
if($exp2[1] == "dateTime"){
$s = str_replace("\\","",$exp[1]);
$d = strtotime($s);
$dateTime = date('Y-m-d H:i:s', $d);
$properties [$exp2[0]][$exp2[1]] = $dateTime;
} else {
$properties [$exp2[0]][$exp2[1]] = $exp[1];
}
} else {
$properties [$exp[0]] = $exp[1];
}
}
}
fclose($handle);
} else {
echo "error";
}
This is working well so far. But I need to split the array into chunks, because otherwise the array is too big to work with it:
$properties_chunk = array_chunk($properties,10000,true);
But now I have the problem that the $properties_chunk array is not created. The system crashes. This is too much. But what can I do now?
The array should look like this in the end:
array(4) {
[0]=>
array(10000) {
["12345"]=>
array(5) {
["dateTime"]=>
string(19) "2016-10-12 19:46:25"
["fileName"]=>
string(46) "monkey.jpg"
["path"]=>
string(149) "Volumes/animals/monkey.jpg"
["size"]=>
string(7) "2650752"
}
["678790"]=>
array(5) {
["dateTime"]=>
string(19) "2016-10-12 14:39:43"
["fileName"]=>
string(45) "elephant.jpg"
["path"]=>
string(171) "Volumes/animals/elephant.jpg"
["size"]=>
string(7) "2306688"
}
... and so on.
If you use array_splice the items will be moved from the input array to the resulting array.
This should mean the memory use should stay the same-ish.
This will do the same as array_chunk but hopefully be less memory hungry.
$arr = [1,2,3,4,5,6,7,8,9,10];
$n = 10000;
$count = (count($arr)/$n)-1; // do not splice the last items in loop
For($i=0; $i<$count; $i++){
$res[] = array_splice($arr, 0,$n);
}
$res[] = array_splice($arr, 0,count($arr));
// here we splice the last items from arr to $res.
// Notice how we splice count($arr) instead of $n.
// If count($arr) == $n we could have done it in the loop.
// But if we assume they are not, array_splice in the loop will create empty items. This line will not.
Var_dump($res, $arr); // $res has all values, $arr is empty
https://3v4l.org/XDpdI

Movie Trailer Page views with Sessions PHP

Here is my problem..
I have Session with Array looking like this
array(3) { [0]=> array(1) { ["trailer"]=> array(1) { ["id"]=> string(5) "id-10" } } [1]=> array(1) { ["trailer"]=> array(1) { ["id"]=> string(5) "id-11" } } [2]=> array(1) { ["trailer"]=> array(1) { ["id"]=> string(5) "id-10" } } }
and an php method .. oh and 1 more thing, im using laravel 5.6
My Code:
public function updateTrailerViews($id = 1){
$trailerViews = array(array());
$trailerViewsCount = \Session::get('trailerViews') == NULL ? 1 : count(\Session::get('trailerViews'));
if($trailer['id'] == NULL){
$id = 1;
}
if (\Session::get('trailerViews') == NULL) {
for ($i=0; $i < $trailerViewsCount; $i++) {
$trailerViews[$i]['trailer']['id'] = 'id-'.$id;
//$trailer['views'] = $trailer['views']+1;
//$trailer->save();
}
\Session::put('trailerViews', $trailerViews);
}else{
for($i=0;$i<$trailerViewsCount;$i++){
if(\Session::get('trailerViews')[$i]['trailer']['id'] != 'id-'.$id){
$idNotExist = 'true';
}else{
$idNotExist = 'false';
}
}
if($idNotExist == 'true'){
$trailerViewsCount1 = $trailerViewsCount+1;
for($int=0;$int<$trailerViewsCount1;$int++){
if($int == $trailerViewsCount1-1){
// if is the last integer of the loop add the new record
$trailerViews[$int]['trailer']['id'] = 'id-'.$id;
}else{
for($int1 = 0; $int1 < $trailerViewsCount; $int1++){
// if the integer is not the last number of the loop add the previous records from the session
$trailerID = \Session::get('trailerViews')[$int1]['trailer']['id'];
$trailerViews[$int1]['trailer']['id'] = $trailerID;
}
}
\Session::put('trailerViews', $trailerViews);
}
}
}
$trailerViewsCountReturn = count(\Session::get('trailerViews'));
//$trailerViewsNumber = \AppHelper::instance()->short_number_format($trailer['views']);
return var_dump(\Session::get('trailerViews'));
}
The problem is when im trying to check the unique id of the page sometimes have a bug, when open page with id=2 then id=5 or other.. and again open id=2 the id is going to be added again.
I wanna make it with unique page id's only.
SOLVED!
public function updateTrailerViews($id = 1){
$trailer = Trailers::find($id);
$trailerViews = array(array());
$trailerViewsCount = \Session::get('trailerViews') == NULL ? 1 : count(\Session::get('trailerViews'));
if($trailer['id'] == NULL){
$id = 1;
}
if (\Session::get('trailerViews') == NULL) {
for ($i=0; $i < $trailerViewsCount; $i++) {
$trailerViews[$i] = 'id-'.$id;
$trailer['views'] = $trailer['views']+1;
$trailer->save();
}
\Session::put('trailerViews', $trailerViews);
}else{
if(!in_array('id-'.$id, \Session::get('trailerViews'))){
if($trailer['id'] == $id){
$idNotExist = 'true';
$trailer['views'] = $trailer['views']+1;
$trailer->save();
}else{
$idNotExist = 'false';
}
}else{
$idNotExist = 'false';
}
if($idNotExist == 'true'){
$trailerViewsCount1 = $trailerViewsCount+1;
for($int=0;$int<$trailerViewsCount1;$int++){
if($int == $trailerViewsCount1-1){
// if is the last integer of the loop add the new record
$trailerViews[$int] = 'id-'.$id;
}else{
for($int1 = 0; $int1 < $trailerViewsCount; $int1++){
// if the integer is not the last number of the loop add the previous records from the session
$trailerID = \Session::get('trailerViews')[$int1];
$trailerViews[$int1] = $trailerID;
}
}
$trailerViews = array_unique($trailerViews);
\Session::put('trailerViews', $trailerViews);
}
}
}
$trailerViewsCountReturn = count(\Session::get('trailerViews'));
$trailerViewsNumber = \AppHelper::instance()->short_number_format($trailer['views']);
return $trailerViewsNumber;
}

Array to associative array

I have an array like this :
array(3) {
[0]=>
array(2) {
[0]=>
string(6) "action"
[1]=>
string(5) "depot"
}
[1]=>
array(2) {
[0]=>
string(9) "Demandeur"
[1]=>
string(11) "Particulier"
}
[2]=>
array(2) {
[0]=>
string(3) "Nom"
[1]=>
string(6) "Cheval"
}
But I want an associative array, to access it like this : $_REQUEST['Nom'] and have in return 'Cheval' etc...
The first array is actually an object, created with jQuery and here is his construction :
jQuery('input:submit').click(function() {
var itemMetaArray = {};
jQuery('.frm_pro_form :input:not(:hidden, :submit)').each(function() {
if(jQuery('#field_demande').val() != undefined){
itemMetaArray['action'] = jQuery('#field_demande').val();
}
else itemMetaArray['action'] = jQuery('#field_demande2').val();
var label = jQuery(this).closest('.frm_form_field').find('.frm_primary_label').text().trim();
if(jQuery(this).attr('name').indexOf("file") == -1 ) {
itemMetaArray[label] = jQuery(this).val();
}else{
var fileName = jQuery(this).attr('name');
fileName = fileName.substring(0,fileName.length-2);
itemMetaArray[label] = fileName;
}
});
After this, I do some parsing in PHP :
$dataInfo = explode(",",$_POST['dataInfo']);
for ($i = 0; $i < count($dataInfo); ++$i){
$tmpWithoutBrackets[$i] = trim($dataInfo[$i],"{..}");
$tmpWithoutColon[$i] = explode(":",$tmpWithoutBrackets[$i]);
for($j = 0; $j < (count($tmpWithoutColon) + 1); ++$j){
$arrayFinal[$i][$j] = trim($tmpWithoutColon[$i][$j],"\"");
}
$arrayFinal[$i] = array_diff($arrayFinal[$i],array(""));
}
$arrayFinal is the same array as arrayInfo
Thanks in advance for your help
You need to modify your array like this:
$test = array('arrayInfo' => array(array('Nom','Cheval'),array('Prenom','Nathan'),array('Adresse postale','4 impasse Molinas')),'arrayFile' => array(array ('application/pdf','3a514fdbd3ca2af35bf8e5b9c3c80d17','JVBERi0xLjUNCiW1tbW1DQoxIDAgb2JqDQo8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFIvTGFuZyhmci1GUikgL1N0cnVjdFRyZWVSb290IDI2IDAgUi9NYXJrSW5mbzw8L01hcmtlZCB0cnVlPj4vTWV0')));
$result = array();
foreach($test as $k=>$t){
$count = 0;
$_key = '';
$_value = '';
foreach($t as $f){
foreach($f as $final){
$count++;
if($count%2!==0){
$_key = $final;
}
else{
$_value = $final;
}
if($_value!==''){
$result[$k][$_key] = $_value;
$_value = '';
}
}
}
}
echo $result['arrayInfo']['Nom'];//Cheval
For your modified question, answer will be a little changed ofcourse:
$test = array(array('Nom','Cheval'),array('Prenom','Nathan'),array('Adresse postale','4 impasse Molinas'));
$result = array();
foreach($test as $k=>$t){
$count = 0;
$_key = '';
$_value = '';
foreach($t as $final){
$count++;
if($count%2!==0){
$_key = $final;
}
else{
$_value = $final;
}
if($_value!==''){
$result[$_key] = $_value;
$_value = '';
}
}
}
var_dump($result);
echo $result['Nom'];//Cheval
I hope it helps

How can I turn a value of an array into the key of an array?

I am parsing a text file that looks more or less like this:
123.animal=cat
123.name=fred
123.food=fish
345.animal=dog
petshop=zoonoria
This is how I am parsing it:
$file_path = $filename;
$linesArray = file($file_path);
$properties = array();
foreach ($linesArray AS $line) {
if (strlen($line) && $line[0] == '#') {
$pdate = substr($line, 1);
$date = rtrim($pdate);
$formatted = DateTime::createFromFormat('* M d H:i:s T Y',$date);
}
if (false !== ($pos = strpos($line, '='))) {
$prop=array();
$prop[trim(substr($line, 0, $pos))] = trim(substr($line, $pos + 1));
$lineContArray = explode("=", $line);
$identArray = explode(".", $lineContArray[0]);
$ident = $identArray[0];
$type = $identArray[1];
$value = trim($lineContArray[1]);
$found = 0;
for ($i=0; $i<count($properties); $i++) {
if ($properties['number'] == $ident) {
$properties[$i][$type]= $value;
$found=1;
break;
}
}
if ($found == 0) {
if (!empty($type)) {
$properties[] = array('number' => $ident, $type => $value);
} else {
$properties[] = array($ident => $value); }
}
}
My result is:
array(3) {
[0]=>
array(2) {
["number"]=>
string(3) "123"
["animal"]=>
string(3) "cat"
}
[1]=>
array(2) {
["number"]=>
string(3) "123"
["name"]=>
string(4) "fred"
}
[3]=>
array(2) {
["number"]=>
string(3) "345"
["animal"]=>
string(4) "dog"
}
[4]=>
array(1) {
["petshop"]=>
string(5) "zoonoria"
}
}
But I need the array to be different, this is the result I like to achieve:
array(3) {
[123]=>
array(3) {
["animal"]=>
string(3) "cat"
["name"]=>
string(4) "fred"
["food"]=>
string(4) "fish"
}
[345]=>
array(1) {
["animal"]=>
string(3) "dog"
}
[petshop]=>
string(8) "zoonoria"
}
}
So my main problem is, I do not know how to turn number into the key. I tried various things, but I failed. I am really happy for every hint.
I tried the solution of Svetlio:
$file_path = $filename;
$linesArray = file($file_path);
$properties = array();
foreach ( $linesArray as $str) {
$exp = explode ('=', $str);
if(count($exp) == 2){
$exp2 = explode('.', $exp[0]);
if( count($exp2) == 2 ) {
$properties [$exp2[0]][$exp2[1]] = $exp[1];
} else {
$properties [$exp[0]] = $exp[1];
}
} else {
}
}
My result:
array(3) {
["123"]=>
array(3) {
["animal"]=>
string(3) "cat
"
["name"]=>
string(4) "fred
"
["food"]=>
string(4) "fish
"
}
[345]=>
array(1) {
["animal"]=>
string(3) "dog
"
}
["petshop"]=>
string(3) "zoonoria
"
}
Here is working solution but it doesn't cover the cases where stings don't contain = or have more than 1 of them..
$strings = array(
'123.animal=cat',
'123.name=fred',
'123.food=fish',
'345.animal=dog',
'petshop=zoonoria'
);
$array = array();
foreach ( $strings as $str) {
// I accept that there is 1 = at strings possible
$exp = explode ('=', $str);
if(count($exp) == 2){
$exp2 = explode('.', $exp[0]);
if( count($exp2) == 2 ) {
$array[$exp2[0]][$exp2[1]] = $exp[1];
} else {
// if there are multiple/null dots i set the string as key
$array[$exp[0]] = $exp[1];
}
} else {
// what to do if there are no or many = = = in the string ?
}
}
var_dump($array);
After getting the result you can use array_reduce to get the desired result
$result = array_reduce($initialArray, function ($result, $item) {
$number = isset($item['number']) ? $item['number'] : end(array_keys($result));
if (!isset($result[$number])) {
$result[$number] = array();
}
foreach ($item as $key => $value) {
if ($key == 'number') continue;
$result[$number][$key] = $value;
}
return $result;
}, array());
foreach ($linesArray AS $line) {
if (strlen($line) && $line[0] == '#') {
$pdate = substr($line, 1);
$date = rtrim($pdate);
$formatted = DateTime::createFromFormat('* M d H:i:s T Y',$date);
}
if (false !== ($pos = strpos($line, '='))) {
$prop=array();
$prop[trim(substr($line, 0, $pos))] = trim(substr($line, $pos + 1));
$lineContArray = explode("=", $line);
$identArray = explode(".", $lineContArray[0]);
$ident = $identArray[0];
$type = $identArray[1];
$value = trim($lineContArray[1]);
$found = 0;
for ($i=0; $i<count($properties); $i++) {
if ($properties['number'] == $ident) {
$properties[$i][$type]= $value;
$found=1;
break;
}
}
if ($found) {
if ($type && $ident) {
$properties[$ident][$type] = $value;
} else if (!$type && $ident) {
$properties[$ident][] = $value;
}else if ($type && !$ident){
$properties[$type][] = $value;
}
}
$data = '123.animal=cat
123.name=fred
123.food=fish
345.animal=dog
petshop=zoonoria';
$ini = parse_ini_string($data);
$result = [];
foreach ($ini as $key => $value) {
$splitKey = explode('.', $key);
$iniPtr = &$result;
foreach($splitKey as $subKey) {
if (!isset($iniPtr[$subKey])) { $iniPtr[$subKey] = null; }
$iniPtr = &$iniPtr[$subKey];
}
$iniPtr = $value;
}
unset($iniPtr);
var_dump($result);
Demo
In your case, use $ini = parse_ini_file($file_path); to read your file data into $ini

Categories