Managing the adds and removes from arrays - php

I am working with a couple of arrays that are stored in sessions. The purpose is to be able to add and remove objects from the arrays which will contain recipients to messages posted. It SEEMS to be working okay but with some quirks.
This code allows objects to be added;
while($row = mysqli_fetch_array($result))
{
$contact = $row['contact'];
$userid = $row['userid'];
echo "<tr>";
echo "<td><a href='mypagepost.php?contact=$userid&recipient=$contact' STYLE='TEXT- DECORATION: NONE'><font color=#808080>" . $row['contact'] . "</a></font></td>";
echo "</tr>";
$contact_count++;
}
And this one gives me the ability to send to another page for removal from the respective arrays.
<?php
$isBefore = array();
foreach ($_SESSION['contactlist'] AS $key => $rec)
{
if (!in_array($rec, $isBefore)) {
$isBefore[] = $rec;
echo "<font color=#808080><a href='removerecipient.php?contact=" . $_SESSION['recipientlist'][$key] . "&recipient=$rec' STYLE='TEXT-DECORATION: NONE'>
<font color=#808080>" . $rec . " </a></font>";
}
}
?>
This references a page with the following;
unset($_SESSION['recipientlist'][array_search($contact, $_SESSION['recipientlist'])]);
unset($_SESSION['contactlist'][array_search($recipient, $_SESSION['contactlist'])]);
So, I'm just starting to learn how to use arrays effectively so please forgive me for asking an obtuse question or two. When I click on a recipient just once to add them to the arrays, it works fine. I find that I can click on recipients in a contact list multiple times and the array still allows them to be added over and over again (although it doesn't print them out in the list). When I go to remove them by clicking on their name, I have to click them over and over again until they're gone. How can I set up a situation where it only gets added once and that's it? The other question I have is that after I remove all recipients from an array, I'm still left with an index number with no value. The print looks like this for both arrays (this is after adding and removing three recipients from the list;
Array ( [3] => )
Array ( [3] => )
The indexes don't apear to have a value associated with them, no idea what this means.

You could create a $_SESSION and check to see
if(isset($_SESSION['nameHere'])){
//do your thing here
}
, or make a variable like
$varName = 0;
and when the form is submitted
if(isset($_POST['submitButtonName'])){
if($varName === 0){
$varName = 1;
//do you thing here
}
}
. That $_POST would be a $_GET if your <form method='get' in your HTML.

Related

How to use a function to build an array?

I am a little rusty on my PHP and I am trying to create a function that will build an array. Essentially, I am trying to have an associative array of contacts ($contacts), with each individual element being a separate array ($contact). For starters, I would like it to be able to have a UniqueID,FirstName,and LastName within the elements. Here is the direction I am heading in right now:
<?php
$contact=array();
function createContact($Unique_ID,$FirstName,$LastName){
global $contact;
$contact=array("Unique_ID"=>$Unique_ID,"First_Name"=>$FirstName,"Last_Name"=>$LastName);
};
createContact("123456","John","Smith");
createContact("654321","Jane","Doe");
createContact("331143","Steve","Sample");
foreach($contact as $key=>$value){
echo $key.",",$value."<br>";
};
?>
This should create the $contact array with 3 separate records, but it only adds the last entry (In this case Steve Sample because it is the last one that was run). I remember learning somewhat about the global variables, but I think I am using it incorrectly. After I solve this, I will find a way to make an array containing all of these arrays.
You are overwriting the array $contact every time you invoke createContact().
You have to append the new records
function createContact($Unique_ID,$FirstName,$LastName){
$contact[] = array("Unique_ID" => $Unique_ID, "First_Name" => $FirstName, "Last_Name" => $LastName);
};
Note the [] to indicate that you want to append another entry.
If you want to print these you probably want to do something like this
foreach ($contact as $item) {
echo "ID = " . $item["Unique_ID"] . "<br>";
echo "First name = " . $item["First_Name"] . "<br>";
echo "Last name = " . $item["Last_Name"] . "<br>";
}
You need additional array.
$final_array = array();
and use
array_push($final_array, $contact);
inside the createContact function

Using "array_values" with "foreach" data?

