How to show a link counter change live? - php

What this code does is taking links from the db and compare it to a keyword, if it compares then KeywordCounter++, and in every time LinkCounter++
I want to type LinkCounter after every link it goes through but in the code I wrote it only shows me after the loop ends (after all the links crosses). How can I see the LinkCounter every time a link is checked?
How will I be able to see live the counter jumps?
<?php //holdes the db connection include('Connect.php');
$KeyWord = 'googoo';
$LinkCounter = "0";
$KeywordCounter = "0";
$query = mysql_query("SELECT * FROM doalgo where Pass != '0'") or die(mysql_error());
while ($info = mysql_fetch_array($query)) {
$id = $info['id'];
$link = $info['link'];
$num_rows = mysql_num_rows($query);
mysql_query("UPDATE doalgo SET Pass = '1' WHERE id = '$id'");
$CurrentFile = file_get_contents($link);
if (!strpos($CurrentFile, $KeyWord)) {
//nothing
} else {
mysql_query("UPDATE doalgo SET Posted = '1' WHERE id = '$id'");
$KeywordCounter++;
}
$LinkCounter++;
if ($id == $num_rows) {
die();
}
}
echo "<br />KeywordCounter: ".$KeywordCounter;
echo "<br />LinkCounter: ".$LinkCounter;
? >

Its better you calculate the average speed of update (for example number of updates per hour) and send just a single integer to the browser every 1 hour.
using jquery you can change the value shown to user with that speed.

If I understand your question correctly, you want the web page to display immediately, then constantly update the LinkCounter display as the SQL queries progress?
If this is a correct understanding, to do this requires AJAX. Your server has to send constant updates to the web browser every time $LinkCounter is updated, then the JavaScript running in the browser will update the display with that information. Obviously, it's a much more complicated thing to do than what your script currently does. It's an entirely different design pattern.
If this is truly something you want to learn to do, there are many books on the subject of AJAX, or google can help you, too.

Related

how do I select a url parameter?

