What is the purpose of associative array - php

I am new to this array in forms. I tried to get rid of the associative array in this line
("F001"=>"a","F002"=>"b","F003"=>"c","F004"=>"d","F005"=>"e","F006"=>"f","F007"=>"g","F008"=>"h","F009"=>"i","F010"=>"j")
and made it ("F001", "F002" and so on) but program wont work. If I put it back it will work. My question is why it wont work if i get rid of the associative array?
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<?php
if (isset($_POST['search'])) {
// move $students into the if statement cause we won't
// need it unless they're searching
$students = array (
array ("F001"=>"a","F002"=>"b","F003"=>"c","F004"=>"d","F005"=>"e","F006"=>"f","F007"=>"g","F008"=>"h","F009"=>"i","F010"=>"j"),
array ("albert","berto","charlie","david","earl","francis","garry","harry","irish","james"),
array (1,2,3,3,2,1,2,1,3,1)
);
$idNumber = $_POST['search'];
// we can use isset here because the student id *is* the key.
// if it was the value, than we would use array_search() and
// check if it returned false
if (isset($students[0][$idNumber])) {
// array_keys returns the keys of an array as an array,
// allowing us to find the numerical index of the key
$studentIndex = array_search($idNumber,array_keys($students[0]));
// printf basically allows for formatted echoing. %s means
// a string. %d means a number. You then pass in your
printf('Student ID: %s<br>Name: %s<br>Grade: %d', $idNumber, $students[1][$studentIndex], $students[2][$studentIndex]);
}
else {
// use htmlspecialchars() to encode any html special characters cause never trust the user
printf('No student with ID "%s" found.', htmlspecialchars($idNumber));
}
}
?>
<form action="" method="POST">
Id number: <input type="text" name="search">
<input type="submit" value="search">
</form>
</body>
</html>

Why it doesn't work if you remove it is mentioned in the comments:
// we can use isset here because the student id *is* the key.
// if it was the value, than we would use array_search() and
// check if it returned false
The reason behind that decision isn't clear from the example, but the letters those keys represent could have a wider meaning to a bigger system, and therefore a decision was taken to make it associative.
As for the purpose of an associative array, it can make searching for specific items simpler, especially in multi-dimensional arrays. It also can improve readability.
Trying to understand the following would be a pain at best:
$posts[0][1][0][7][4] = 'value';
Where as understanding the below is a little easier:
$posts[newest][1][information][tags][4] = 'value';
The use of associative arrays above make it easier to see that in an array of posts, the newest post with index 1 has information, and the 5th tag (because of 0 indexing) is 'value'.

Related

in_array() not working properly using $_POST

