PHP counting varibles and redirecting - php

I've been scratching my head on the best way to accomplish this.
I'm getting 8 variables from a url:
a=imagine
b=lead
c=champion
d=champion
e=champion
f=champion
g=lead
h=champion
In this example there's 5 "champion" so I'd redirect to my champion page.
I've added them into an array:
$a = $_GET["a"]; $b = $_GET["b"]; $c = $_GET["c"]; $d = $_GET["d"]; $e = $_GET["e"]; $r = $_GET["r"]; $g = $_GET["g"]; $h = $_GET["h"];
$info = array($a,$b,$c,$d,$e,$f,$g,$h); print_r(array_count_values($info));
and then printed: Array ( [imagine] => 1 [lead] => 2 [champion] => 5 )
Am I doing it right? How can I use those values to redirect to my champion page as that's the highest count?

First, I agree that array_count_values is a good tool for this, but you don't need to make a new array with all the $a, $b, etc. variables. You can just do
$info = array_count_values($_GET);
After you have that, you can sort the array in descending order and take the first key to find the page you want to redirect to.
arsort($info);
$location = key($info);
I agree with the other answer that redirecting to a page based on user input is risky, and you should not redirect without first verifying that the location is valid. If you only have a few valid locations, this could be as simple as:
if (in_array($location, ['champion', 'lead', 'imagine'])) {
header("Location: yourdomain/$location");
}

If I understand you correctly:
$list = ['imagine' => 1 ,'lead' => 2, 'champion' => 5 ];
// find the highest count
$highest = max($list);
// check what page it is
foreach($list as $page=>$count){
// redirect
if($count === $highest){
header('Location: ' . $page);
exit();
}
}
Beware that relying on the user input is not safe. I'd also look up a white list for the pages.

Related

Removing a certain number out of a session array in PHP

I have a button next to all my 'shop items' that can remove one of the shop item, however i need it to just remove one, and not rid the entire array of the number, i thought this was possible by using a break statement when i found the number i want to remove, but it removes all of the numbers.
if (isset($_GET['remove']) && isset($_SESSION['shopitems'])) {
if (in_array($_GET['remove'], $_SESSION['shopitems'])) {
for ($i = 0; $i < sizeof($_SESSION['shopitems']); $i++) {
if ($_SESSION['shopitems'][$i] == $_GET['remove']) {
$shopArray = $_SESSION['shopitems'];
if(sizeof($shopArray) == 1) {
$_SESSION['shopitems'] = null;
$_SESSION['added'] = null;
} else {
array_splice($shopArray, $i, $i);
$_SESSION['shopitems'] = $shopArray;
}
break;
}
}
}
}
Here i check if the URL contains the remove variable and the session is set, once i have done this, i check if the array contains the number that is put in the URL, if so i'll start a for loop and check if the key index of the session shop items is equal to the URL variable, if so i want to remove it, however if i use array_splice, suddenly they are all gone, is this because of the function i am using? Or is the break not executing correctly?
Why don't you try array_search() and unset()? It's easier, have a look at the code below and adapt it to your situation:
$array = [1, 5, 6, 12];
$wantToRemove = 5;
$key = array_search($wantToRemove, $array);
unset($array[$key]);
var_dump($array);
You can format your $_SESSION['shopitems'] like this :
$_SESSION['shopitems'] = array (
"item_id" => "item_info",
"item2_id" => "item2_info",
...
)
and do unset($_SESSION['shopitems'][$_GET['remove']]).
Your code could be :
if (isset($_GET['remove']) && isset($_SESSION['shopitems']))
if (isset($_SESSION['shopitems'][$_GET['remove']]))
unset($_SESSION['shopitems'][$_GET['remove']])

php include() won't work?

