How can I change the keys from an array? - php

I created an array in Zend Framework where I need to change some keys.
The keys are now incremented by a integer I need to increment them somehow different.
I have the following code:
public function turnoverAction()
{
$arrayTurnover = array();
$selectDebiteur = $this->tableDebiteuren->select("debiteur_id","debiteur_nummer","bedrijf_id")
->setIntegrityCheck(false)
->where('debiteur_id = 3');
$debiteur = $this->tableDebiteuren->fetchRow($selectDebiteur);
$selectverkoopHoofdpost = $this->tableVerkoopHoofdpost->select("*")
->setIntegrityCheck(false);
$verkoopHoofdposten = $this->tableVerkoopHoofdpost->fetchAll($selectverkoopHoofdpost);
$currentYear = (int)date('Y');
$amountOfYearsToShow = $currentYear - 5 + 1;
for($amountOfYearsToShow; $amountOfYearsToShow <= $currentYear; $amountOfYearsToShow++)
{
$amountOfYearsToShowBegin = $amountOfYearsToShow.'-01-01';
$amountOfYearsToShowEnd = $amountOfYearsToShow.'-12-31';
$arrayYear = array();
$totaal = 0;
foreach($verkoopHoofdposten as $verkoopHoofdpost)
{
$selectverkoopSubpost = $this->tableVerkoopSubpost->select("*")
->setIntegrityCheck(false)
->joinLeft('verkoopPost','verkoopPost.verkoopSubpost_id = verkoopSubpost.verkoopSubpost_id')
->joinLeft('verkoop_verkoopPost','verkoop_verkoopPost.verkoopPost_id = verkoopPost.verkoopPost_id')
->joinLeft('verkopen','verkopen.verkoop_id = verkoop_verkoopPost.verkoop_id')
->where('verkopen.debiteur_nummer = ' . $debiteur['debiteur_nummer'])
->where('verkopen.verkoop_factuurdatum > ? ', $amountOfYearsToShowBegin)
->where('verkopen.verkoop_factuurdatum < ? ', $amountOfYearsToShowEnd)
->where('verkoopHoofdpost_id = ' . $verkoopHoofdpost['verkoopHoofdpost_id']);
$verkoopSubposten = $this->tableVerkoopSubpost->fetchAll($selectverkoopSubpost);
$totaal_hoofdpost = 0;
foreach($verkoopSubposten as $verkoopSubpost)
{
$totaal_hoofdpost += $verkoopSubpost['verkoopPost_verkoopsom'];
}
$totaal += $totaal_hoofdpost;
$turnoverValues['post']['totaal_hoofdpost'] = number_format($totaal_hoofdpost, 2, ',', '.');
$turnoverValues['post']['hoofdpost_omschrijving'] = $verkoopHoofdpost['verkoopHoofdpost_omschrijving'];
array_push($arrayYear, $turnoverValues);
}
$turnoverValue['totaal'] = number_format($totaal, 2, ',', '.');
array_push($arrayYear, $turnoverValue);
array_push($arrayTurnover, $arrayYear);
unset($arrayYear);
}
var_dump($arrayTurnover);
}
This returns the following output:
array(2) {
[0]=>
array(2) {
[0]=>
array(1) {
["post"]=>
array(2) {
["totaal_hoofdpost"]=>
string(6) "value"
["hoofdpost_omschrijving"]=>
string(4) "value"
}
}
[1]=>
array(1) {
["post"]=>
array(2) {
["totaal_hoofdpost"]=>
string(5) "value"
["hoofdpost_omschrijving"]=>
string(8) "value"
}
}
}
[1]=>
array(2) {
[0]=>
array(1) {
["post"]=>
array(2) {
["totaal_hoofdpost"]=>
string(6) "value"
["hoofdpost_omschrijving"]=>
string(4) "value"
}
}
[1]=>
array(1) {
["post"]=>
array(2) {
["totaal_hoofdpost"]=>
string(5) "value"
["hoofdpost_omschrijving"]=>
string(8) "value"
}
}
}
}
I however need the following output:
array(2) {
[2009]=>
array(2) {
["post"]=>
array(1) {
["totaal_hoofdpost"]=>
string(6) "value"
["hoofdpost_omschrijving"]=>
string(4) "value"
}
["post"]=>
array(1) {
["totaal_hoofdpost"]=>
string(5) "value"
["hoofdpost_omschrijving"]=>
string(8) "value"
}
}
[2010]=>
array(2) {
["post"]=>
array(1) {
["totaal_hoofdpost"]=>
string(6) "value"
["hoofdpost_omschrijving"]=>
string(4) "value"
}
["post"]=>
array(1) {
["totaal_hoofdpost"]=>
string(5) "value"
["hoofdpost_omschrijving"]=>
string(8) "value"
}
}
}
Is this somehow possible?