I am trying to organize an array of data to be sent in an email. I have no problem getting the data, but I am not sure how to organize it.
Foreach: Here outputs a list of questions generated by the user in the backend
$message = array();
foreach($questions['questions'] as $key => $value){
if(is_array($value) && isset($value[ 'questionlist'])){
foreach($value as $key => $subquestion){ //line 119
foreach ($subquestion as $key => $value){
$message[] = $value['a-question'];
}
}
}
}
I am trying to conjoin the data with each other, the data from the foreach and the $_POST data which is check values.
My logic for doing it this way is because one comes from the database, one is just form data (that does not need to be saved to the database it comes from the front end unlike the data from the database that is generated via backend) That said there perhaps is a better way, but I pretty much got this I am just not sure how to join the data so it looks like
<li>MYARRAYDATA - MYFORMDATA</li>
<li>MYARRAYDATA - MYFORMDATA</li>
<li>MYARRAYDATA - MYFORMDATA</li>
//The form input data '0', '1' values
$checks = $_POST['personalization_result'];
//Putting that data into array_values
$checkValues = array_values($checks);
//Then passing the array_values into 'implode' and organizing it with a list (<li>)
$checkString = '<li>'.implode('</li><li>',$checkValues).'</li>';
//Then testing with var_dump outputs a nice list of '0','1' values
var_dump ($checkString);
Trying the same method but trying to conjoin the foreach array and the check values does not work, here is an example.
//Similar to $checkValues I pass the data from the foreach into "array_values"
var_dumping this works fine.
$arrayValues = array_values($message);
//This is obvious it's the same as above it "implodes" the data nicely into a list(<li>)
$arrayString = '<li>'.implode('</li><li>',$arrayValues).'</li>';
//This var dumps the "$arrayString" nicely
var_dump ($arrayString)
Again the actual question is here, how do I conjoin each piece of data?
My Attempts: Here are my attempts for "conjoining" the data.
// This does not work well (maybe by cleaning up it can work) but it outputs 2 separate lists
var_dump ($arrayString.'_'.$checkString);
//I tried to run it inside one implode variable this is invalid arguments
$checkString = '<li>'.implode('</li><li>',$arrayValues.'_'.$checkValues).'</li>';
//Modified one implode variable this outputs see below
$checkString = '<li>'.implode('</li>'.$arrayValues.'<li>',$checkValues).'</li>';
<li>Array
1</li>
<li>Array
0</li>
<li>Array
1</li>
<li>Array
0</li>
var_dump results: Here is the var_dump result of each array, I want to combine these into one list
$_POST array
// Var dump of form $_POST DATA
var_dump ($checkString);
//Result
1 //This is generated through the $_POST method not on database
0 //This is generated through the $_POST method not on database
1 //This is generated through the $_POST method not on database
0 //This is generated through the $_POST method not on database
DATABASE array
// Var dump of datbase generated from backend
var_dump ($arrayString);
//Result
I am 1 //This is generated in the backend and is stored on a database
Hi I am 2 //This is generated in the backend and is stored on a database
civil is 3 //This is generated in the backend and is stored on a database
THIS IS FOURTA //This is generated in the backend and is stored on a database
The Goal
I am 1 - 1 //This is checked
Hi I am 2 - 0 //This is NOT checked
civil is 3 - 1 //This is checked
THIS IS FOURTA - 0 //This is NOT checked
The Answer: Thanks to #xdim222
I didn't understand it at first, because of the increment, but now I understand it all, initially it would have worked but my variables were under the foreach statement and that was causing it not to return the array.
At least in my opinion thats what it was, because when I added the variable above the foreach it worked.
I modified the answer to suit my code.
//$messages = array('test1', 'test2', 'test3', 'test4', 'test5');
//Instead of using this array I used the array generated in my foreach above.
// Instead of this $checks = array(1,0,1,0); I take the $_POST value which generates an array, you can see above.
$checkValues = array_values($checks);
$checkString = implode($checkValues);
$i=0;
foreach($messages as $msg) {
echo $msg . ' - ' . ( isset($checkString[$i])? $checkString[$i] : 0 ) . '<br>';
$i++;
}
Again thanks to #xdim222 for being patient, reading my long question, and most importantly helping me learn, by asking this question and finding a solution this stuff really sticks and is in my opinion the best way to learn (by asking). :)
To make it easier, I assign $messages and $checks directly, I have tried this code and it works. You might have different elements of your arrays, but I think you can figure it out from my code below:
$messages = array('test1', 'test2', 'test3', 'test4', 'test5');
$checks = array(1,0,1,0);
$i=0;
foreach($messages as $msg) {
echo $msg . ' - ' . ( isset($checks[$i])? $checks[$i] : 0 ) . '<br>';
$i++;
}
PS: I made a mistake in my previous answer by incrementing $i before echoing things out, array element should start by 0.
While waiting for your reply to my comment above, I'm trying to write some code here..
I assume you want to display the questions that were pulled from database and it should be displayed based on what user chose in the form. So you may use this code:
foreach($questions['questions'] as $key => $value){
if(is_array($value) && isset($value[ 'questionlist'])){
foreach($value as $key => $subquestion){ //line 119
foreach ($subquestion as $key => $value){
$message[$key] = $value['a-question'];
}
}
}
}
I added $key in $message in the code above, with an assumption that $key is the index of a question, and this index will be matched with what user chose in the form. Then we can list all the questions that a user have chosen:
foreach($checks as $check)
echo '<li>'.$check . ' - ' . $message[$check].'</li>';
Is this what you want?
Based on your update:
$i=0;
foreach($message as $msg) {
$i++;
echo '<li>'. $msg . ' - ' . ( isset($checks[$i])? $checks[$i] : 0 ) . '</li>';
}
Maybe this is what you want.
As I said, there should be a relation between the $message and $checks, otherwise the above code looks a bit weird, because how do we know that a question is selected by user? Maybe you should show how you get that $_POST['personalization_result'] in your HTML.

