Using foreach inside of a defined array PHP - php

Is there anyway to loop through an array and insert each instance into another array?
$aFormData = array(
'x_show_form' => 'PAYMENT_FORM',
foreach($aCartInfo['items'] as $item){
'x_line_item' => $item['id'].'<|>'.$item['title'].'<|>'.$item['description'].'<|>'.$item['quantity'].'<|>'.$item['price'].'<|>N',
}
);

Not directly in the array declaration, but you could do the following:
$aFormData = array(
'x_show_form' => 'PAYMENT_FORM',
'x_line_item' => array(),
);
foreach($aCartInfo['items'] as $item){
$aFormData['x_line_item'][] = $item['id'].'<|>'.$item['title'].'<|>'.$item['description'].'<|>'.$item['quantity'].'<|>'.$item['price'].'<|>N';
}

Yes, there is a way ; but you must go in two steps :
First, create your array with the static data
And, then, dynamically add more data
In your case, you'd use something like this, I suppose :
$aFormData = array(
'x_show_form' => 'PAYMENT_FORM',
'x_line_item' => array(), // right now, initialize this item to an empty array
);
foreach($aCartInfo['items'] as $item){
// Add the dynamic value based on the current item
// at the end of $aFormData['x_line_item']
$aFormData['x_line_item'][] = $item['id'] . '<|>' . $item['title'] . '<|>' . $item['description'] . '<|>' . $item['quantity'] . '<|>' . $item['price'] . '<|>N';
}
And, of course, you should read the section of the manual that deals with arrays : it'll probably help you a lot ;-)

You mean something like this :
$aFormData = array(
'x_show_form' => 'PAYMENT_FORM',
'x_line_item' => array(),
);
foreach($aCartInfo['items'] as $item) {
$aFormData['x_line_item'][] = implode('<|>', $aCartInfo['items']).'<|>N',
}

Related

Insert php variable inside array

I have a filter for the CPT and I need to manually type all custom taxonomy names inside the array():
sc_render_filter(
'test',
'All Categories',
array( 'Category One', 'Category two', 'Category three'),
''
. ($current_sub_brand ? ( 'sub_brand=' . $current_sub_brand . '&' ) : '' )
. ($current_varietal ? ( 'varietal=' . $current_varietal . '&' ) : '' )
. ($current_publication ? ( 'publication=' . $current_publication . '&' ) : '' )
. ($current_vintage ? ( 'vintage=' . $current_vintage . '&' ) : '' )
);
Is it possible somehow to use the variable or foreach loop inside array() to automatically generate terms or names? Or maybe I need another approach?
This is what I have in foreach:
$source = '';
foreach ($termslist as $term) {
$source .= "'". $term->name. "'". ',';
}
echo rtrim($source, ',');
Unfortuntely for your project, it is appropriate to use variable variables (which I do not typically endorse). Using variable variables is a symptom that array data is not properly stored as such. The fact that you have individual $current_ variables looks to be an earlier problem to address.
In the meantime, you can loop through the know keys and dynamically access these variables. When finished, call http_build_query() to cleanly, reliably generate a url querystring string.
Code: (Demo)
$keys = ['sub_brand', 'varietal', 'publication', 'vintage'];
$data = [];
foreach ($keys as $key) {
$data[$key] = ${'current_' . $key};
}
$queryString = http_build_query($data);
sc_render_filter(
'test',
'All Categories',
['Category One', 'Category two', 'Category three'],
$queryString
);
The querystring string looks like this:
sub_brand=foo&varietal=bar&publication=boo&vintage=far

How can I make HTML data attributes string from a nested array in PHP?