I'm trying to let the user select multiple countries and then check if the countries he selected are in the array of allowed countries using PHP
I used javascript for multiple options , this is why it is not found in the tags. Otherwise for testing you can put some custom options between the tags. (country codes in this case)
HTML:
<form method="POST" action="">
<select name="countries[]" class="country" multiple></select>
<button type="submit">Submit</button>
</form>
PHP:
<?php
if(isset($_POST['countrylist'])) {
$arr = array("FR","GF","PF","TF","GE","DE","GI","GR","GL","HK","IS","IN","ID","IE","IL","IT","JP","JO","KZ","KR","LV","LB","LI","LT","LU","MK","MX","MD","MC","MN","MS","MA","NP","NL","NZ","NO","PK"); //These are allowed country codes which are sent by the user the same way as above using POST request. The sent array looks fine as you can see in the var_dump result below.
$array2 = (array) $_POST['countries'];
$array2= array_filter($array2);
if(!in_array($array2, $arr)) {
echo var_dump($array2);
}
}
?>
The in_array() function doesn't seem to work , my var_dump result looks something like this:
array(1) { [0]=> string(2) "FR" } //If I selected France country for example.
$arr is an array of strings. $array2 is an array of strings (just one string in this case).
You are using $array2 as your needle, so you are asking "Does this array appear in this set of strings", which is doesn't, because the array isn't a string.
You would need to do something more like in_array($array2[0], $arr).
That, of course, misses the point since you want to accept multiple values, but it is a place to start.
You need to loop over $array2 and test each value in turn until you get to the end or hit a failure state. You might also look at using array_filter again, this time passing a callback.
in_array() works just fine but you call with wrong arguments. The first argument that it expects is a value to search in the second argument (that must be an array).
Since you have an array of values that you want to search you can either try to search each value at a time using in_array() or you can use array_intersect() to find the values that are present in both arrays.
Your choice will be influenced by the way you decide to handle the unexpected values in the input.
Example using in_array():
$knownValues = ['FR', 'GF', 'PF', 'TF'];
if (! is_array($_POST['countries'])) {
// The input does not look valid; there is nothing to process
// Handle this in the most appropriate way for your application and stop here
// return/exit/throw/whatever
}
$valid = [];
foreach ($_POST['countries'] as $countryId) {
if (! in_array($countryId, $knownValues)) {
// $countryId is not a valid/known country code
// Do something with it (report it, ignore it etc.)
continue;
}
$valid[] = $countryId;
}
// Here $valid contains the input values that are present in $knownValues
Example using array_intersect():
$knownValues = ['FR', 'GF', 'PF', 'TF'];
if (! is_array($_POST['countries'])) {
// The input does not look valid; there is nothing to process
// Handle this in the most appropriate way for your application and stop here
// return/exit/throw/whatever
}
$valid = array_intersect($_POST['countries'], $knownValues);
$invalid = array_diff($_POST['countries'], $knownValues);
// The known/valid and unknown/invalid values have been separated
// Do whatever you want with them.

Why the output is not a string

I tried many time, but I still don't understand why the output is not a string, anything wrong ? help me check it. The final output should be a uppercase name string
<html>
<p>
<?php
// Create an array and push on the names
// of your closest family and friends
$name = array();
array_push($name,"Mike");
array_push($name,"Jane");
array_push($name,"Jack");
array_push($name,"Nike");
array_push($name,"Ash");
array_push($name,"Chris");
array_push($name,"Zark");
// Sort the list
sort($name);
join(",",$name);
// Randomly select a winner!
$random = count($name,rand(0,7));
// Print the winner's name in ALL CAPS
$winner = strtoupper($random);
print($winner);
?>
</p>
</html>
$random = count($name,rand(0,7));
This line assigns the count of elements in $name. I don't know what else you expected to get back other than a number here.
What you really want:
echo strtoupper($name[array_rand($name)]);
http://php.net/manual/en/function.array-rand.php
Other Notes:
Your call to join() doesn't do anything useful since you're not doing anything with the return value.
Your call to sort is pointless if you're just picking a random entry later.
Pick a plural name for your array names so you know they are arrays. $names instead of $name.
If you know all of the array elements ahead of time, no need for array_push(), just use an array literal: array('Mike', 'Jane', /* etc */)
If you're outputting data into the context of HTML, always use htmlspecialchars() to make sure any reserved characters are escaped properly. This isn't a problem with the code you literally have here, but will be as soon as you want to output < or ".

How to send array with various submit buttons?

