Grab random value the remove from array - php

I am wanting to use a form confirmation to display a single use code and then discard the code so it wont be used again. So far this is what I have:
$codes = array(
'810',
'0190',
'1924',
'481',
'2941',
'8777',
'092',
'432',
'984',
'172',
'8483'
);
$rand_code = array_rand($codes);
$code_gen = $codes[$rand_code];
return $confirmation = 'Here is your code:' . $code_gen;
This shows me a random code each time I submit the form so it works perfect. I need to actually store that code and not use it again. What would be my best solution? Any help would be greatly appreciated.

Shuffle to get a random one, then pop it out, bam.
shuffle($codes);
while($code_gen = array_pop($codes)){
return $confirmation = 'Here is your code:' . $code_gen;
}

If you prepend the datetime to the ticketnumber then you are guaranteed that your number is not used again without needing to store it. (unless we have time travellers).
e.g. 110912032634 = ticket 1 and 110912032785 = ticket 2
If you mean by "later on" in the session, use sessions, etc...
If you mean by "later on" : after a month to collect data, then store it in a database

Related

Trying to remove duplicate lines from array acc. to column contents

Using PHP and making a SELECT query from DB I am getting an output I don't like.
I start like this:
$details = Db::getInstance()->executeS($sql);
And I get, after a
echo json_encode($details);
For debug purposes:
[{"email":"test#on.gr","lastname":"TEST","firstname":"TEST1","id_lang":"1","id_order":"1"}]
[{"email":"test#on.gr","lastname":"OTHER","firstname":"DIFFERENT","id_lang":"1","id_order":"2"}]
[{"email":"test#on.gr","lastname":"THIRD","firstname":"DIFFERENT","id_lang":"1","id_order":"3"}]
[{"email":"new#on.gr","lastname":"THIRD","firstname":"NEW","id_lang":"1","id_order":"4"}]
What I want is to transform array $details to check on each "line" if the email column has unique values on the whole output. If yes to delete the lines that contain the duplicate entries and leave only the first that contain it.
Desired output:
[{"email":"test#on.gr","lastname":"TEST","firstname":"TEST1","id_lang":"1","id_order":"1"}]
[{"email":"new#on.gr","lastname":"THIRD","firstname":"NEW","id_lang":"1","id_order":"4"}]
(As you see lines with id order 2 and 3 where removed as they have the same email with the first)
Any kind of help will be highly appreciated.
Edit: just wanted to add up here that my code isn't in PHP. You have to change it.
Do an ORDER BY email command in the select statement.
Pseudo Code:
Loop through results:
String email1 = "";
String email2 = "";
for (i=0;i<(Detailssize); i++){
email2 = details[email][i]; //Do whatever you need to do to access the value of the email key here.
if(email2 != email1){
KEEP IT
}
else{
THROW AWAY
}
email1 = email2;
}
Obviously this is not PHP. It has been a while since i coded php. Nonetheless logically this should still work. I'm sure theres a way to change your SELECT statement to only return one from each value but i'm not good enough at SQL for that. This isn't as good of a solution but hope it helps.
Keep a list of emails you've seen before; whenever you encounter an email that has been seen before, skip that row.
Like this:
$newSet = array();
$seenBefore = array();
foreach( $details as $row ) {
if( isset( $seenBefore[ $row['email'] ) ) {
continue; // jump to the next row
}
// this email address must be new; add it to things we've seen before then add this row to the newSet
$seenBefore[$row['email']] = true;
$newSet[] = $row;
}
Then output $newSet in whichever way you want.

Preserving $_POST variables when paginating

I have a simple list of orders which a user can filter by status (open,dispatched,closed). The filter dropdown triggers a post to the server and sends the filter value through. Orders are listed out 10 to a page with pagination links for any results greater than 10. Problem is when I click the pagination links to view the next page of results the filter value in the post is lost.
public function filter_orders() {
$page = ($this->uri->segment(4)) ? $this->uri->segment(4) : 0;
$filter = $this->input->post('order_status_filter');
$config = array();
$config["base_url"] = base_url() . "control/orders/filter_orders";
$config["per_page"] = 10;
$config['next_link'] = 'Next';
$config["uri_segment"] = 4;
$config['total_rows'] = $this->model_order->get_all_orders_count($this->input->post('order_status_filter'));
}
How can I make the pagination and filter work together. I've thought about injecting a query string in to the pagination links but it doesn't seem like a great solution.
The answer is very simple, use $_GET. You can also use URI segments.
i.e, index.php/cars/list/5/name-asc/price-desc'
The main reason you'll want to use $_GET is so you can link other users so they see the same result set you see. I'm sure users of your web app will want this functionality if you can imagine them linking stuff to each other.
That said, it would be ok to ALSO store the filters in the session so that if the user navigates away from the result set and then goes back, everything isn't reset.
Your best bet is to start a session and store the POST data in the session. In places in your code where you check to see if the user has sent POST data, you can check for session data (if POST is empty).
In other words, check for POST data (as you already do). If you got POST data, store it in the session. If a page has no POST data, check to see if you have session data. If you do, proceed as if it was POSTed. If you have both, overwrite the session with POST. You'll want to use new data your user sent you to overwrite older data they previously sent.
You either put everything in $_GET or if the data is sensible, put it in $_SESSION. Then it travels between pages.
In your case there seem to be no reason to put your filter data anywhere else than in $_GET.
A query string does seem the best solution. You could store it in the session or in cookies as well, but it makes sense to also store it in the query string.
Store it in cookies or the session if you want to remember the user's choice. Which seems like a friendly solution. It allows the user to keep their settings for a next visit, or for another page.
Store it in the query string, because going to 'page 2' doesn't tell you anything if you don't know about filters, page size or sorting. So if a user wants to bookmark page 2 or send it by e-mail, let them be able to send a complete link that contains this meta information.
Long story short: Store it in both.
maybe its not a right answer but, give it a try
<?php
// example url
$url = "index.php?page=6&filter1=value1&filter2=value2";
// to get the current url
//$url = "http://".$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"];
// change the page to 3 without changing any other values
echo url_change_index( $url, "page", 3 );
// will output "index.php?page=3&filter1=value1&filter2=value2"
// remove page index from url
echo url_change_index( $url, "page" );
// will output "index.php?filter1=value1&filter2=value2"
// the function
function url_change_index( $url, $name = null, $value = null ) {
$query = parse_url( $url, PHP_URL_QUERY );
$filter = str_replace( $query, "", $url );
parse_str( $query, $parsed );
$parsed = ( !isset( $parsed ) || !is_array( $parsed ) ) ? array() : $parsed;
if ( empty( $value ) ) {
unset( $parsed[$name] );
}
else {
$parsed[$name] = $value;
}
return $filter.http_build_query( $parsed );
}
?>

How To Stop Duplicates Being Listed On PHP Results?

I've made up a PHP script which assigns a score to listings on a website and assigns it to the results page. I have got it to work in that it shows the score and the details but it keeps listing the same results over and over.
I can't work out what it is doing but there is a small section of code I was hoping would prevent duplicate listings. Could anyone give it a tweak and see if I am going wring somewhere?
The Code is:
$dupCatch .= $adId.",";
$dupResults = explode(',', $dupCatch);
foreach($dupResults as $dupResult){
if($dupResult == $adId){
print "";
} else {
print $showResults;
$scoreBox = 'THIS IS THE SCORE: ' . $finalScore . '';
print $scoreBox;
}
}
Thanks in advance!
Jack
The problem is that you add your current $adId to the duplicate list before you check if it is there - which it will always be, of course.
Storing a bunch of numbers in a string, explodeing it every time, is a little weird, use an array instead. You also don't need to manually loop through all the items, just use in_array()
if( !in_array($adId, $dupCatch) ){
print $showResults;
$scoreBox = 'THIS IS THE SCORE: ' . $finalScore . '';
print $scoreBox;
}
$dupCatch[] = $adId;
Needless to say: it would be a better idea to fix the part that gives you the duplicate results in the first place.
You can either try to use array_unique from php side or use unique attribute at field in mysql this way duplicates can be prevent before even inserting them.

Storing multiple inputs with the same name in a CodeIgniter session

I've posted this in the CodeIgniter forum and exhausted the forum search engine as well, so apologies if cross-posting is frowned upon.
Essentially, I've got a single input, set up as <input type="text" name="goal">. At a user's request, they may add another goal, which throws a duplicate to the DOM. What I need to do is grab these values in my CodeIgniter controller and store them in a session variable. My controller is currently constructed thusly:
function goalsAdd(){
$meeting_title = $this->input->post('topic');
$meeting_hours = $this->input->post('hours');
$meeting_minutes = $this->input->post('minutes');
$meeting_goals = $this->input->post('goal');
$meeting_time = $meeting_hours . ":" . $meeting_minutes;
$sessionData = array(
'totaltime' => $meeting_time,
'title' => $meeting_title,
'goals' => $meeting_goals
);
$this->session->set_userdata($sessionData);
$this->load->view('test', $sessionData);
}
Currently, obviously, my controller gets the value of each input, writing over previous values in its wake, leaving only a string of the final value. I need to store these, however, so I can print them on a subsequent page.
What I imagine I'd love to do is extend the input class to be able to call $this->input->posts('goal'). Eventually I will need to store other arrays to session values. But I'm totally open to implementation suggestion.
Thanks so much for any help you can give.
You'd want to use this in your form:
<input type="text" name="goal[]">
You can then get the values in the Controller via:
$goal = $this->input->post('goal');
And then set the variable in the session via:
$this->session->set_userdata('goal', $goal);
If you want to retrieve it again. do this via:
$goal = $this->session->userdata('goal');
You'll have something like this:
$goal[0] = 'first goal';
$goal[1] = 'second goal';
Please try it first :)