Its better to use direct array assignment rather than using array_push.
In your case, you may only had to replace array_push($arrayTurnover, $arrayYear); and put something like
$arrayTurnover[$amountOfYearsToShow] = $arrayYear;
I hope this will help.

Related

Assigning specific element of multidimensional array in url in php

My goal is to get specific element/value from a multidimensional array and assign them in a URL in loop. I have already tried and was able to get elements in the array but this displays all elements. I only want to get specific, like nid and field_x values.
This is my link structure: http://localhost:8080/$nid/$field_x
Expected result:
http://localhost:8080/123/one
http://localhost:8080/789/three
This is my sample var_dump result
array(1) {
[0]=>
array(38) {
["nid"]=>
array(1) {
[0]=>
array(1) {
["value"]=>
int(123)
}
}
["vid"]=>
array(1) {
[0]=>
array(1) {
["value"]=>
int(456)
}
}
["field_x"]=>
array(1) {
[0]=>
array(4) {
["target_id"]=>
string(6) "One"
}
}
["field_y"]=>
array(1) {
[0]=>
array(4) {
["target_id"]=>
string(2) "Two"
}
}
}
[1]=>
array(38) {
["nid"]=>
array(1) {
[0]=>
array(1) {
["value"]=>
int(789)
}
}
["vid"]=>
array(1) {
[0]=>
array(1) {
["value"]=>
int(321)
}
}
["field_x"]=>
array(1) {
[0]=>
array(4) {
["target_id"]=>
string(6) "Three"
}
}
["field_y"]=>
array(1) {
[0]=>
array(4) {
["target_id"]=>
string(2) "Four"
}
}
}
}
You can use a foreach() and get the data using $values['nid'][0]['value'] or $values['field_x'][0]['target_id']:
foreach ($result as $values) {
$nid = $values['nid'][0]['value'];
$field_x = $values['field_x'][0]['target_id'];
echo "http://localhost:8080/$nid/$field_x" ;
}
Will outputs:
http://localhost:8080/123/One
http://localhost:8080/789/Three
You probably want to do something else than an echo, so you can create a new array:
$urls = [];
foreach ($result as $values) {
$nid = $values['nid'][0]['value'];
$field_x = $values['field_x'][0]['target_id'];
$urls[] = "http://localhost:8080/$nid/$field_x" ;
}
print_r($urls);

Output and use array elements from a REST Api call in php

I am calling a REST Api to get data using curl in php. It gives me the list of data/contents in the api in Array php format.
I was able to get single element value using $resultArray[0]['nid'][0]['value'];. But my goal is to get elements in all contents in the api.
Say I want to get the following elements in the nested arrays.
$resultArray[0]['nid'][0]['value'];
$resultArray[0]['vid'][0]['value'];
$resultArray[0]['cid'][0]['value'];
And use these values in a loop too.
I am trying to search how I can do it loop, and if anyone can provide sample code, that would be appreciated.
Update:
This is the sample result of var_dump:
array(1) {
[0]=>
array(38) {
["nid"]=>
array(1) {
[0]=>
array(1) {
["value"]=>
int(1)
}
}
["vid"]=>
array(1) {
[0]=>
array(1) {
["value"]=>
int(2)
}
}
["cid"]=>
array(1) {
[0]=>
array(1) {
["value"]=>
int(3)
}
}
["field"]=>
array(1) {
[0]=>
array(4) {
["target_id"]=>
int(4)
}
}
}
[1]=>
array(38) {
["nid"]=>
array(1) {
[0]=>
array(1) {
["value"]=>
int(11)
}
}
["vid"]=>
array(1) {
[0]=>
array(1) {
["value"]=>
int(22)
}
}
["cid"]=>
array(1) {
[0]=>
array(1) {
["value"]=>
int(33)
}
}
["field"]=>
array(1) {
[0]=>
array(4) {
["target_id"]=>
int(44)
}
}
}
[2]=>
array(38) {
["nid"]=>
array(1) {
[0]=>
array(1) {
["value"]=>
int(111)
}
}
["vid"]=>
array(1) {
[0]=>
array(1) {
["value"]=>
int(222)
}
}
["cid"]=>
array(1) {
[0]=>
array(1) {
["value"]=>
int(333)
}
}
["field"]=>
array(1) {
[0]=>
array(4) {
["target_id"]=>
int(444)
}
}
}
}
And I want to use these elements values in a loop.
Say my expected result is.
Test1 = "1", "2", "3"
Test2 = "11", "22", "33"
Test3 = "111", "222", "333"
These equivalent numbers should be comming from the element nid, vid, cid.
I dont just want to assign/echo these values in the result as I have array[100s] in one api call.
Since your array is a multidimensional array, you need to have nested foreach loops:
$test = 1;
foreach ($resultArray as $items) {
// Echo the current test number
echo "Test{$test} = ";
$values = [];
foreach ($items as $item) {
// Get the correct value.
if (array_key_exists('value', $item[0])) {
$values[] = $item[0]['value'];
continue;
}
if (array_key_exists('target_id', $item[0])) {
$values[] = $item[0]['target_id'];
continue;
}
}
echo '"' . implode('", "', $values) . '"' . "\n";
$test++;
}
Demo: https://3v4l.org/fnHlV