Can you send an array with various values in html? I would like to send different array values with various different submit buttons all within one <form> element.
Here is what I am doing currently. It works so I'm not having a problem, but I couldn't find any documentation for anything similar and I am really curious if theres another way.
Button with my *psuedo*array
<input type="submit" name="form_action" value="action:new_business,id:0">
Decode function:
$action = explode(',', $_POST['form_action']);
$new = array();
foreach ($action as $v) {
$t = explode(':',$v);
$new[$t[0]] = $t[1];
}
print_r($new);
And the results:
Array ( [action] => new_business [id] => 0 )
Of course, this works, so I'm really just curious whether there's a built in solution already.
The desired simplicity:
<input type="submit" name="array" value="array('0'=>'foo','1'=>'bar')">
print_r($_POST['array]);
Array ( [0] => foo [1] => bar )
Edit: I know how to send arrays with html, but that was not my question. If I use hidden inputs, they get sent regardless of which submit button I click, there will be multiple submit buttons contained in one <form> element, and I need to know which was clicked and what action it is going to be used for. Sorry if that was unclear but I don't think I deserve downvotes either way...
Try this:
<input type="hidden" name="form_action[action]" value="new_business" />
<input type="hidden" name="form_action[id]" value="0" />
Inputs with names of the form name[key] will be condensed into an array. This also applies to name[], which will become elements of an indexed array.
I know the question is old. I still like to answer this, as I am implementing currently something similar.
You can indeed write your statement and turn it into a valid context. By implementing:
if(isset($_POST['array'])){
eval('$my = '.$_POST['array'].';');
print_r($my);
}
you concatenate your POST to a valid php expression in string format and evaluate it. This however is very dangerous because it allows execution of any code inside without any verification. You MUST NOT use this in a public environment because anyone can easily modify the string being send by the button.
The best solution in terms of safety and efficiency is really to send a csv format:
<input type="submit" name="array" value="array('0','foo','1','bar')">
in php do:
$my_assoc = array();
if(isset($_POST['action'])){
$my = explode(",",filter_input(INPUT_POST, 'action' , FILTER_SANITIZE_STRING));
for($i = 0, $num = count($my); $i < $num; $i+=2){
$my_assoc[$my[$i]] = $my[$i+1];
}
print_r($my_assoc);
}
The explode function is linear in complexity and has no large impact. By filtering the csv string, you can also make sure to have no unwanted characters in it (never trust incoming data). You can then either keep the indexed array ($my) and treat every two values as (psydo) key-value pair or turn it into an associative array ($my_assoc).

Print PHP values or words instead of its corresponding incrementing numerical ID's

$page_id++ represents page order ID from 0 to 5 inclusive in a wordpress website and increments.
I then include some HTML like so:
<div class="page_title <?php echo page_item;?>" id="about"><?php the_title()?></div>
the output for the div class is "page_title 0" for the first one.
What I'm wanting to know is if i could replace the number with a word or a class. I've tried creating an array:
<?php $page_id = array (0 === 'one', 1 === 'two',2 === 'three',3 ==='four',4 ==='five', 5=== 'six')?>
but it just returns: "page_title Array"
EDIT: I've also tried replacing === with => in the Array.
I know I need to read up on my syntax (or even logic!) here but any help/ explainations or clues even would be appreciated as always.
It looks like you're not actually refer to the items in the array, just the array itself.
Are you using a foreach loop to print these out?
<?php foreach($page_id as $page_item):?>
<div class="page_title <?php echo $page_item;?>" id="about"><?php the_title()?></div>
<?php endforeach;?>
Or alternatively do it manually:
<div class="page_title <?php echo $page_id[0];?>" id="about"><?php the_title()?></div>
So you would do that, referencing keys 0 - 5.
Try something more like:
<?php
$pageIDs = array(0 => 'one', 1 => 'two'); // and so on...
$page_id = $pageIds[$page_id ];
// ... Other wordpressy stuff...
Essentially, the idea being you grab the value from an array, rather than passing an array as the variable, when you get $page_id in this case, it'll be the string.
You can, and in fact should, be using something besides numbers as class names. I'm about 78% certain that a class name should contain at least one non-digit character, and should start with a letter. (That's actually the rule for IDs, it seems. I'm not finding a hard-set rule for classes, but eh.)
As for how to map numbers to words, you should be looking up the id in your array rather than echoing the whole thing.
<?php $page_classes = array(...); ?>
...
<div class="page_title <?= $page_classes[$page_id] ?>" id="about">
<?php the_title()?>
</div>
(Note, if you're doing this in a situation where you expect more than one such div to be printed, you should seriously consider losing the id attribute or making it equal to the class name you're printing out or...something. IDs should be unique.)

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

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;
}

Categories