I have a simple like counter code, but the changes made disappear
after the page is refreshed.
Why does this happen, should this be done using PHP ?
How can this code be written much more efficiently, just for the knowledge anyway this is not the main question.
var like=document.getElementById("like__image");
addEventListener("click",function(){
var likeBox=document.getElementById("like__box");
var likeAdd=Number(likeBox.textContent)+1;
likeBox.textContent=likeAdd;
});
According to my understanding, you need this count to be global and to be available to all the users who access your page. Javascript is a client side script and the only file you can create using this is a cookie. In this case, you can't use cookies as it is created separately for each user.
For persistent result use a database or if you are not using a database for your application/website you can use a file (like .txt or .xml) to save your count and next time you can read from that file to display it again. But generally using database is recommended over a file system.
Using file system:
For main file we have a small php code to get the existing like count and an ajax function requesting like.php file when a user clicks on the like button.
HTML body:
<?php
$likeFile = 'like.txt';
/* check if the like file exists*/
if(file_exists($likeFile)) {
/* read the only the first file of the file as we don't intend to have more */
$file = fopen($likeFile, 'r');
$like = fgets($file);
fclose($file);
if($like) {
/* if we get the line split the string "likes=number" and get the existing count */
$likeCount = end(explode('=', $like));
}
} else {
$likeCount = 0;
}
?>
Like <span id="count"><?php echo $likeCount ?></span>
Javascript:
<script type="text/javascript">
function like(){
$.ajax({
type:"POST",
data: {like:true},
url: "like.php",
success: function(result){
$('#count').text(result);
}
});
}
</script>
In the like.php, we are checking for the post variable "like" just to be sure that we don't simply increment the like on direct access to this file. Here we are checking if the like.txt file exists or not. If true, it gets the first line like=1, get the count, increment the count and return it back to the ajax request. If false, it simply creates the file like.txt with like=1 for the first and only time.
<?php
if(isset($_POST['like']) && $_POST['like'] == true)
{
$likeFile = 'like.txt';
/* check if the like file exists*/
if(file_exists($likeFile)) {
/* read the only the first file of the file as we don't intend to have more */
$file = fopen($likeFile, 'r');
$like = fgets($file);
fclose($file);
if($like) {
/* if we get the line split the string "likes=number" and get the existing count */
$likeCount = end(explode('=', $like));
$likeCount++; /* increment the count by one */
file_put_contents($likeFile, 'likes=' . $likeCount); /* write the new count the same file and save it */
echo $likeCount; /* return the like count to the ajax request */
}
} else {
/* if file does not exist create it for the first time with count 1 */
file_put_contents($likeFile, 'likes=1');
echo '1';
}
} else {
return 'Something Wrong!';
}
Hope this is clear enough and helpful for you.
I suggest looking to cookies if you want to keep track of information across page reloads in a simple way. If you want the information to be available to anybody other than the user who created it, you'll likely need some form of server-side persistence such as a database.
The javascript is reloaded when the page is reloaded, so it's natural that the changes are lost as well.
You can, however, store them permanently, either in a web service, or preferrably in localStorage. Then you can retrieve from localStorage on page load.
Using PHP probably wouldn't help without storing it somewhere.
I don't think your code could be written that much more efficient.
Related
I did a searching in the similar questions, but I did not find a solution for my problem.
I would like to pass part of the URL from the index page to another function that is called if the user is autenticated. I can print the url variable in the next page, before the authentication. But since, the URL changes when the user is autenticated, I am getting a blank. How do I keep the value in the other page after the URL change?
In my index.php I call a js function that gey the course number when the page loads:
<body onload="myFunction()">
The myFunction is js code in data.js file that get part of the URL:
const url = location.href;
const urlCourse=url.split('=')[1];
document.getElementById("demo").innerHTML = urlCourse.toString(8);
}
In the callCourses.php, I have:
const course='<p id=demo></p>';
echo course; // It works!
if ($GLOBALS['authenticated'] ) { //here the URL will change because the user is now authenticated
echo course; // Error does not get the course number.
If the url is changed after authentication and if you have no access to changing that url, you will need to store that variable in one of the following places:
On the Server
Cookies
Session Cookies
// Before authentication
$_SESSION['courseNumber'] = getCourseNumberFromURL();
...
// In authenticated
$courseNumber = $_SESSION['courseNumber'];
Web Browser
Local Storage
Session Storage
// Before authentication
localStorage.set('courseNumber', getCourseNumberFromURL())
...
// After Authentication
const courseNumber = localStorage.get('courseNumber')
Edit - Expanded Answer
So, I think some clarification is needed here. PHP and JavaScript can't actually communicate with each other in the way I think you are understanding. You can use PHP to generate dynamic scripts, but once the html has been sent to the user, PHP can no longer interact with or manipulate that page. This means you can't access a JavaScript variable via PHP.
If we need to send JavaScript data over to our server, we perform one of two actions:
Create a custom form and send it to a PHP endpoint.
Make an XMLHttpRequest.
For 2, I recommend looking into fetch, which is highly supported in all modern browsers. (https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)
With that explanation out of the way, here is what I recommend doing for your case:
<?php
// Whatever you had before
// Store the courseNumber if we haven't already
if (!$_SESSION['courseNumber']) {
$_SESSION['courseNumber'] = $_GET['courseNumber'];
}
// More junk
// Now, let's check if authenticated:
if ($GLOBALS['authenticated'] ) {
// We are! Let's echo the courseNumber
echo $_SESSION['courseNumber'];
// Or, if you need to do it in a tag, try this:
// This directly inserts the data as the page is being generated to send by PHP
echo "<p id='demo'>".$_SESSION['courseNumber']."</p>";
// Or do this if you have to have the JavaScript insert the value for some reason
echo "<p id='demo'></p>";
echo "<script>document.querySelector('#demo').innerText = '" . $_SESSION['courseNumber'] . "'</script>";
}
?>
Summary: I have a solution I've built for monitoring variables and code processing in my environment. It works well for static pages, and the code below is a usable solution for that. However, if the page includes ajax calls which updates common variables after the page runs, this monitoring method isn't useful. To make it do so, I want to figure out a way to piggyback off an ajax call that will story information that's run in place, but I can't figure out how to work it into this code.
I have the following error checking file for php that I use in my development environment, the following using a magic function, register_tick_function, to store code as its run and show the variables for each step. Including it on a page allows the tick process to run...
<?php
register_tick_function(function(){
if (isset($GLOBALS["developer_debug"]) && $GLOBALS["developer_debug"] == 'active'){
$backtrace = debug_backtrace();
$line = $backtrace[0]['line'] - 1;
$file = $backtrace[0]['file'];
if ($file == __FILE__) return;
static $fp, $cur, $buf;
if (!isset($fp[$file])) {
$fp[$file] = fopen($file, 'r');
$cur[$file] = 0;
}
if (isset($buf[$file][$line])) {
$code = $buf[$file][$line];
} else {
do {
$code = fgets($fp[$file]);
$buf[$file][$cur[$file]] = $code;
} while (++$cur[$file] <= $line);
}
$line++;
if (defined('ERR_LOG')){ $error_log = ERR_LOG; } else {
$error_log = "../logs/error_log";
}
error_log("\n==========================================================\n", 3, $error_log);
error_log("\n $file : $line :: $code \n", 3, $error_log);
error_log("\n Variables: \n" . print_r(get_defined_vars(), true) . "\n", 3, $error_log);
$GLOBALS["_TROUBLESHOOTING"][] = "<code>\n $file : $line ::: ". htmlentities($code, ENT_QUOTES) . " \n</code>";
}
}, ["_SERVER" => $_SERVER, "_COOKIE"=>$_COOKIE, "_REQUEST"=>$_REQUEST, "_SESSION"=>$_SESSION, "_GLOBALS"=>$GLOBALS]);
// To use...
// declare(ticks=1);
// include_once('debug.php');
and in my direct page loads (such as index.php) I can include this js:
$(document).ready(function() {
var dev_top_button = document.createElement("Button");
dev_top_button.innerHTML = "Top Dev Data";
dev_top_button.style = "top:0;right:75%;position:absolute;z-index: 9999"
document.body.appendChild(dev_top_button);
var dev_bottom_button = document.createElement("Button");
dev_bottom_button.innerHTML = "Bottom Dev Data";
dev_bottom_button.style = "top:0;right:50%;position:absolute;z-index: 9999"
document.body.appendChild(dev_bottom_button);
$(dev_top_button).click(function(){
$("#debug_top").toggle();
});
$(dev_bottom_button).click(function(){
$("#debug_bottom").toggle();
});
});
and this on the page itself:
echo "<div class='debug_outer' id='debug_top'><h3>Developer Information</h3><div class='debug_inner'><pre>";
if (isset($GLOBALS['_TROUBLESHOOTING']) && is_array($GLOBALS['_TROUBLESHOOTING']) && ! empty($GLOBALS['_TROUBLESHOOTING'])) {
$troubleshooting_return_array = $GLOBALS['_TROUBLESHOOTING'];
} else {
$troubleshooting_return_array = ['Empty'];
}
echo print_r(["_COOKIE" => $_COOKIE, "_REQUEST" => $_REQUEST, "_SESSION" => $_SESSION, "_TROUBLESHOOTING" => $troubleshooting_return_array, "_SERVER" => $_SERVER, "_GLOBALS" => $GLOBALS], true);
echo '</pre></div></div>';
(And a similar output at the end of the page)
So, for most pages, this method to quickly check out page variables works great. And results in a nice javascript button to where I can quickly check what my start and end variables are on a page, along with a _TROUBLESHOOTING array I can easily dump whatever values I want to for quick looking over at page start and end.
So this system has been working pretty well for me for quite awhile now. The problem, however, comes with ajax calls. I've tried several different ways, but ajax calls generally want and expect data in a certain format. I'm -wanting- to make a third div for displaying data, along with a button for it, but I'm having a hard time figuring out how to piggyback any output data along with an ajax call, and it has to be called when the ajax is called in order to get how all the variables change and to track anything I'm troubleshooting. Sure, I can put an output to the error logs each time, but that's way slower on workflow and requires grepping through all the output since the last time the logs were cleared rather than simply seeing what my data is as I'm manipulating it.
Does anyone have a good idea to piggyback off of ajax calls to take use of these existing kinds of calls? Because messing with the returned values of the ajax calls will always result in bad data for the ajax call itself.
Solution was fairly straightforward after I thought about it for a while:
For ajax requests, send the data to a sub-array in session; a sub-array that's normally ignored by by the normal two print outs. Then, have a third button that's an ajax request that specifically fetches the value of that sub-array. The sub-array can be specifically filled with a sub-sub array for each ajax call that has been done, and then when fetched by the third button, it creates a div to share it and then empty the sub-array (otherwise it will bloat way too quickly), allow seeing all ajax calls since the last time the button was clicked (and appending them to the existing list, if still on the same page.)
I am trying to save a variable for counting the views of my personal website, I dont need to use php because its literally a viewcount. I know how to retrieve the count from the server using $.post, but how would I retrieve it (Edit: In the simplest way possible.)?
The website I'm trying to do it with is http://artsicleprojects.com/
Thanks in advance!
You will need PHP for this question, because it is dealing with server-side actions. First, you need to make a server-side script to increment the text file's number. Then, you will need to make a client-side script to make a request to the server. This script increments a number in the text file every time the request is made. Anyway, here's how I would do it (Note: this code is un-tested):
PHP:
<?php
/*Reads and collects current count.*/
$rfile = fopen("views.txt", "r") or die("Unable to open file!");
$count = fread($rfile,filesize("views.txt"));
fclose($rfile);
/*Increments the count.*/
$wfile = fopen("views.txt", "w");
$ncount = $count + 1;
fwrite($wfile, $ncount);
fclose($wfile);
?>
Note on code: for this code to work correctly, you may need a text file already made (views.txt), in the same directory as the PHP script, with a single "0" written in it.
JavaScript (with jQuery):
$.post("phpscript.php", function(data, status){
console.log(status);
});
This also is supposed to be in the same directory as the script to work.
I'm working on a piece of some software that will grab information from a mysql database and throw it onto our form dynamically. I'm running into a couple problems, though. I'll give a quick rundown of some functionality.
When the form loads, we have a ton of selection lists. These are all populated through arrays with various keys/values in php. When I select an option from one list, we'll call it a "customers" list, on-click I need to check if that customer has a special flag (stored in the database), and update another selection list based on that data.
How I understand the core of my solution is I need to have a javascript trigger on-click, which I have. The function that is called references a php page that handles the database query through a class and it's function.
<script>
function setService()
{ // The customer's "id" grabbed from the aforementioned customer selection list
customer = $('#customer').val();
$.get('thePage.php?key=setService?customer='+customer);
}
</script>
This function then talks to my php. The CustomerProvider class works 100%. I have tested that thoroughly on other pages. The problem arises when I try to actually get my selection list to change.
<?
if(isset($_GET['key']) && $_GET['key'] == 'setService')
{
$customer = $_GET['customer'];
$customer = intval($customer);
$s = CustomerProvider::getHasContract($customer);
if ($s != '')
{ ?> <script>var element = document.getElementById('ticket_service');
element.value = 'Contracted Hours';</script> <? }
else return;
}
?>
I'm coding in javascript literally for the first time ever and they kinda just threw me on this project. I know that my portion isn't being read as html or output as I intend. I know that every other part of the php and the first bit of javascript seems to be executing okay. Any help would be incredibly appreciated.
You seem to be on the right track but just for your own sanity here are a couple pointers. You shouldn't be returning Javascript from PHP for a situation like this. Instead you should be relying on Javascript promises to wait for a response containing just the data and continue the execution of your client code once you have your values returned. Take a look at this:
<script>
function setService() { // The customer's "id" grabbed from the aforementioned customer selection list
customer = $('#customer').val();
$.get('thePage.php?key=setService?customer=' + customer, function(data) {
console.log(data + ' was returned from your php script!');
if(data.hasContract=='1')
$('#ticket_service').val('Contracted Hours');
else
$('#ticket_service').val('No Contracted Hours');
});
}
</script>
And then your PHP script will just look like this:
<?
if(isset($_GET['key']) && $_GET['key'] == 'setService')
{
$customer = $_GET['customer'];
$customer = intval($customer);
$s = CustomerProvider::getHasContract($customer);
if ($s != ''){
$hasContract = 1;
}
else
$hasContract = 0;
echo json_encode(array('hasContract' => $hasContract));
}
?>
Therefore returning only the data needed for the client app to continue... not application logic
Your code isn't doing anything with the output of the PHP script. If you want the output to be inserted somewhere in the DOM, you should use .load() rather than $.get.
$("#someelement").load('thePage.php?key=setService?customer='+customer);
This will put the output into <div id="someelement">. If the output contains <script>, the script will be executed.
If you know the result is just a script, you could use $.getScript() instead of $.get. Then the output should just be the Javascript, not enclosed in HTML tags like <script>.
The problem here is that you are not using the result from the server. Your JavaScript may indeed be correct, but the browser never sees or runs it. From the docs:
Request the test.php page, but ignore the return results.
$.get( "test.php" );
Try this code, which utilizes the $.getJSON() shortcut function. I've written two versions, which you can see commented in the code. One moves the logic for determining contract status into the JS. Either should work.
PHP
<?
if(isset($_GET['key']) && $_GET['key'] == 'setService')
{
$customer = $_GET['customer'];
$customer = intval($customer);
$s = CustomerProvider::getHasContract($customer);
// Default output
$output = array('hasContract' => false);
// Customer has contract
if ($s != '')
$output['hasContract'] = true;
echo json_encode($output)
// Alternative: PHP just returns getHasContract, JS determines action
// (this would replace $ouput, conditional, and echo)
// echo json_encode(array("hasContract" => $s));
}
?>
JavaScript
function setService()
{ // The customer's "id" grabbed from the aforementioned customer selection list
customer = $('#customer').val();
$.getJSON('thePage.php?key=setService?customer='+customer, function(result) {
// Alternative
// if (result.hasContract != "")
if (result.hasContract)
{
var element = document.getElementById('ticket_service');
element.value = 'Contracted Hours';
}
});
}
As others wrote, your code doesn't do a thing with the GET variables.
the element "ticket_service" doesn't exists on page and even if it was, the code has no impact on the page that sent the request, you should print/echo the result you want to display/return and then manipulate it with JS/Jquery.
since I'm against GET and pro POST which is safer method, here's an example with POST:
JS:
function postSomthing(customerID){
$.post(
'thePage.php',
{key:'setService',customer:customerID},
function(data){
if(data!='x'){
$('#ticket_service').val(data)
}
else{alert('no ticket');/*whatever you want to do*/}
});
}
PHP(thePage.php) :
if(isset($_POST['key']) && $_POST['key'] == 'setService'){
$customer = intval($_POST['customer']);
$s = CustomerProvider::getHasContract($customer);
if ($s != ''){echo 'x';/* false, or whatever you want*/}
else{echo 'Contracted Hours';}
}
notes:
you should create an element with the id "ticket_service" in the viewed page and not in the backstage one.
This is an extension of the question here - Create a new page for different php ORDER BY statement?
I basically need to change a session variable and refresh the page at the same time using php (I think).
I.e. When I click <a href="#">Sort by date<a> on my page the following things happen:
$_SESSION['orderby']; = 'date';
Page refreshes
The session variable will then be changed and used later in my code.
I may need to use javascript? I'm not really sure, how would I do this?
EDIT
I do NOT want/need to be redirected to another page, the page just needs to be refreshed. Basically I need to click on a link (or button) and a php variable needs to be changed.
AJAX maybe?
What you would be able to do, is appending a GET-value to the URL and fetch that with PHP.
For instance:
<!-- HTML -->
Sort by <a href='?sort=date'>date</a>
// PHP:
if (isset($_GET['sort'])) {
$_SESSION['orderby'] = $_GET['sort'];
}
Additionally you can check if the GET-value is in a given array (to avoid errors from url-manipulation):
if (isset($_GET['sort'])) {
$sorts = array('date', 'ranking', 'page'); // ...
$_SESSION['orderby'] = (in_array($_GET['sort'], $sorts) ? $_GET['sort'] : 'STANDARD SORT');
}
use ajax send your var to php file to update session
$.ajax({
type: 'POST',
url: 'date.php',
data: {'date':date},
success: function(result) {
console.log(result)
}
});
date.php
<?php
session_start();
if(isset($_POST['date'])){
$_SESSION['date'] = $_POST['date'];
echo 'Date set to: '.$_SESSION['date'];
}
}