How do I use cookies to store users' recent site history(PHP)?

I decided to make a recent view box that allows users to see what links they clicked on before. Whenever they click on a posting, the posting's id gets stored in a cookie and displays it in the recent view box.
In my ad.php, I have a definerecentview function that stores the posting's id (so I can call it later when trying to get the posting's information such as title, price from the database) in a cookie. How do I create a cookie array for this?
**EXAMPLE:** user clicks on ad.php?posting_id='200'
//this is in the ad.php
function definerecentview()
{
$posting_id=$_GET['posting_id'];
//this adds 30 days to the current time
$Month = 2592000 + time();
$i=1;
if (isset($posting_id)){
//lost here
for($i=1,$i< ???,$i++){
setcookie("recentviewitem[$i]", $posting_id, $Month);
}
}
}
function displayrecentviews()
{
echo "<div class='recentviews'>";
echo "Recent Views";
if (isset($_COOKIE['recentviewitem']))
{
foreach ($_COOKIE['recentviewitem'] as $name => $value)
{
echo "$name : $value <br />\n"; //right now just shows the posting_id
}
}
echo "</div>";
}
How do I use a for loop or foreach loop to make it that whenever a user clicks on an ad, it makes an array in the cookie? So it would be like..
1. clicks on ad.php?posting_id=200 --- setcookie("recentviewitem[1]",200,$month);
2. clicks on ad.php?posting_id=201 --- setcookie("recentviewitem[2]",201,$month);
3. clicks on ad.php?posting_id=202 --- setcookie("recentviewitem[3]",202,$month);
Then in the displayrecentitem function, I just echo however many cookies were set?
I'm just totally lost in creating a for loop that sets the cookies. any help would be appreciated
Don't set multiple cookies - set one that contains an array (serialized). When you append to the array, read in the existing cookie first, add the data, then overwrite it.
// define the new value to add to the cookie
$ad_name = 'name of advert viewed';
// if the cookie exists, read it and unserialize it. If not, create a blank array
if(array_key_exists('recentviews', $_COOKIE)) {
$cookie = $_COOKIE['recentviews'];
$cookie = unserialize($cookie);
} else {
$cookie = array();
}
// add the value to the array and serialize
$cookie[] = $ad_name;
$cookie = serialize($cookie);
// save the cookie
setcookie('recentviews', $cookie, time()+3600);
You should not be creating one cookie for each recent search, instead use only one cookie. Try following this ideas:
Each value in the cookie must be
separated from the other with an
unique separator, you can use . ,
; or |. E.g: 200,201,202
When
retrieving the data from the cookie,
if it exists, use
explode(',',CookieName);, so you'll
end up with an array of IDs.
When adding
data to the cookie you could do,
again, explode(',',CookieName); to
create an array of IDs, then check if the
new ID is not in the array using
in_array(); and then add the value
to the array using array_push();.
Then implode the array using
implode(',',myString); and write
myString to the cookie.
That's pretty much it.

Categories