moving a numbered amount of named items from one array into another - php

I'm not exactly sure how the logic would work on this. My brain is fried and i cant think clearly.
I am handling some POST data, and one of the fields in this array is a quantity string. I can read this string and determine if there are more than 1 widgets that need handled.
if($quantity <= 1){ //$_POST[widget1] }
Now say there are 4 widgets. The quantity field would reflect this number, but how would i loop through them and assign them to a new array themselves?
$_POST[widget1], $_POST[widget2], $_POST[widget3], $_POST[widget4]
How do i take that quantity number, and use it to grab that many and those specific named items from the post array, using some kind of wild card or prefix or something? I dont know if this is a for, or while, or what kind of operation. How do I loop through $_POST['widget*X*'], where X is my quantity number?
The end result is im looking to have an array structured like this:
$widgets[data1]
$widgets[data2]
$widgets[data3]
$widgets[data4]

Using a for loop, you can access the $_POST keys with a variable, as in $_POST["widget$i"]
$widgets = array();
for ($i=1; $i<=$quantity; $i++) {
// Append onto an array
$widgets[] = $_POST["widget$i"];
}
However, a better long-term solution would be to change the HTML form such that it passes an array back to PHP in the first place by adding [] to the form input's name attribute:
<input type='text' name='widgets[]' id='widget1' value='widget1' />
<input type='text' name='widgets[]' id='widget2' value='widget2' />
<input type='text' name='widgets[]' id='widget3' value='widget3' />
Accessed in PHP via $_POST['widgets'], already an array!
var_dump($_POST['widgets']);

Iterate over the number of items, at least over one (as you describe it):
$widgets = array();
foreach (range(1, max(1, $quantity)) as $item)
{
$name = sprintf('widget%d', $item);
$data = sprintf('data%d', $item);
$widget = $_POST[$name];
// do whatever you need to do with that $widget.
$widgets[$data] = $widget;
}

Related

PHP - Get input from dynamically added html table rows

I have the following Fiddle set up here Fiddle
As you can see, I am able to add inputs by clicking the Add Row button.
All inputs that are added have a unique id and name. The problem is, I cant just do something like
$actionInput = $_POST["actionInput"];
Because I might need
$actionInput1 = $_POST["actionInput1"];
$actionInput2 = $_POST["actionInput2"];
$actionInput3 = $_POST["actionInput3"];
Depending on how many rows are added. So how can I get all the inputs without knowing what inputs I need to grab?
Thanks
Actually, you need to maintain counter in hidden, which you will get at the time of posting the form in case you don't want to maintain elements as array, otherwise you can put elements as array as described below:
<input type=text name="inputs[]" />
Name your inputs with array boundary, like:
<input type=text name="actioninput[]" />
now you can itreate throught them in you POST or GET ( depends ) array:
print_r($_POST);
Assuming your JSFiddle works fine for you, following are the steps.
1) Get keys of $_POST.
2) Get maximum counter value from keys.
3) Take a for loop from 0 to count of post.
4) If counter is 0, no suffix, else, add counter as suffix.
5) Now, you get posted variable.
6) Repeat it for every element in rows.
<?php
$keys = array_keys($_POST);
$keys = implode(',', $keys);
$n = str_replace('actionInput', '', $keys);
$m = explode(',', $n);
$max = max($m);
for ($i=0 ; $i<=$max ; $i++) {
$suffix = ($i==0) ? '' : $i;
if (isset($_POST['actionInput' . $suffix])) {
echo "<br/>-".$_POST['actionInput' . $suffix];
}
}
replace name=actionInput with name=actionInput[]
it should be an array with same name
same thing will apply with all form fields generated dynamically whose values you'll need.
Change this line in Add row jquery event
return name + i to return name
Remove i from it and then
name=actionInput[]
print_r($_POST);
It will gives array of actioninput

access via post method input with integer name