PHP: Combining data with a shared key from a single array into new array

I have this array:
array(5) {
[0]=>
array(4) {
["productCode"]=>
string(4) "X001"
["productUPC"]=>
string(3) "261"
["productTextSeq"]=>
string(1) "1"
["productTxtVal"]=>
string(5) "Text1"
}
[1]=>
array(4) {
["productCode"]=>
string(4) "X001"
["productUPC"]=>
string(3) "261"
["productTextSeq"]=>
string(1) "2"
["productTxtVal"]=>
string(5) "Text2"
}
[2]=>
array(4) {
["productCode"]=>
string(4) "X001"
["productUPC"]=>
string(3) "261"
["productTextSeq"]=>
string(1) "3"
["productTxtVal"]=>
string(5) "Text3"
}
[3]=>
array(4) {
["productCode"]=>
string(4) "X002"
["productUPC"]=>
string(3) "262"
["productTextSeq"]=>
string(1) "1"
["productTxtVal"]=>
string(5) "Text1"
}
[4]=>
array(4) {
["productCode"]=>
string(4) "X002"
["productUPC"]=>
string(3) "262"
["productTextSeq"]=>
string(1) "2"
["productTxtVal"]=>
string(5) "Text2"
}
}
With the above input, I want the output array to look like this:
array(2) {
[0]=>
array(3) {
["productCode"]=>
string(4) "X001"
["productUPC"]=>
string(3) "261"
["productTxtVal"]=>
string(17) "Text1 Text2 Text3"
}
[1]=>
array(3) {
["productCode"]=>
string(4) "X002"
["productUPC"]=>
string(3) "262"
["productTxtVal"]=>
string(11) "Text1 Text2"
}
}
The resulting array does not need the productTextSeq key, just the combined values of productTextVal, when the productCode is the same. I've searched SO for examples of this but it seems every example I've found are based on multiple input arrays. I know I can brute force this with nested foreach functions but would love a more elegant solution.
I ended up just doing it the brute force method, here is my solution if anyone's interested:
$productData = array();
$sortedData = array();
$comments = '';
$saveKey = '';
$appendComment = false;
$idx = 0;
foreach ($data as $key=>$value) {
foreach ($value as $k=>$v) {
if ($k == 'productCode') {
if ($v == $saveKey) {
$appendComment = true;
} else {
$appendComment = false;
$saveKey = $v;
if ($idx !== 0) { // Don't write to array on first iteration!
$productData['productTxtVal'] = $comments;
$sortedData[] = $productData;
}
}
}
if ($k == 'productTxtVal') {
if ($appendComment == true) {
$comments .= ' ' . trim($v);
} else {
$comments = trim($v);
}
}
}
$productData = $value;
$idx++;
}
Not "elegant" but it works. I also have a check after this logic in case only one productCode is in the original array, as it won't be written to the $sortedData array since the key never changes.
The following code assumes you control the contents of the original data array (due to risk of injection using extract() function) and that no 2 items with the same productCode have the same productTextSeq.
$products = [];
foreach ($data as $item) {
// extract contents of item array into variables
extract($item);
if (!isset($products[$productCode])) {
// create product array with code, upc, text as array
$products[$productCode] = compact('productCode', 'productUPC') + ['productTxtVal' => []];
}
// add text value to array with sequence as index
$products[$productCode]['productTxtVal'][$productTextSeq] = $productTxtVal;
}
$products = array_values( // ignore array keys
array_map(function($product) {
ksort($product['productTxtVal']); // sort text as array by index/ sequence
$product['productTxtVal'] = implode(' ', $product['productTxtVal']); // implode into string
return $product;
}, $products)
);
You can run the code here: https://repl.it/BWQL

Invalid argument for FOR EACH loop