I am having trouble getting my include() function to work in my code. Basically I have a the $order array that has the order that my pages will be shown in.
In this case: page numbers: 1,2,3,4,5,6 as seen in the $order array.
If I just post 6 include() function's with the exact path, the pages are shown, however if I try to include them under this for() loop it doesn't work.
$order Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 [5] => 6 )
$fields = 6;
The weird part is if I make the array 4,5,6,1,2,3 it work's perfectly:
$order Array ( [0] => 4 [1] => 5 [2] => 6 [3] => 1 [4] => 2 [5] => 3 )
Only show's first 3 pages
for($x = 0; $x < $fields; $x++)
{
$page_info = mysql_query("SELECT * FROM pages WHERE id='" . $order[$x] ."'");
$pageInfo = mysql_fetch_array($page_info);
$pageNum = $pageInfo['id'];
if($pageNum <= 6)
{
$pagePath = "page" . $pageNum . ".php";
include($pagePath);
}
}
What is confusing is I know it is reading each $pageInfo['id'] because this is the following output:
Output: 123456
for($x = 0; $x < $fields; $x++)
{
$page_info = mysql_query("SELECT * FROM pages WHERE id='" . $order[$x] ."'");
$pageInfo = mysql_fetch_array($page_info);
echo $pageInfo['id'];
}
This works
include("page1.php");
include("page2.php");
include("page3.php");
include("page4.php");
include("page5.php");
include("page6.php");
You probably have $x set to some number inside one of the includes. If it is only showing the first three, then perhaps in page3.php you have something like $x = 7;.
You obviously have the numbers coming out that you're expecting to see (1-6), because you are printing them to the screen. You've tried a suggestion of using trim which didn't get you any further.
My presumption is that your echo used for debugging is places outside your if statement, and that your if statement isn't running every time you expect it to. Firstly, try putting your echo inside the if statement to make sure that your output is the same, then put var_dump($pagePath); into it as well to ensure that your variable is what you're expecting.
Another thing you could try, you could make sure the file exists:
echo (file_exists($pagePath)) ? 'Exists' : 'Does not exist...';
You could post us the code in your included files to check that you aren't overwriting variables like $x or $pageNum etc from your includes - variables are global between includes and will overwrite eachother.
Finally, I know you'll have a good explanation for this, but this looks pretty longwinded to me, in this particular application, you could just do this:
for($i = 1; $i <= 6; $i++) {
include 'page' . $i . '.php';
}
SIDE NOTES:
mysql_* functions are deprecated and you should be using either PDO or mysqli. Resources:
- http://php.net/manual/en/book.pdo.php
- http://php.net/manual/en/book.mysqli.php
PHP's include function is a language control structure, not a function, so shouldn't be used with brackets: (for you downvoters, I'm not saying it can't, I'm saying it shouldn't)
// good:
include 'filename.php';
// bad:
include('filename.php');
1) I would not recommend fetching the DB on a loop but keeping your example:
You could try inside your loop something like
if($pageNum ){ //lets omit the <=6 for the test.
$pagePath = "page" . $pageNum . ".php";
echo "include($pagePath);";
}
and check the results, maybe you are getting something different to what you are expecting.
Try this
for($x = 0; $x < count($order); $x++)
{
$page_info = mysql_query("SELECT * FROM pages WHERE id=" . $order[$x]);
$pageInfo = mysql_fetch_array($page_info);
foreach($pageInfo as $p_info)
{
$pageNum = $p_info['id'];
break;
}
if($pageNum <= 6)
{
$pagePath = "page" . $pageNum . ".php";
require_once($pagePath);//If it can't find the file then it will kill page and show corresponding error
}
}

array_replace() / array_merge() | ( $_SESSION = array() ) argument is not an array?