Some time ago I had to parse nested data attributes to a JSON, so I found a JS solution here on SO. Eg.:
data-title="Title" data-ajax--url="/ajax/url" data-ajax--timeout="10" data-ajax--params--param-1="Param 1"
to
['title' => 'Title', 'ajax' => ['url' => '/ajax/url', 'timeout' => 10, 'params' => ['param-1' => 'Param 1']]]
So now I need a reverse action in PHP. I need to make attributes string from nested array to use it later in HTML. There can be infinite levels.
I've tried recursive functions. Tried recursive iterators. Still no luck. I always lose top level keys and get something like data-ajax--url=[...] --timeout=[...] --param-1=[...] (missing -ajax part) and so on. The part I can't get is the keys - getting values is easy. Any advice would be welcome.
This can be achieved with some simple concepts like loop,
recursive function and static variable.
Use of static variables is very important here since they remember the last modified value within the function's last call.
Within the loop, we are checking if the currently traversed value is an array.
If it's an array, we are modifying the prefix with the current key and calling the recursive function and .
If not, we are simply concatenating the prefix with the present key.
Try this:
$data = ['title' => 'Title', 'ajax' => ['url' => '/ajax/url', 'timeout' => 10, 'params' => ['param-1' => 'Param 1']]];
function formatter($data = array()) {
static $prefix = 'data-';
static $attr_string = '';
foreach($data as $key => $value) {
if (is_array($value)) {
$prefix .= $key.'--';
formatter($value);
} else {
$attr_string .= $prefix.$key.'="'.$value.'" ';
}
}
return $attr_string;
}
echo formatter($data);
Output:
data-title="Title" data-ajax--url="/ajax/url" data-ajax--timeout="10" data-ajax--params--param-1="Param 1"
So after almost 6 hours of trying to figure this out and lots of searches, also with some hints from Object Manipulator, I found this answer on SO and just had to adapt it to my needs:
function makeDataAttributes(array $attributes)
{
$rs = '';
$iterator = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($attributes));
foreach ($iterator as $key => $value) {
for ($i = $iterator->getDepth() - 1; $i >= 0; $i--) {
$key = $iterator->getSubIterator($i)->key() . '--' . $key;
}
$rs .= ' data-' . $key . '="' . $iterator->current() . '"';
}
return trim($rs);
}
Thanks everyone for your comments. It helped me to define my search more clearly. Also got some new knowledge about iterators.

Stop getting duplicate rows on 'saveAll' in CakePHP

In CakePHP when I save the data with the below code, I get the data being saved as expected but I get all the data saved 2 times. The $lesson data variable does not retrieve 2 copies of the data so the save function is the problem. I tried using save in a loop and that gives the same problem. There must be something simple I am doing wrong.
http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-save-array-data-null-boolean-validate-true-array-fieldlist-array
$data=array();
$i=0;
$this->Lessondata->cacheQueries = false;
$this->Lessondata->create( );
foreach ($lessons as $item):
// $this->Lessondata->cacheQueries = false;
$data[$i]['Lessondata']['lesson_id']=$item['Lesson']['id'];
$data[$i]['Lessondata']['st_id']=$item['Student']['id'];
$data[$i]['Lessondata']['tutor_id']=$item['Tutor']['id'];
$data[$i]['Lessondata']['student_name']=$item['Student']['first_name'].' '.$item['Student']['last_name'];
$data[$i]['Lessondata']['subject']=$item['Subject']['name'];
$data[$i]['Lessondata']['tutor_name']=$item['Tutor']['first_name'].' '.$item['Tutor']['last_name'];
$data[$i]['Lessondata']['class_year']=$item['Student']['class_year'];
// debug($data[$i]);
debug($i);
$i=$i+1;
endforeach;
$this->Lessondata->saveAll($data);
Try it.
$data = array();
foreach ($lessons as $item):
$data['Lessondata'][] = array(
'lesson_id' => $item['Lesson']['id'],
'st_id' => $item['Student']['id'],
'tutor_id' => $item['Tutor']['id'],
'student_name' => $item['Student']['first_name'] . ' ' . $item['Student']['last_name'],
'subject' => $item['Subject']['name'],
'tutor_name' => $item['Tutor']['first_name'] . ' ' . $item['Tutor']['last_name'],
'class_year' => $item['Student']['class_year'],
);
endforeach;
$this->Lessondata->create();
$this->Lessondata->saveAll($data);
This works but I need to check when the duplication starts. This is a bad answer as I am allowing for a quirk. As yet there is no other answer. I am happy to take this down if someone provides a working answer.
$this->Lessondata->create();
foreach ($lessons as $item):
$ff = $this->Lessondata->find('first', array(
'conditions' => array('Lessondata.lesson_id' => $item['Lesson']['id'])
));
if (!empty($ff)) {
debug($item);
break;
}
$data[$i]['Lessondata']['lesson_id'] = $item['Lesson']['id'];
$data[$i]['Lessondata']['st_id'] = $item['Student']['id'];
$data[$i]['Lessondata']['tutor_id'] = $item['Tutor']['id'];
$data[$i]['Lessondata']['student_name'] = $item['Student']['first_name'].' '.$item['Student']['last_name'];
$data[$i]['Lessondata']['subject'] = $item['Subject']['name'];
$data[$i]['Lessondata']['tutor_name'] = $item['Tutor']['first_name'].' '.$item['Tutor']['last_name'];
$data[$i]['Lessondata']['class_year'] = $item['Student']['class_year'];
$i = $i+1;
endforeach;
debug($data);
$this->Lessondata->saveAll($data);