If I have a form that contains many fields generated dynamically (their names are integer, because they are named after the iteration that generates them). I need to get their values via post or get (this is an issue i will deal with myself, so lets assume its post).
the code for the inputs:
for ($x = 0; $x < 5; $x++)
for ($y = 0; $y < 12; $y++){
echo '<input type="text" name="'.$x.'"> Bar 1<br/>';
}
How can i get all the 12th values in an array on the server side using php? I generally know how to use post, but in this case what should i put inside the brackets of $_POST[]?
And what is the correct syntax to make the name an array?
Go through the post and ever 12th pull out a value just add a counter. If other posted information is in form, then do a preg match for first part of your key name and then iterate over counter on that name.
foreach ($_POST as $key => $value)
echo "Field ".htmlspecialchars($key)." is ".htmlspecialchars($value)."<br>";
If that approach isn't appealing, JSON encode the values being sent in an array to the php then do a json_decode into a php array and then take out every twelfth element.
Your code will produce twelve input fields with the same name ($x), which wont work (each input needs a unique name).
If I remember correctly, you can do something like this:
echo '<input type="text" name="'.$x.'[]"> Bar 1<br/>';
and it will generate an array in $_POST: $_POST[$x][0] = 'first', $_POST[$x][1] = 'second', ...

Dynamic form and looping through form array to insert into Mysql

I have a form that is built dynamically:
foreach($xml->config->popup as $popup_item){
<input class="fm-req" id="fm-popup_name[]" name="fm-popup_name[]" type="text" value="" />
<textarea class="fm-req" rows="4" cols="50" id="fm-popup_desc[]" name="fm-popup_desc[]" /></textarea>
<input class="fm-req" id="fm-popup_image[]" name="fm-popup_image[]" type="file" />
}
I haven't worked with arrays in form names before but i seen on another post on stack overflow you could do this and it seems like this is a much better way than i had planned, which was to add $i to the end of the name and increment each loop so i would have ended up with:
fm-popup_name1
fm-popup_name2
fm-popup_name3 etc etc
I could then do a loop count when building the form, pass the count as a hidden field and then use a for loop where x <= count and do my insert that way. But in the interest of improving the code and keeping it more compact and easy to understand, i think its worth doing this way but i cant figure out a good way to do it:
foreach($_POST['fm-popup_name'] as $index => $value) {
// get the value of name
}
foreach($_POST['fm-popup_desc'] as $index => $value) {
// get the value of name
}
foreach($_POST['fm-popup_image'] as $index => $value) {
// get the value of name
}
With that i can access all the data i need but i don't want to make 3 separate inserts for 1 record.
How can i take the information above and something like:
foreach($_POST['fm-popup_name,fm-popup_desc,fm-popup_image'] as $index => $value) {
INSERT INTO mytable(
popup_name,
popup_desc,
popup_image
)
VALUES(
'$popup_name',
'$popup_desc'
'$popup_image'
)";
}
Any ideas? Hopefully code is ok, i filtered out all the other crap that is irrelevant so hopefully all the id's etc match but im just looking for a rough example and i can convert back to my code.
You can use something the following, but there is a risk (can you spot it?) :
$entries = count($_POST['fm-popup_name']);
for($i = 0; $i < entries; ++$i) {
$name = $_POST['fm-popup_name'];
$desc = $_POST['fm-popup_desc'];
// other processing
}
If you haven't spotted it, the risk is that not all array elements may be populated, so you may not get a proper mapping for each row, unless you enforce it on the front end and validate this before processing your loop.

Accounting for missing array keys, within PHP foreach loop