I have this code for my school project and thought the code does its job on what i wanted it to do, i still keep on getting the error about $_SESSION[] is not an array argument when using the array_replace() and array_merge() functions:
Session is already initiated on the header:
// Start Session
session_start();
For initialising the $_SESSION['cart'] as an array:
// Parent array of all items, initialized if not already...
if (!isset($_SESSION['cart'])) {
$_SESSION['cart'] = array();
}
For adding products from a dropdown menu: - (Just to see how the session is assigned:)
if (isset($_POST['new_item'])) { // If user submitted a product
$name = $_POST['products']; // product value is set to $name
// Validate adding products:
if ($name == 'Select a product') { // Check if default - No product selected
$order_error = '<div class="center"><label class="error">Please select a product</label></div>';
} elseif (in_array_find($name, $_SESSION['cart']) == true) { // Check if product is already in cart:
$order_error = '<div class="center"><label class="error">This item has already been added!</label></div>';
} else {
// Put values into session:
// Default quantity = 1:
$_SESSION['cart'][$name] = array('quantity' => 1);
}
}
Then here is where the issue comes, when they try to update the product:
// for updating product quantity:
if(isset($_POST['update'])) {
// identify which product to update:
$to_update = $_POST['hidden'];
// check if product array exist:
if (in_array_find($to_update, $_SESSION['cart'])) {
// Replace/Update the values:
// ['cart'] is the session name
// ['$to_update'] is the name of the product
// [0] represesents quantity
$base = $_SESSION['cart'][$to_update]['quantity'] ;
$replacement = $_SESSION['cart'][$to_update] = array('quantity' => $_POST['option']);
array_replace($base, $replacement);
// Alternatively use array merge for php < 5.3
// array_merge($replacement, $base);
}
}
Note that both the functions array_replace() and array_merge() are updating the values and doing what the initial goal was, but the problem is that i still keep on getting that one argument($base) is not an array issue.
Warning: array_replace() [function.array-replace]: Argument #1 is not an array in ...
any suggestions for a better way to approach this issue would be a valuable help :)
Thanks for your help :)
Edit: The in_array_find() is a function that i use in replacement of in_array() as it doesn't apply to finding values in a multi-dimensional array: specifically 2 depth arrays:
found it from here and it works for me
The code for it is:
// Function for searching values inside a multi array:
function in_array_find($needle, $haystack, $strict = false) {
foreach ($haystack as $item => $arr) {
if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && in_array_r($needle, $item, $strict))) {
return true;
}
}
return false;
}
array_replace returns the replaced array. So you need to do:
$base=array_replace($base, $replacement);
Also, I suggest using named keys consistently throughout, as opposed to mixing named and numeric:
$base = $_SESSION['cart'][$to_update]['quantity'];
EDIT:
This may not be exactly what you're going for...
I set up a test situation without using $_SESSION, and I got the same error you did. I changed the code as follows and no longer get the error.
$sesh=array(
'cart'=>array(
0=>array(
'quantity'=>1
)
)
);
$to_update=0;
$new_quantity=5;
//$base = $sesh['cart'][$to_update]['quantity']; <--- changed this to line below
$base = $sesh['cart'][$to_update];
$replacement = $sesh['cart'][$to_update] = array('quantity' => $new_quantity);
$base=array_replace($base, $replacement);
echo"<pre>";print_r($base);echo"</pre>";
PHP FIDDLE: http://phpfiddle.org/main/code/mvr-shr
This have solved this issue:
Basically as per the structure: (Lets slice it into bits)
$_SESSION['cart'] = array();
then
$_SESSION['cart'][$name] = array('quantity' => 1);
finally:
$base = $_SESSION['cart'][$to_update]['quantity'] ;
$replacement = $_SESSION['cart'][$to_update] = array('quantity' => $_POST['option']);
array_replace($base, $replacement);
The reason why it says that the argument $base is not an array is because:
['quantity'] in $base is not an array as it forms the 'quantity' => 1 what we need is the array() value from the array('quantity' => 1); for it to be identified as an array.
So final answer should be: $base = $_SESSION['cart'][$to_update];
as there is only one array() recorded in where the $to_update resides so the replacement argument shall replace this identified array.
$_SESSION only exists when a Session starts. In order to do that you need to add on top of all your code session_start() otherwise the session will not start, unless you define it on php directives.

Cookie not save in foreach