I'm getting an error on a for each loop, saying that it get's invalid argument.
$bidder = new MuxBidder( $mailer->bidder_id );
$today = $bidder->getTodayBoughtLeads();
$legum = $bidder->getLegum();
$zipInterval = $bidder->getMeta('zip-intervals');
var_dump($bidder->getMeta('zip-intervals'));
$region = $lead->getRegion();
$zip = $lead->getZip();
// If "revisor"
if ( !$legum ) {
if( $lead->getPrice( $bidder->getId() ) >= $bidder->getMeta( 'min_clips' ) ) {
foreach ($zipInterval as $interval) {
if ($interval['from'] <= $zip && $zip <= $interval['to']) {
// "revisor" just get the lead straight away
$this->push_lead( $mailer->lead_id, $mailer->bidder_id );
return true;
}
}
}
// If Legum user ("advokat")
}
The error appears with $zipInterval. When I var_dump that variable I have:
array(1) {
[0]=> array(2) {
["from"]=> string(4) "0000" ["to"]=> string(4) "9999"
}
}
array(1) {
[0]=> array(2) {
["from"]=> string(4) "1000" ["to"]=> string(4) "9999"
}
}
array(1) {
[0]=> array(2) {
["from"]=> string(4) "1000" ["to"]=> string(4) "9999"
}
}
array(2) {
[0]=> array(2) {
["from"]=> string(4) "0000" ["to"]=> string(4) "9999"
}
[1]=> array(2) {
["from"]=> string(0) "" ["to"]=> string(0) ""
}
}
string(0) ""
Can anybody see what's wrong with the argument ?
Looks like you call this function more than once? On the last loop you get an empty string returned instead of an array.
try checking if the value is an array before iterating.
<?php
if(is_array($zipInterval)){
foreach($zipInterval as $interval){
//...
}
}

Reverse array in php

array(7) {
[0]=> array(2) { ["id"]=> string(1) "9" ["roi"]=> float(0) }
[1]=> array(2) { ["id"]=> string(1) "1" ["roi"]=> float(0) }
[2]=> array(2) { ["id"]=> string(2) "10" ["roi"]=> float(0) }
[3]=> array(2) { ["id"]=> string(2) "14" ["roi"]=> float(0) }
[4]=> array(2) { ["id"]=> string(1) "4" ["roi"]=> float(0) }
[5]=> array(2) { ["id"]=> string(1) "5" ["roi"]=> float(141) }
[6]=> array(2) { ["id"]=> string(1) "6" ["roi"]=> float(2600) }
}
I would just like to reverse this, so id 6 (with roi of 2600) comes first in the array etc.
How can I do this? array_reverse() and rsort() does not work in this case
http://php.net/manual/en/function.array-reverse.php:
$newArray = array_reverse($theArray, true);
The important part is the true parameter, which preserves the keys.
Not convinced? You can see it in action on this codepad exampole.
foreach($array as $arr){
array_unshift($array, $arr);
array_pop($array);
}
$res = array(
0=>array("id"=>9, "roi"=>0),
1=>array("id"=>1,"roi"=>0),
2=>array("id"=>10,"roi"=>0),
3=>array("id"=>14,"roi"=>0),
4=>array("id"=>4,"roi"=>0),
5=>array("id"=>5,"roi"=>141),
6=>array("id"=>6,"roi"=>2600));
$res4 = array();
$count = count($res);
for($i=$count-1;$i>=0;$i--){
$res4[$i] =$res[$i];
}
print_r($res4);
You can use an usort() function, like so
$arr = array('......'); // your array
usort($arr, "my_reverse_array");
function my_reverse_array($a, $b) {
if($a['roi'] == $b['roi'])
{
return 0;
}
return ($a['roi'] < $b['roi']) ? -1 : 1;
}
This will make sure the item with the highest roi is first in the array.
$res = array(
0=>array("id"=>9, "roi"=>0),
1=>array("id"=>1,"roi"=>0),
2=>array("id"=>10,"roi"=>0),
3=>array("id"=>14,"roi"=>0),
4=>array("id"=>4,"roi"=>0),
5=>array("id"=>5,"roi"=>141),
6=>array("id"=>6,"roi"=>2600));
$count = count($res);
for ($i=0, $j=$count-1; $i<=floor($count/2); $i++, $j--) {
$temp = $res[$j];
$res[$j] = $res[$i];
$res[$i] = $temp;
}
echo '<pre>';
print_r($res);
echo '</pre>';
It's easy. May be use usort function of php like:
usort($arr, function($a, $b) {
return $b['roi'] - $a['roi'];
});
Just swap position $a and $b that is correct.

Categories