I'm parsing a document for several different values, with PHP and Xpath. I'm throwing the results/matches of my Xpath queries into an array. So for example, I build my $prices array like this:
$prices = array();
$result = $xpath->query("//div[#class='the-price']");
foreach ($result as $object) {
$prices[] = $object->nodeValue; }
Once I have my array built, I loop through and throw the values into some HTML like this:
$i = 0;
foreach ($links as $link) {
echo <<<EOF
<div class="the-product">
<div class="the-name"><a title="{$names[$i]}" href="{$link}" target="blank">{$names[$i]}</a></div>
<br />
<div class="the-image"><a title="{$names[$i]}" href="{$link}" target="blank"><img src="{$images[$i]}" /></a></div>
<br />
<div class="the-current-price">Price is: <br> {$prices[$i]}</div>
</div>
EOF;
$i++; }
The problem is, some items in the original document that I'm parsing don't have a price, as in, they don't even contain <div class='the-price'>, so my Xpath isn't finding a value, and isn't inserting a value into the $prices array. I end up returning 20 products, and an array which contains only 17 keys/values, leading to Notice: Undefined offset errors all over the place.
So my question is, how can I account for items that are missing key values and throwing off my arrays? Can I insert dummy values into the array for these items? I've tried as many different solutions as I can think of. Mainly, IF statements within my foreach loops, but nothing seems to work.
Thank you
I suggest you look for an element inside your html which is always present in your "price"-loop. After you find this object you start looking for the "price" element, if there is none, you insert an empty string, etc. into your array.
Instead of directly looking for the the-price elements, look for the containing the-product. Loop on those, then do a subquery using those nodes as the starting context. That way you get all of the the-product nodes, plus the prices for those that have them.
e.g.
$products = array();
$products = $xpath->query("//div[#class='the-product']");
$found = 0 ;
foreach ($products as $product) {
$products[$found] = array();
$price = $xpath->query("//div[#class='the-price']", $product);
if ($price->length > 0) {
$products[$found] = $price->item(0)->nodeValue;
}
$found++;
}
If you don't want to show the products that don't have a price attached to them you could check if $prices[$i] is set first.
foreach($links AS $link){
if(isset($prices[$i])){
// echo content
}
}
Or if you wanted to fill it will dummy values you could say
$prices = array_merge($prices,
array_fill(count($prices), count($links)-count($prices),0));
And that would insert 0 as a dummy value for any remaining values. array_fill starts off by taking the first index of the array (so we start one after the amount of keys in $prices), then how many we need to fill, so we subtract how many are in $prices from how many are in $links, then we fill it with the dummy value 0.
Alternatively you could use the same logic in the first example and just apply that by saying:
echo isset($prices[$i]) ? $prices[$i] : '0';
Hard to understand the relation between $links and $prices with the code shown. Since you are building the $prices array without any relation to the $links array, I don't see how you would do this.
Is $links also built via xpath? If so, is 'the-price' div always nested within the DOM element used to populate $links?
If it is you could nest your xpath query to find the price within the query used to find the links and use a counter to match the two.
i.e.
$links_result = $xpath->query('path-to-link')
$i = 0
foreach ($links_result as $link_object) {
$links[$i] = $link_object->nodeValue;
// pass $link_object as context reference to xpath query looking for price
$price_result = $xpath->query('path-to-price-within-link-node', $link_object);
if (false !== $price_result) {
$prices[$i] = $price_result->nodeValue;
} else {
$prices[$i] = 0; // or whatever value you want to show to indicate that no price was available.
}
$i++;
}
Obviously, there could be additional handling in there to verify that only one price value exists per link node and so forth, but that is basic idea.

Foreach value from POST from form

I post some data over to another page from a form. It's a shopping cart, and the form that's being submitted is being generated on the page before depending on how many items are in the cart. For example, if there's only 1 items then we only have the field name 'item_name_1' which should store a value like "Sticker" and 'item_price_1' which stores the price of that item. But if someone has 5 items, we would need 'item_name_2', 'item_name_3', etc. to get the values for each item up to the fifth one.
What would be the best way to loop through those items to get the values?
Here's what I have, which obviously isn't working.
extract($_POST);
$x = 1; // Assuming there's always one item we're on this page, we set the variable to get into the loop
while(${'item_name_' .$x} != '') {
echo ${'item_name' .$x};
$x++;
}
I'm still relatively new to this kind of usage, so I'm not entirely how the best way to deal with it.
Thanks.
First, please do not use extract(), it can be a security problem because it is easy to manipulate POST parameters
In addition, you don't have to use variable variable names (that sounds odd), instead:
foreach($_POST as $key => $value) {
echo "POST parameter '$key' has '$value'";
}
To ensure that you have only parameters beginning with 'item_name' you can check it like so:
$param_name = 'item_name';
if(substr($key, 0, strlen($param_name)) == $param_name) {
// do something
}
Use array-like fields:
<input name="name_for_the_items[]"/>
You can loop through the fields:
foreach($_POST['name_for_the_items'] as $item)
{
//do something with $item
}
If your post keys have to be parsed and the keys are sequences with data, you can try this:
Post data example: Storeitem|14=data14
foreach($_POST as $key => $value){
$key=Filterdata($key); $value=Filterdata($value);
echo($key."=".$value."<br>");
}
then you can use strpos to isolate the end of the key separating the number from the key.
i wouldn't do it this way
I'd use name arrays in the form elements
so i'd get the layout
$_POST['field'][0]['name'] = 'value';
$_POST['field'][0]['price'] = 'value';
$_POST['field'][1]['name'] = 'value';
$_POST['field'][1]['price'] = 'value';
then you could do an array slice to get the amount you need

Categories