Using foreach in conjunction with a multi-dimensional array(?)

I am trying to use Simple HTML DOM to cycle through an HTML file and find all HREF links that contain the string "/en/news/". For each of these values in this initial array, I want to give certain attributes as seen below.
foreach($html->find('a[href^="/en/news/"]') as &$a) {
$arrayz = array(
'hyperLink' => 'http://samplewebsite.com' . $a->href,
'fileName' => str_replace("-", "", filter_var($a, FILTER_SANITIZE_NUMBER_INT)) . ".txt",
'processedTime' => date_default_timezone_get()
);
}
echo '<pre>', print_r($arrayz), '</pre>';
However, this is only printing the hyperLink, filename, and processedTime values for a SINGLE member of the initial array.
How can I make this work for all members of the initial array?
Thanks!
You are overwriting a single array inside the loop, try this:
foreach($html->find('a[href^="/en/news/"]') as &$a) {
$arrayz[] = array(
'hyperLink' => 'http://samplewebsite.com' . $a->href,
'fileName' => str_replace("-", "", filter_var($a, FILTER_SANITIZE_NUMBER_INT)) . ".txt",
'processedTime' => date_default_timezone_get()
);
}
echo '<pre>', print_r($arrayz), '</pre>';

Three dimension array

I'm trying to build a 3 dimension array with the following code :
while ($Inf = $queryPrep->fetch(PDO::FETCH_OBJ)) {
$cie_Names = array(
$Inf->dp_id=>array(
'name'=> $Inf->dp_desc,
'enabled'=>$Inf->dp_enabled));
}
Unfortunatly, this code was only returning the last record, so I chaged for :
$cie_Names = array();
while ($Inf = $queryPrep->fetch(PDO::FETCH_OBJ)) {
$cie_Names = [$Inf->dp_id]=>array(
'name'=> $Inf->dp_desc,
'enabled'=>$Inf->dp_enabled);
}
But now I'm getting a error.
I'll need to call my array later this way :
foreach ($depts as $ID => $DeptDetail) {
$optlist .= '<option value=' . $ID . '>' . $DeptDetail['name'] . $DeptDetail['enabled'] . '</option>';
}
You add a new element to an array by assigning to arrayName[]:
while ($Inf = $queryPrep->fetch(PDO::FETCH_OBJ)) {
$cie_Names[] = array(
$Inf->dp_id=>array(
'name'=> $Inf->dp_desc,
'enabled'=>$Inf->dp_enabled
)
);
}
However, this seems like a poor array layout -- each element of the cie_Names array will be an associative array with a different key; accessing them will be difficult because you won't know how the keys map to array indexes, you'll have to do a loop to find anything. What would probably be more useful is:
while ($Inf = $queryPrep->fetch(PDO::FETCH_OBJ)) {
$cie_Names[$Inf->dp_id] = array(
'name'=> $Inf->dp_desc,
'enabled'=>$Inf->dp_enabled
);
}
The keys of the cie_Names array will then by the dp_id values.

Categories