So I have a backoffice called biblioteca.php where I have some requests and I can validate them trough a button called "Validar". That button redirects to a page like this: http://localhost/pap_16gpsi21/validacao.php?nproposta=87 where I can fill the form and submit.
What I want is to validate the request related to that url.
Example:
I've a request and his number is 90, I click on "Validar", then redirects me to a page like this http://localhost/pap_16gpsi21/validacao.php?nproposta=90, I fill the form and click submit. Then it updates the request number 90 in the database ($updateEstado = "UPDATE propostas SET validacao='Validado'";)
biblioteca.php
$selectProp = "SELECT nproposta, prioridade,disponibilidade,validacao,
autorizacao,aquisicao,registo,biblioteca,docente
FROM propostas
ORDER BY nproposta DESC";
$resultado = mysqli_query($ligaBD, $selectProp);
if (mysqli_num_rows($resultado) > 0) {
// output data of each row
while($row = mysqli_fetch_assoc($resultado)) {
<td><a class="btn btn-default" href="./validacao.php?nproposta=<?= $row["nproposta"] ?>">Validar</a></td>
valida.php
// gets nproposta from propostas
$npropostaLinha = "SELECT nproposta FROM propostas";
$resultado=mysqli_query($ligaBD, $npropostaLinha);
$nproposta = "";
printf($npropostaLinha);
$row = mysqli_fetch_array($resultado,MYSQLI_NUM);
printf("==> ");
print_r($row[0]);
$nproposta = $row[0];
$insertValidacao = "INSERT INTO validacao
(nproposta,nome_validacao,nif_validacao,
email_validacao,preco_validacao)
VALUES ($nproposta,'$nome_validacao','$nif_validacao',
'$email_validacao','$preco_validacao')";
$updateEstado = "UPDATE propostas SET validacao='Validado'";
$resultado = mysqli_query($ligaBD, $insertValidacao);
$resultado = mysqli_query($ligaBD, $updateEstado);
The problem is that if I have 3 requests (90,91,92) and I decide to validate just the number 91 it updates the first which is the number 90.
Also I know this isnt the safest method but this is just a test.
Hopefully, I explained explicitly. Sorry for any grammatical mistakes. Thank you
You need a couple of changes in your code as there are a few logical mistakes that I think you want to avoid.
You need to target a variable to specify from your SELECT that you desire a specific proposta;
You need, when updating, to specify which row, otherwise you will update every single record in your DB;
For such, go to your valida.php and add the following:
At the very top, check you have the variable ready
if (!isset($_POST['nproposta']) || empty($_POST['nproposta'])) {
//Do here what you desire to stop the script from running. Redirect back if you wish;
echo "No proposal id was found";
die;
}
$nPropostaID = $_POST['nproposta'];
Once you have your ID to target the row in your DB, update your query to consider it;
UPDATE propostas SET validacao='Validado' WHERE nproposta = $nPropostaID
Go to your form view and add below line within the form
<input type='hidden' value="<?php echo $_GET['nproposta']?>" name="nproposta">
NOTE: Because you mentioned you are aware of the SQL injections and this is a test I won't go with those, but always good to remember to be careful with them :) My proposal for the queries is just to get you going and in no way good for a script!

PHP/MySQL - Run actions from background / Dealing with a longer-running method

I have a form in PHP that saves some data into a database. However, after a successful insert, the PHP function below executes to arrange every entry by a "visible" ID column (called correlativo in this case).
function ordenar_ids()
{
$sql = "SELECT DISTINCT(DATE_FORMAT(fecha, '%Y')) FROM emergencias ORDER BY fecha";
$results = mysql_query($sql);
$anios = [];
while ($row = mysql_fetch_array($results))
array_push($anios, $row[0]);
foreach($anios as $anio)
{
$sql = "SELECT id_emergencia FROM emergencias WHERE fecha LIKE '".$anio."%' ORDER BY fecha ASC;";
$results = mysql_query($sql);
$correlativo = 1;
while ($row = mysql_fetch_array($results))
{
$sql = "UPDATE emergencias SET correlativo = $correlativo WHERE id_emergencia = '".$row[0]."';";
mysql_query($sql);
$correlativo++;
}
}
return 1;
}
Initial (local) tests were successful, however when we tested this in a production environment we noticed this process is taking way too long (about 15 seconds on average) which is detrimental to the user experience.
Is it possible to run this function in the background after the user has submitted the form? If it's not possible, how can we work around this problem?
Additional Data:
The user doesn't need a return value of this function, nor it's needed for the following actions that happens after.
You can't easily run a mysql query in the background. But xou could start a new php script in background: http://php.net/manual/de/function.exec.php#86329
But better would be to improve the script performance itself. I think, you can improve it by using one "update ... select" query, avoiding LIKE % or using mysql triggers.

Query isn't inserting into database [duplicate]

This question already has answers here:
Can I mix MySQL APIs in PHP?
(4 answers)
Closed 6 years ago.
I am attempting to implement a click count system. I am using the following code in this link Click here to see code, but changing it to modern standards. Initially I received errors for the msqli_real_escape_ string, but I believed I resolved it(no errors). Now, I am not receiving any errors at all, but the query is not sending into my database. I am using ini_set('display_errors', 1);
error_reporting(E_ALL); for error checking. Also I have my $con and session in and ini file that I call, so the session and connection are not issues.
Does anyone see what I am doing wrong or is there a good way I can check to see what isn't working?
//create current page constant
$curPage = mysqli_real_escape_string($con,htmlspecialchars($_SERVER['PHP_SELF']));
//set number of clicks variable to 0
$clicks = 0;
//do not recount if page currently loaded
if($_SESSION['page'] != $curPage) {
//set current page as session variable
$_SESSION['page'] = $curPage;
$click_sql = "
SELECT *
FROM click_count
WHERE page_url = ?
";
if (!$click_stmt = $con->prepare($click_sql)) {
$click_stmt->bind_param("s", $curPage);
$click_stmt->execute();
$num_rows = $click_stmt->fetchColumn();
if (!$click_stmt->errno) {
// Handle error here
}
$stmt->bind_result($click_id, $page_url, $page_count);
} elseif ($num_rows == 0) {
//try to create new record and set count for new page to 1
//output error message if problem encountered
$click_insert_stmt = "
INSERT INTO click_count
(page_url, page_count)
VALUES(?, ?)";
if(!$click_stmt = $con->prepare($click_insert_stmt)) {
$click_insert_stmt->execute(array('$curPage',1));
echo "Could not create new click counter.";
}
else {
$clicks= 1;
}
} else {
//get number of clicks for page and add 1 fetch(PDO::FETCH_BOTH)
while($click_row = $click_insert_stmt->fetch(PDO::FETCH_BOTH)) {
$clicks = $row['page_count'] + 1;
//update click count in database;
//report error if not updated
$click_update_stmt = "
UPDATE click_count
SET page_count = ?
WHERE page_url = ?
";
if(!$click_stmt = $con->prepare("$click_update_stmt")) {
$click_update_stmt->execute(array('$clicks', '$curPage'));
echo "Could not save new click count for this page.";
}
}
}
}
Edit: New Updated Code
// ********Page count************
//create current page constant
$curPage = mysqli_real_escape_string($con,($_SERVER['PHP_SELF']));
//set number of clicks variable to 0
$clicks = 0;
//do not recount if page currently loaded
if($_SESSION['page'] != $curPage) {
//set current page as session variable
$_SESSION['page'] = $curPage;
$click_sql = "
SELECT *
FROM click_count
WHERE page_url = ?
";
if (!$click_stmt = $con->prepare($click_sql)) {
$click_stmt->bind_param("s", $_SERVER['PHP_SELF']);
$click_stmt->execute();
$num_rows = $click_stmt->fetchColumn();
if (!$click_stmt->errno) {
// Handle error here
}
$stmt->bind_result($click_id, $page_url, $page_count);
} elseif ($num_rows == 0) {
//try to create new record and set count for new page to 1
//output error message if problem encountered
$click_insert_stmt = "
INSERT INTO click_count
(page_url, page_count)
VALUES(?, ?)";
if(!$click_stmt = $con->prepare($click_insert_stmt)) {
$click_insert_stmt->execute(array($curPage,1));
echo "Could not create new click counter.";
}
else {
$clicks= 1;
}
} else {
//get number of clicks for page and add 1 fetch(PDO::FETCH_BOTH)
while($click_row = $click_insert_stmt->fetch(PDO::FETCH_BOTH)) {
$clicks = $row['page_count'] + 1;
//update click count in database;
//report error if not updated
$click_update_stmt = "
UPDATE click_count
SET page_count=page_count+1
WHERE page_url = ?
";
if(!$click_stmt = $con->prepare("$click_update_stmt")) {
$click_update_stmt->execute(array($curPage));
echo "Could not save new click count for this page.";
}
}
}
}
It looks like you're doing a lot of stuff like this:
$click_update_stmt->execute(array('$clicks', '$curPage'));
I'm not sure where you picked up this habit of quoting variables as strings, but you need to drop it. '$x' and $x are two hugely different things. In the first case it's literally '$x' and in the second case it's whatever the $x variable happens to represent.
Fix it like this:
$click_update_stmt->execute(array($clicks, $curPage));
Also since you're using prepared statements, which by the way is great, you do not need to and should not manually escape your values. Applying them to placeholders with bind_param is the safe way of doing it. Doing any other escaping mangles the data.
Just bind directly to the source:
$click_stmt->bind_param("s", $_SERVER['PHP_SELF']);
Don't arbitrarily run things like htmlspecialchars on input out of paranoia or because you're doing cargo-cult programming and you saw it done in a YouTube tutorial somewhere. That function is intended to be used to display values only, not store them. Data in your database should be as raw as possible.
There's a lot of problems with this code, and one of them that has me confused is why there's so much code. Remember SELECT * and then binding results to arbitrary variables is trouble, your schema might change and then your code is out of sync. Whenever possible fetch rows as an associative array if doing this, then all you have to worry about is renamed ore removed columns.
The biggest problem is this is subject to race conditions because it doesn't use an atomic increment. When writing counters, always do your updates as operations that are a single statement:
UPDATE click_count SET page_count=page_count+1 WHERE page_url=?
Your approach of reading the count, incrementing it, and then writing it back into the database means that you're inviting problems if another operation runs concurrently, something very likely on click-counter code.

Long polling JQUERY chat using sleep()

The following code makes the web loading for like 10 minutes and I dont know why!
function chatheartbeat(){
include("config.php");
$useradn = $_SESSION['displayname'];
$query = "select * from chat where (userbdn = '".$useradn."' AND isread = 1) order by id ASC";
$result = mysql_query($query , $link);
$num_rows = mysql_num_rows($result);
if ($num_rows >= 1) {
$items = array();
$i='1';
while($chat = mysql_fetch_array($result)){
$items[$i]['from']=$chat['useradn'];
$items[$i]['msg']=$chat['msg'];
$items[$i]['timee']=date("H:i" ,$chat['timee']);
$i++;
}
$query = "update chat set isread = 0 where userbdn = '".$useradn."' and isread = 1";
mysql_query($query , $link);
header('Content-type: application/json');
echo json_encode($items);
exit;
}else{
sleep(2);
chatheartbeat();
}
}
Any suggestions?
The function will never return until there are some results from the first select.
I would suggest that you return after n runs through (e.g. 5), even if there are no results. The client can then re-issue the ajax call to poll again.
Also, it's not a great idea to do this in a recursive manner. I would suggest doing this in a for loop instead.
You are calling your function recursively and as the session variable does not change between the function calls, if it goes to the else part the first time, it will go there every time, creating a never ending loop.
By the way, if you want to use polling, you should set a timer in the client part (javascript) and not use a recursive function on the server side.
There are a few things you want to look at when performing any long polling techniques.
You need to exit after some predefined time period. Waiting on the server until you have something to respond with will lead you to execution timeouts.
Know what is going on with your SESSION data. PHP by default will use file based sessions and locks the file during the course of the request (unless you intervine)

timeline new comments count php

I need to solve next problem:
I need the most optomized solution for count new time comments in blogposts.
My own solution is:
create one more tbl, where save blogpost_id, lastview_num_comment what updated with every review of post, and count_num_comment what == blog_post.num_comments
example:
<?php
function post($id){
if($id && $id!=0){
$sql = "SELECT `num_comments` FROM `blog_post` WHERE `id`=".quote_smart($id);
$res=mysql_query($sql);
$rw=mysql_fetch_array($res);
$sql = "UPDATE `new_comments` SET last_view_numcom=".$rw['num_comments'];
if(mysql_query($sql)){
return 1;
}else $this->error("database connect failed");
}else redirect("");
}
?>
but with everyone adding comment i need to use update query what aren't the best solution
I don't think there is better solution if you need real time number. Otherwise you could update this every x minutes by cron.
However you can improve this code by reducing it to one mysql_query run:
$sql = "UPDATEnew_commentsSET last_view_numcom = (SELECTnum_commentsFROMblog_postWHEREid=".quote_smart($id).")";

Categories