People
I am trying to build a shopping cart, So i will have to pass the id , quantity and location_id to the function. In the function, i will look at the id and location_id passed in, if similar id and location_id is found. I will +1 to the item. However, if i use the function in array, it is not working.
Below is another function i built to test the variables pass to function within foreach.
But is does not say the first variable i passed in. it will only save the latest variable.
Below is my function codes :
static public function test($id , $per_min, $location_id_cart = 0){
echo $new_cart = $id.'-'.$per_min.'-'.$location_id_cart;
if(isset($_COOKIE['cart_item'])){
$last = $_COOKIE['cart_item'];
$testing = $last.','.$new_cart;
}else{
$testing = $new_cart;
}
$set = setcookie("cart_item", $testing, time()+3600);
var_dump($_COOKIE);
}
Below is my codes calling the function :
$id = 125;
$multi_location = array(636 , 789);
$multi_quantity = array();
$multi_quantity[636] = 5;
$multi_quantity[789] = 10;
$array_key = array_keys($multi_quantity);
foreach($array_key as $o){
if(!in_array($o , $multi_location)){
unset($multi_quantity[$o]);
}
}
$count = 0;
foreach($multi_location as $i){
ZCart::test($id , $multi_quantity[$i], $i);
}
My result :
'cart_item' => string '125-10-789' (length=10)
My expected result :
'cart_item' => string '125-5-636,125-10-789'
if i refresh my page, the result i get is this :
'cart_item' => string '125-10-789,125-10-789,125-10-789,125-10-789,125-10-789,125-10-789,125-10-789'
The cookie will only save the latest value given in the array. it does not save 125-5-636 to the cookie.
Why? can anyone help me on this please? Thank you!
try the following code:
static public function test($id , $per_min, $location_id_cart = 0){
$new_cart = $id.'-'.$per_min.'-'.$location_id_cart;
if(isset($_COOKIE['cart_item'])){
$last = $_COOKIE['cart_item'];
$testing = $last.','.$new_cart;
}else{
$testing = $new_cart;
}
$set = setcookie("cart_item", $testing, time()+3600);
//This line deals with adding to the cookie while the script is running
$_COOKIE['cart_item'] = $testing;
//var_dump($_COOKIE);
}
I have a feeling that the $_COOKIE array isn't being updated when you use setcookie(), this is why we update it manually with the line below it.
Also I'd remove the var_dump() call, along with echoing the $new_cart variable, as this will stop setcookie() from working. Instead, I would put it at the bottom of your calling code:
$id = 125;
$multi_location = array(636 , 789);
$multi_quantity = array();
$multi_quantity[636] = 5;
$multi_quantity[789] = 10;
$array_key = array_keys($multi_quantity);
foreach($array_key as $o){
if(!in_array($o , $multi_location)){
unset($multi_quantity[$o]);
}
}
$count = 0;
foreach($multi_location as $i){
ZCart::test($id , $multi_quantity[$i], $i);
}
var_dump($_COOKIE);
If you are implementing a shopping cart, I'd strongly recommend using sessions, which allow you to store the sensitive stuff on the server side away from harm and are in my experience much easier to work with than cookies!
Another option would be to store the user's cart in a database and then if they aren't logged in link to that cart with an ID stored in a cookie. This would allow the cart to stay around if the user closes their browser but keeps the secure stuff from the cookie. I hope this makes sense!
because you are not using array or different variable. Every time you call function in loop, It updates value of cart_item.It doesnot store value in different variables.

Cannot add new values to $_SESSION

I've a very strange problem with a session variable.
This var is an associative array. I create this in a page (page A) with a lot of filterable items. I save filters in a session var
$_SESSION['filter'] = Array ( 'm' => 'acrylic', 'a' => 'P', 'c' => 1960 );
the user can go to a detail page (page B) but here I have
$_SESSION['filter'] = Array ( 'm' => 'acrylic', 'a' => 'P');
the strange is that when I go i the detail page I miss the last item in the associative array
so I can't go back with the right filter info.
I build the session var in this function, the options are passed in the URL example: http://www.web.com/artworks/a-P/c-1960/o-private+collection
the argument $args with this URL will be this array('a-P', 'c-1960', 'o-private+collection')
private function filter($args){
// options
$f = array('a','c','u','t','m','o');
$a = array();
foreach($args as $i){
$t = explode('-', $i);
if (in_array($t[0], $f)){
$a[$t[0]] = urldecode($t[1]);
$this->suffix .= '/'.$i;
}
else if(is_numeric($i))
$a['pp'] = intval($i);
}
$_SESSION['filter'] = $a;
return $a;
}
I call this in page A, In the page B I don't call this function the only interaction is
if (isset($_SESSION['filter'])){
print_r($_SESSION);
...
Someone can help me?
Thanks
You have to call session_start somewhere in your script before adding new values into $_SESSION, otherwise they will not persist. Do you do that?
I don't know exactly but try with giving last varible value in quotes.

Categories