mobilestimulus Posted October 26, 2018 Share Posted October 26, 2018 Hello! I'm new here, and this is my first post. Let's say I have a list of four links I want to display on a page using php, call them 1 2 3 and 4. Now, when link 2 is visited, or any of the links, the destination url opens in a new window, a cookie is set onclick and the page reloads, and the visited link goes to the bottom of my list, and the new the new order is: 1 3 4 2. php function to read cookie and calculate the new order here echo '<ul> <li> <a href="https://current-page" onClick="window.open(\'http://page-1\'); setCookie(\''.$cookie_name.'\', \'1\', '.$cookie_expires_time.');">Link One</a> </li> <li> <a href="https://current-page" onClick="window.open(\'http://page-2\'); setCookie(\''.$cookie_name.'\', \'2\', '.$cookie_expires_time.');">Link Two</a> </li> <li> <a href="https://current-page" onClick="window.open(\'http://page-3\'); setCookie(\''.$cookie_name.'\', \'3\', '.$cookie_expires_time.');">Link Three</a> </li> <li> <a href="https://current-page" onClick="window.open(\'http://page-4\'); setCookie(\''.$cookie_name.'\', \'4\', '.$cookie_expires_time.');">Link Four</a> </li> </ul>'; echo 'some javascript function to enable set cookie on click'; Any help is much appreciated. Thanks. Quote Link to comment Share on other sites More sharing options...
requinix Posted October 26, 2018 Share Posted October 26, 2018 You can get the cookie value in PHP using $_COOKIE[$cookie_name]. All those links look the same except for the target and the text. Use an array to hold all four of them. $links = [ 1 => ["url" => "http://www.example.com/page-1", "text" => "Link One"], ... ]; Check if the cookie exists. If it does, take the value from it and check if it's one of the keys in $links. If it is, remove that value and put it at the end of the list. if (isset(/* cookie */)) { $id = // value from cookie if (isset($links[$id])) { $link = // item in $links array unset($links[$id]); // remove $links[$id] = $link; } } Finally output the links using a foreach on $links. 1 Quote Link to comment Share on other sites More sharing options...
mobilestimulus Posted October 26, 2018 Author Share Posted October 26, 2018 (edited) 2 hours ago, requinix said: Use an array to hold all four of them I appreciate you, and I'm learning. I'm sure I'm getting it wrong, as this is not as expected: $links = [ 1 => ["url" => "http://www.example.com/page-1", "text" => "Link One"], 2 => ["url" => "http://www.example.com/page-1", "text" => "Link Two"], 3 => ["url" => "http://www.example.com/page-1", "text" => "Link Three"], 4 => ["url" => "http://www.example.com/page-1", "text" => "Link Four"] ]; foreach ( $links as $key => $value ) { echo "$key=$value<br />"; } Edited October 26, 2018 by mobilestimulus added code Quote Link to comment Share on other sites More sharing options...
requinix Posted October 26, 2018 Share Posted October 26, 2018 You are looping over $links. What are going to be the keys in $key and what are going to be the values in $value? 1 Quote Link to comment Share on other sites More sharing options...
mobilestimulus Posted October 26, 2018 Author Share Posted October 26, 2018 1 hour ago, requinix said: You are looping over $links. What are going to be the keys in $key and what are going to be the values in $value? Okay. Thank you so much! Way more helpful than other places for sure! I think I am almost there... What goes here?: $link = // item in $links array Quote Link to comment Share on other sites More sharing options...
mobilestimulus Posted October 26, 2018 Author Share Posted October 26, 2018 @requinix Okay, again, I'm getting there, slowly, but making progress. Your help is appreciated. However, with each link visit, all that happens is the visited link goes to the bottom of the list. Is that because the cookie doesn't have information about the current order of the list? For instance, on the first visit, I use Link 1, the new order is 2 3 4 1. Now, if i visit link 3 next, the order should now be 2 4 1 3, but instead the order is now 1 2 4 3. Am I still messing up, or do I need to add something else? My code so far: $cookie_name = "link_order_test"; $cookie_expires_time = '1440'; $links = [ 1 => ["url" => "http://www.google.com/", "text" => "Google"], 2 => ["url" => "https://forums.phpfreaks.com/topic/307814-how-to-rotate-links-using-php-and-cookie/?tab=comments#comment-1561732", "text" => "phpfreaks.com"], 3 => ["url" => "https://www.w3schools.com/", "text" => "w3schools"], 4 => ["url" => "http://php.net/manual/en/language.types.array.php", "text" => "php.net"] ]; if(isset($_COOKIE[$cookie_name])) { $id = $_COOKIE[$cookie_name]; if (isset($links[$id])) { $link = $links[$id]; // item in $links array unset($links[$id]); // remove $links[$id] = $link; } } else { echo 'Cookie Not Found'; } echo '<ul>'; foreach ( $links as $key => $value ) { echo '<li><a href="/test/" onClick="window.open(\''.$value[url].'\'); setCookie(\''.$cookie_name.'\', \''.$key.'\', '.$cookie_expires_time.');">'.$value[text].'</a></li>'; } echo '</ul>'; echo '<a href="/test/" onClick="setCookie(\''.$cookie_name.'\', \'0\', -'.$cookie_expires_time.');">Reset List</a>'; echo '<script> function setCookie(cname, cvalue, exdays) { var d = new Date(); d.setTime(d.getTime() + (exdays*60*1000)); var expires = "expires="+d.toUTCString(); document.cookie = cname + "=" + cvalue + "; " + expires; } </script>'; Quote Link to comment Share on other sites More sharing options...
requinix Posted October 26, 2018 Share Posted October 26, 2018 Okay, so you want to keep track of what they visited? That does sound like cookies alright*, but simply knowing the most recent link won't be enough. You need to store all the links... although storing all the links is a hassle, so instead store just the ID numbers of the links. Rewrite your script a bit: Set up the cookie and link information. Use $_GET["link"] as the way to know the most recently clicked link, instead of the cookie. For the moment you're getting rid of cookies entirely. Change your HTML so that you're passing the link ID through the query string as /test/?link=number. Still no cookies. Make sure your script continues to work. No cookies for now, but clicking the links should continue to take you back to the same page with the visited link at the bottom of the list. It won't remember like you want, but we're just making sure everything still works with the changes in place. While you're in there, temporarily put a setcookie($cookie_name, "", 1); This will clear out the existing cookie so we can reuse it for something else. Once you've made sure everything is still working, remove that line and you can start on using the cookie again. This time the cookie will store the entire set of IDs like 1,2,3,4. If the cookie is set then get that string value from it, and if not then use 1,2,3,4 as the default - so not having a cookie is fine. explode that value into an array you can stick in a variable. Now change your foreach loop so that it goes over that array variable instead of $links. This new variable will only have values in it - its keys are useless. Use each value to get the link information from $links, then to display the link. * Actually in the Real World we wouldn't use cookies for this. 1 Quote Link to comment Share on other sites More sharing options...
mobilestimulus Posted October 27, 2018 Author Share Posted October 27, 2018 @requinix 17 hours ago, requinix said: This time the cookie will store the entire set of IDs like 1,2,3,4. If the cookie is set then get that string value from it, and if not then use 1,2,3,4 as the default - so not having a cookie is fine. explode that value into an array you can stick in a variable. I'm having trouble with this part. Can you give me a "push" in the right direction? Here is what I have now: <?php $link_order = htmlspecialchars($_GET["link_order"]); $cookie_name = "link_order_test"; $cookie_expires_time = '1440'; $links = [ 1 => ["url" => "http://www.google.com/", "text" => "Google"], 2 => ["url" => "https://forums.phpfreaks.com/topic/307814-how-to-rotate-links-using-php-and-cookie/?tab=comments#comment-1561732", "text" => "phpfreaks.com"], 3 => ["url" => "https://www.w3schools.com/", "text" => "w3schools"], 4 => ["url" => "http://php.net/manual/en/language.types.array.php", "text" => "php.net"] ]; $id = $link_order; if (isset($links[$id])) { $link = $links[$id]; // item in $links array unset($links[$id]); // remove $links[$id] = $link; } $pieces = explode(" ", $links[$key]); print_r($pieces); echo '<ul>'; foreach ( $links as $key => $value ) { echo '<li><a href="/test/?link_order='.$key.'" onClick="window.open(\''.$value[url].'\'); setCookie(\''.$cookie_name.'\', \''.$key.'\', '.$cookie_expires_time.');">'.$value[text].'</a></li>'; } echo '</ul>'; ?> Quote Link to comment Share on other sites More sharing options...
mobilestimulus Posted October 27, 2018 Author Share Posted October 27, 2018 So I think I have all of the parts here, just not sure how to implement them. Again, any more help you're willing to give is appreciated. Here is what I have now: <?php $link_order = htmlspecialchars($_GET["link_order"]); $cookie_name = "link_order_test"; $cookie_expires_time = '1440'; if(isset($_COOKIE[$cookie_name])) { $number_set = $_COOKIE[$cookie_name]; }else{ $number_set = '1,2,3,4'; echo 'Cookie Not Found <br />'; } $pieces = explode(",", $number_set); $links = [ 1 => ["url" => "http://www.google.com/", "text" => "Google", "number" => "1"], 2 => ["url" => "https://forums.phpfreaks.com/topic/307814-how-to-rotate-links-using-php-and-cookie/?tab=comments#comment-1561732", "text" => "phpfreaks.com", "number" => "2"], 3 => ["url" => "https://www.w3schools.com/", "text" => "w3schools", "number" => "3"], 4 => ["url" => "http://php.net/manual/en/language.types.array.php", "text" => "php.net", "number" => "4"] ]; foreach ($pieces as $value1) { echo "$value1<br>"; } $id = $link_order; if (isset($links[$id])) { $link = $links[$id]; // item in $links array unset($links[$id]); // remove $links[$id] = $link; } echo '<ul>'; foreach ( $links as $key => $value ) { echo '<li><a href="/test/?link_order='.$value[number].'" onClick="window.open(\''.$value[url].'\'); setCookie(\''.$cookie_name.'\', \''.$value[number].'\', '.$cookie_expires_time.');">'.$value[text].'</a></li>'; } echo '</ul>'; if(isset($_COOKIE[$cookie_name])) { echo '<a href="/test/" onClick="setCookie(\''.$cookie_name.'\', \'0\', -'.$cookie_expires_time.');">Reset List</a>'; } echo '<script> function setCookie(cname, cvalue, exdays) { var d = new Date(); d.setTime(d.getTime() + (exdays*60*1000)); var expires = "expires="+d.toUTCString(); document.cookie = cname + "=" + cvalue + "; " + expires; } </script>'; ?> Quote Link to comment Share on other sites More sharing options...
requinix Posted October 27, 2018 Share Posted October 27, 2018 Let's trim off some of the older code and get something simple that won't do everything you need yet. <?php // cookie information $cookie_name = "link_order_test"; $cookie_expires_time = 1440; // links $links = [ 1 => [ "url" => "http://www.google.com/", "text" => "Google" ], 2 => [ "url" => "https://forums.phpfreaks.com/topic/307814-how-to-rotate-links-using-php-and-cookie/?tab=comments#comment-1561732", "text" => "phpfreaks.com" ], 3 => [ "url" => "https://www.w3schools.com/", "text" => "w3schools" ], 4 => [ "url" => "http://php.net/manual/en/language.types.array.php", "text" => "php.net" ] ]; // list of links to use from the cookie if (isset($_COOKIE[$cookie_name])) { $number_set = $_COOKIE[$cookie_name]; } else { $number_set = '1,2,3,4'; } $pieces = explode(",", $number_set); // loop to show the links echo '<ul>'; foreach ($pieces as $number) { $value = $links[$number]; echo '<li><a href="/test/?link_order=' . $number . '" onClick="window.open(\'' . $value["url"] . '\');">' . $value["text"] . '</a></li>'; } echo '</ul>'; ?> 1. I removed the "number" from $links because you already have the number: it's the array key 2. It's not shuffling $links yet but it does get $number_set 3. Nothing to set the cookie 4. Using $pieces to control the order of what links to show 5. Quotes with $value["url"] and $value["text"] because the key in there is a string, not a number, and strings need quotes If you look at the page in your browser it seems like it might work because it will open the popup and reload the page, but it doesn't change the links. Add that in next. <?php $pieces = explode(",", $number_set); $pieces = array_combine($pieces, $pieces); // update if there is an update to make if (isset($_GET["link_order"])) { $link_order = $_GET["link_order"]; if (isset($pieces[$link_order])) { unset($pieces[$link_order]); $pieces[$link_order] = $link_order; } } ?> This is a little different from before. $pieces is going to control what links show in what order, and to rearrange what's in it in the easiest way it helps to have the numbers as keys - so isset() will work. array_combine will do that by creating a new array using one with keys and one with values, and with $pieces as both we get an array like [1=>1, 2=>2, 3=>3, 4=>4]. With that the first time we'll be back to having the page update for the link you click but not remembering earlier clicks. That's because we aren't doing anything with the cookie. So now do that. But instead of changing the cookie in Javascript on the client, have PHP do it on the server. That is where cookies are normally handled. <?php if (isset($_GET["link_order"])) { ... $number_set = implode(",", $pieces); // array back into string setcookie($cookie_name, $number_set, time() + $cookie_expires_time); } ?> Note that setcookie() wants the expiration time as a (future) point in time, not a duration. Quote Link to comment Share on other sites More sharing options...
mobilestimulus Posted October 27, 2018 Author Share Posted October 27, 2018 @requinix Alright. So, I don't understand what is happening yet, but I will put some more time into learning about it. In the meantime, are you saying that I should now be here?: <?php // cookie information $cookie_name = "link_order_test"; // cookie expires 2 minutes from page load $cookie_expires_time = 120; // links $links = [ 1 => [ "url" => "http://www.google.com/", "text" => "Google" ], 2 => [ "url" => "https://forums.phpfreaks.com/topic/307814-how-to-rotate-links-using-php-and-cookie/?tab=comments#comment-1561732", "text" => "phpfreaks.com" ], 3 => [ "url" => "https://www.w3schools.com/", "text" => "w3schools" ], 4 => [ "url" => "http://php.net/manual/en/language.types.array.php", "text" => "php.net" ] ]; // list of links to use from the cookie if (isset($_COOKIE[$cookie_name])) { $number_set = $_COOKIE[$cookie_name]; } else { $number_set = '1,2,3,4'; } $pieces = explode(",", $number_set); $pieces = array_combine($pieces, $pieces); // update if there is an update to make if (isset($_GET["link_order"])) { $link_order = $_GET["link_order"]; if (isset($pieces[$link_order])) { unset($pieces[$link_order]); $pieces[$link_order] = $link_order; } $number_ set = implode(",", $pieces); // array back into string setcookie($cookie_name, $number_set, time() + $cookie_expires_time); } // loop to show the links echo '<ul>'; foreach ($pieces as $number) { $value = $links[$number]; echo '<li><a href="/test/?link_order=' . $number . '" onClick="window.open(\'' . $value["url"] . '\');">' . $value["text"] . '</a></li>'; } echo '</ul>'; ?> Quote Link to comment Share on other sites More sharing options...
requinix Posted October 27, 2018 Share Posted October 27, 2018 Yes, except for maybe a syntax error that PHP would tell you about immediately if it were there. Quote Link to comment Share on other sites More sharing options...
mobilestimulus Posted October 27, 2018 Author Share Posted October 27, 2018 How do I do that? Quote Link to comment Share on other sites More sharing options...
requinix Posted October 27, 2018 Share Posted October 27, 2018 Do... what? Just run it and see what happens. If it works then it works. Quote Link to comment Share on other sites More sharing options...
mobilestimulus Posted October 27, 2018 Author Share Posted October 27, 2018 It doesn't work now, but did earlier. something about this line I guess: $number_ set = implode(",", $pieces); // array back into string Quote Link to comment Share on other sites More sharing options...
requinix Posted October 27, 2018 Share Posted October 27, 2018 Look at it. See anything wrong? Quote Link to comment Share on other sites More sharing options...
mobilestimulus Posted October 27, 2018 Author Share Posted October 27, 2018 Ha! Yes. An extra space....Fixed. Still not as expected however. Do I need to do more yet? Code as of now: <?php // cookie information $cookie_name = "link_order_test"; // cookie expires 2 minutes from page load $cookie_expires_time = 120; // links $links = [ 1 => [ "url" => "http://www.google.com/", "text" => "Google" ], 2 => [ "url" => "https://forums.phpfreaks.com/topic/307814-how-to-rotate-links-using-php-and-cookie/?tab=comments#comment-1561732", "text" => "phpfreaks.com" ], 3 => [ "url" => "https://www.w3schools.com/", "text" => "w3schools" ], 4 => [ "url" => "http://php.net/manual/en/language.types.array.php", "text" => "php.net" ] ]; // list of links to use from the cookie if (isset($_COOKIE[$cookie_name])) { $number_set = $_COOKIE[$cookie_name]; } else { $number_set = '1,2,3,4'; } $pieces = explode(",", $number_set); $pieces = array_combine($pieces, $pieces); // update if there is an update to make if (isset($_GET["link_order"])) { $link_order = $_GET["link_order"]; if (isset($pieces[$link_order])) { unset($pieces[$link_order]); $pieces[$link_order] = $link_order; } $number_set = implode(",", $pieces); // array back into string setcookie($cookie_name, $number_set, time() + $cookie_expires_time); } // loop to show the links echo '<ul>'; foreach ($pieces as $number) { $value = $links[$number]; echo '<li><a href="/test/?link_order=' . $number . '" onClick="window.open(\'' . $value["url"] . '\');">' . $value["text"] . '</a></li>'; } echo '</ul>'; ?> Quote Link to comment Share on other sites More sharing options...
requinix Posted October 27, 2018 Share Posted October 27, 2018 I copied that and ran it and it works for me. How is it working now and how do you expect it to work? Is there any more code being run than besides what you've shown here? Particularly anything that's happening before this code? Quote Link to comment Share on other sites More sharing options...
mobilestimulus Posted October 27, 2018 Author Share Posted October 27, 2018 Wait. I think it is working. I cleared the cookie. Let me test. Again, thank you so much.... Quote Link to comment Share on other sites More sharing options...
mobilestimulus Posted October 27, 2018 Author Share Posted October 27, 2018 Okay, working as expected. Two things: I should be using: htmlspecialchars($_GET["link_order"]); to prevent injection. Correct? Is there anything else I should do to protect this code? Quote Link to comment Share on other sites More sharing options...
requinix Posted October 27, 2018 Share Posted October 27, 2018 1. XSS is about what happens with output. You aren't using that value with output so there is no risk of injection. 2. htmlspecialchars() should only be used right when something is about to be outputted. Not any earlier, and definitely not when you first get the value from the user/cookie/wherever. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.