How to reference a item in an array numerically when it has been created as an associative array

I am using PHP 5.3.6
I have the following code below. Everything works fine except for the last line which attempts to to return a value based on the position in the array as opposed to the associative name. Can anyone explain why this takes place and how I can build the array so that I can reference an item either by the associative name or position number?
Thanks.
<?php
class myObject {
var $Property;
function myObject($property) {
$this->Property = $property;
}
}
$ListOfObjects['form_a'] = new myObject(1);
$ListOfObjects['form_b'] = new myObject(2);
$ListOfObjects['form_c'] = new myObject(3);
$ListOfObjects['form_d'] = new myObject(4);
echo "<pre>";
print_r($ListOfObjects);
echo "</pre>";
echo "<hr />";
foreach ($ListOfObjects as $key => $val) {
echo "<li>" . $ListOfObjects[$key]->Property . "</li>";
}
echo "<hr />";
echo "<li>" . $ListOfObjects['form_a']->Property . "</li>"; // Works ok.
//Edit: ------------------------------------------------------------
//Edit: Everything above is for context only
//Edit: I'm only interested in the line below and why it does not work
//Edit: ------------------------------------------------------------
echo "<li>" . $ListOfObjects[0]->Property . "</li>"; //Does not work.
?>
function value_from_index($a,$k){
return array_slice($a,$k,1);
}
If you just want the first/last element of an array, try end($array) for the last item without destroying it and reset($array) to get the first.
Don't use reset and end if you're looping through an array as Flambino notes, this indeed results in some unexpected behaviour.
For anything inbetween you'll need to use array_slice()
Not the nicest way of doing it, but effektive and readable:
$i = 0;
$last = count($ListOfObjects);
foreach($ListOfObjects as $obj) {
if($i == 0) {
//do something with first object
$obj->property;
else if ($i == ($last-1)) {
//do something with last object
$obj->property;
}
}
PHP arrays aren't like arrays you know from most other programming languages, they are more like ordered hash tables / ordered dictionaries - they allow for access by named index and retain order when new items are added. If you want to allow access with numeric indices to such an array you have to define it that way or use one of roundabout ways given in other answers.
In your case you can use a single line of code to allow access by index:
$ListOfObjects += array_values($ListOfObjects);
This will extend your array with the same one but with numeric indices. As objects are always passed by reference, you can access the same object by writing $ListOfObjects['form_b'] and $ListOfObjects[1].

Making POST values dynamic within a loop to store as an array?

I've been working on trying to write a function that will grab the POST values of any given form submission, pop them into an array, loop through the array using trim, addslashes etcetera pass that value back to a variable where it can then be passed to a database.
Now the hurdle I have atm is getting all the input,textarea,select element data into an array upon form submission. code I have follows
$fields = array($_POST['1'], $_POST['2']);
$i = 0;
foreach ($fields as $field) {
$i++;
${'field'.$i } = trim(addslashes(strip_tags($field)));
echo "POST field info #". $i ." - ". ${'field'.$i }."<br />";
}
As you can see everything is fine here baring that the POST value names are still being in-putted statically, what I need is a way to get that POST data fed into a loop which dynamically calls the POST name using an increment variable and then pop all that data into the same array. Code I have tried follows.
for ($ii=0;$ii++;) {
foreach($_POST['$ii'] as $field) {
$fields = array($field);
}
}
$i = 0;
foreach ($fields as $field) {
$i++;
${'field'.$i } = trim(addslashes(strip_tags($field)));
echo "POST field info #". $i ." - ". ${'field'.$i }."<br />";
}
Now I know this wont work but I can sense I am relatively close, so I am wondering if any clever person can help me sort the last part out? I sadly am now going to sleep and wont be viewing this post for at least 9 hours, apologies.
Thanks in advance.
Dan.
$arrayOfPostValues = $_POST; // it already is an array
$arrayOfPostValues = array_map('strip_tags', $arrayOfPostValues);
$arrayOfPostValues = array_map('trim', $arrayOfPostValues);
Or, if you really, really want to use a loop:
foreach ($arrayOfPostValues as &$value) {
$value = trim(striptags($value));
}
I'd absolutely advise against the use of addslashes, it serves very little purpose. Use mysql_real_escape_string or prepared statements instead.
I'd also advise against breaking the vales out of the array into separate variables, it can only cause problems. If you really want to do it, there's the extract function, which does exactly that. But, again, don't do it. Arrays are the perfect way to handle this kind of data.
You need to assign values to $_POST[1] and $_POST[2] to begin with, I've done this for you but normally they would be populated from a form I assume?
I'm not sure why you want to do this sort of thing: ${'field'.$key}, but I've left that part as is as I assume you must have a reason.
Anyway I've modified your code a bit, see below.
$_POST['1'] = '<h1>variable 1</h1>';
$_POST['2'] = '<h2>variable 2</h2>';
foreach($_POST as $key => $value){
${'field'.$key} = trim(addslashes(strip_tags($value)));
echo "POST field info #". $key ." = ". ${'field'.$key}."<br />";
}
The above code outputs:
POST field info #1 = variable 1
POST field info #2 = variable 2
On a side note, using field names such as '1' and '2' is not very good. Try using something more descriptive but as I said above I assume you have a reason for doing this.
UPDATE:
You can still get this to work for any form even if you are using specific names for the form elements. I have added a few lines below as an example for you.
$_POST['email'] = 'example#example.com';
$_POST['password'] = 'hgbks78db';
$_POST['name'] = '';
foreach($_POST as $key => $value){
if($value==''){
echo 'POST field "'.$key . '" is empty<br />';
/* I added the name of the field that is empty to an error array
so you have a way of storing all blank fields */
$a_error[] = $key;
}
else{
echo 'POST field "'.$key . '" is not empty<br />';
}
}

PHP nested loop behaving unexpectedly

I have an array which contains the categories for a particular article ($link_cat). I'm then using mysql_fetch_array to print out all of the categories available into a list with checkboxes. While it's doing this I want it to compare the value it's on, to a value from the other array. If there is a match, then it means that one of the categories applies to this article, and it should print out a line of code to apply the checked attribute. great! except it's not working =[
while ( $row = mysqli_fetch_array($results, MYSQLI_ASSOC) ){
$cat[$i] = $row['category'];
$cat_id[$i] = $row['cat_id'];
echo '<li><input type="checkbox" ';
$catCount = count($link_cat);
for ($ct = 0; $ct < $catCount; $ct++){
if ($cat_id[$i] == $link_cat[$ct]){
echo 'checked="checked" ';
}
}
echo 'name="' . $cat_id[$i] . '" />' . $cat[$i] . '</li>';
$i++;
}
I've never really done a nested loop before (I suspect thats the problem).
The problem seems to be that when this runs, $link_cat[0] which will have the first category to check against in it - doesn't register. It comes up blank. Printing out variables inside the for loop confirmed this. Any others [1] [2] etc, are fine. It's just [0]. But why? it doesn't seem to make any sense. I know there is something in there, because I printed the contents of array as I filled it it, just to check. Yet it doesn't just show during the loop. Any ideas?
slight bug fix (and blatant style change): Your version can print out checked="checked" multiple times. Do $cat and $cat_id need to be arrays?
while ( $row = mysqli_fetch_array($results, MYSQLI_ASSOC) ) {
$cat = $row['category'];
$cat_id = $row['cat_id'];
echo '<li><input type="checkbox" ';
if ( in_array($cat_id, $link_cat) ) {
echo 'checked="checked" ';
}
echo "name='$cat_id' />$cat</li>";
}
For situation where one would normally throw a debugger at a problem, I like to throw in a nice print_r in a comment block (view-source for debug output, safer on live-ish sites).
echo '<!-- ' . print_r($link_cat, TRUE) . ' -->';
While I was originally very wrong about the array looping needing a reset, I can't shake the feeling that looping through that array isn't the fastest way to do what you are after.
Perhaps array_search would do, or maybe array_key_exists. in_array look like a winner but I didn't think of it

Categories