plus 1 to column each time page viewed? - php

can someone please help i am trying to make a kind of view count, to reflect the number of times a post has been viewed.
I am trying to create a function in mysql which will add +1 to a column called read in my table. so if the count starts from 0 in the column and each time someone opens that post it adds a 1 and another 1 and another 1 for however many times the page has been accessed.
i am trying to do this but am failing miserably can someone please show me how to achieve this type of thing please.
function read_forum_set() {
global $connection;
global $forum_id;
$query = "SELECT *
FROM ptb_forum, ptb_profiles
UPDATE ptb_forum.read_forum +1
WHERE ptb_profiles.user_id = ptb_forum.from_user_id
AND ptb_forum.id = '$forum_id' ";
$read_forum_set = mysql_query($query, $connection);
confirm_query($read_forum_set);
return $read_forum_set;
}

You need an update with join:
update ptb_forum
join ptb_profiles on ptb_profiles.user_id = ptb_forum.from_user_id
set ptb_forum.read_forum = ptb_forum.read_forum + 1
where ptb_forum.id = $forum_id
Whatever you do, make sure you use update ... set column = column + 1 and not two separate queries (one to read the old count and one to update it) because only with a single update expression you will be sure that each hit is counted exactly once.

First of all it's probably better to separate the queries out for sanity sake.
As for an increment query, very simple
UPDATE table
SET column = column + 1
WHERE foo = bar

Related

Queries slow down website and must make them execute faster

I have 2 queries in wordpress that slow significantly my website. the first one is
global $wpdb;
$tbl = $wpdb->prefix . "my_tournament_matches_events";
$result = $wpdb->get_var("SELECT count(*) FROM $tbl WHERE match_id = '$match' AND player_id = '$player' AND event_id = 'app'");
if($result) { return 'checked="checked"';
The problem is that it checks for every single player (0.33sec) if he attended the game, which means 20 queries for each team (6.6sec and for both teams=13,2sec). I wonder if i could make it with only two queries (One for each team).
The second query is
$output.="<td colspan='2'>".my_fetch_data_from_id($homeplayer->player_id,'data_value')."</td>";
foreach($events as $event){
$evcount = $wpdb->get_results("SELECT count(*) as total_events
FROM $table2
WHERE match_id='$mid'
AND player_id='$homeplayer->player_id'
AND event_id='$event->id'" );
$total= $evcount[0]->total_events;
$output.="<td><input type='text' name=hm-$homeplayer->player_id-$event->id value='$total'/></td>";
}
In the second query it checks for each player, but since i have available about 11 events, that means, it executes 11events*20players*2teams=440 queries. Is it possible to alter the code to reduse number of queries and time of them? Average time of each of the second query is about 0,3sec, so every improvement will be noticable
To sum it up:
Add LIMIT 1 to the queries this will make sure that if the query finds a result it doesn't continue looking for others;
Avoid using * in count but only count on the required fields;
Add indexes to columns where possible;
For readability, consistency and some errors you can change the single and double quotes:
$output.='<td colspan="2">'.my_fetch_data_from_id( $homeplayer->player_id, 'data_value' ).'</td>';
$output.='<td><input type="text" name="hm-'.$homeplayer->player_id-$event->id.'"value="'.$total.'"/></td>';
// Seems odd here otherwise ^
I suggest adding two indexes in the database. (and ofc. checking if they are present)
ALTER TABLE my_tournament_matches_events
ADD INDEX index1 (`player_id`, `match_id`, `event_id`);
ALTER TABLE total_events
ADD INDEX index2 (`player_id`, `match_id`, `event_id`);
This should speed things up, considerably. 0.33s is a slow query response time.

Lock a Select on the Postgres Database and updating the Column of "value+1" when necessary

I am updating this question, please do not mind the comments below as, instead of deleting this question, I reworked it to give it a sense.
A form on a php page let me create a csv file, to name this file I need to run a SELECT on the database, it the name does not exists, my query must create it; if the name exist, it must update it.
The problem is, there is a chance where 2 or more users can push the submit button at the same time.
This will cause the query to reurn the same value to all of them, therefore creating or updating the file in a non-controlled way.
I need to create a system, that will LOCK the table for INSERT/UPDATE and, if in the meantime another connection appear, the column on the database that will name the file must be incremented of +1.
$date = date("Ymd");
$csv = fopen("/tmp/$user_$date_$id_$reference.csv", 'w+');
Where "reference" is a progressive number in the format of "Axxxx". x's are numbers.
The SELECT would be:
$sql = pg_query($conn, " SELECT user, identification, reference, FROM orders WHERE identification = '$_POST[id_order]' ORDER BY date DESC LIMIT 1");
while ($row = pg_fetch_row($sql)) {
$user = $row[0];
$id = $row[1];
$reference = $row[2];
}
I need to create a function, like the one below, where users can both INSERT and UPDATE, and in the case of concurrent connection, the ones that are not the first will have "reference" incremented of 1.
CREATE OR REPLACE FUNCTION upsert_identification( in_identification TEXT, in_user TEXT ) RETURNS void as $$
BEGIN
UPDATE table SET identification=in_identification, user=in_user, reference=in_reference WHERE identification = in_identification;
IF FOUND THEN
RETURN;
END IF;
BEGIN
INSERT INTO table ( identification, user, reference ) VALUES (in_identification, in_user, in_reference );
EXCEPTION WHEN OTHERS THEN
-- Should the increment be here?
END;
RETURN;
END;
$$ language plpgsql;
I hope what I'm asking is clear, re-read and I do understand it. Please comment below for any question you might have.
I really hope someone can help me!
I was looking for some clues in the postgres manual, I found this link about locking but I am not so sure this is what I need: LINK

SQL - change an existing row

I'm using PHP in order to create a website where managers have access and review forms that employees have submitted. In the reviewing PHP file, I have created two buttons which basically approve or disapprove the form. After they click on one of the buttons, they are being redirected to another PHP file which actually inserts into the MySQL Database a change in a column I named 'processed'. It changes 0 which is unprocessed to 1, which is processed. The table I am referring to has columns such as formid, fullname, department and other job related stuff, as well as the 'processed' column which allows the managers to see if there is a pending form to be reviewed.
My problem is that I have no idea how to actually allow MySQL to find the proper row and change only the cell with the name 'processed' from 0 to 1 without having to insert every cell again. Here's what I have tried till now:
$id = $_SESSION[id];
$fullname = $_SESSION[fullname];
$teamformid = $_SESSION[teamformid];
if (isset($_POST['approved'])) {
$sql = "INSERT INTO carforms (processed) where aboveid='$id' and processed='0' and teamformid=$teamformid
VALUES ('0')";
}
else if (isset($_POST['disapproved'])) {
//todo
}
How do I tell SQL to only find the specific row I want and change only one column which is processed?
Also, do I always have to type every column name when I use the INSERT INTO command?
Thanks in advance.
Use the Below code it'll work for you.
$id = $_SESSION[id];
$fullname = $_SESSION[fullname];
$teamformid = $_SESSION[teamformid];
if (isset($_POST['approved'])) {
$sql = "UPDATE `carforms` SET processed = '1' WHERE `aboveid` = '".$id."' AND `teamformid` = '".$teamformid."'";
}
Try:
"UPDATE carforms SET processed = 1 WHERE aboveid = $id AND teamformid = $teamformid"
From what I have interpreted from your question, it seems like you need to use the MySQL UPDATE command. This will update any existing rows.
For example, let's say you have a table called 'forms', consisting of a Primary Key 'form_id' and a field named 'processed'.
If we want to change the value of 'processed' to '1', we would run...
UPDATE forms SET processed = 1 WHERE form_id = [whatever number the form is];
Obviously this only works where the form (with a form_id) exists already
There is no "INSERT...WHERE" in SQL.
To change an existing record there are 2 options, REPLACE or UPDATE. The former will create the record if it does not already exist and has similar syntax to INSERT. UPDATE uses the WHERE clause to identify the record(s) to be changed.
Using REPLACE is tricky. It needs to work out whether it should INSERT a new record or UPDATE an existing one - it does this by checking if the data values presented already exist in a unique index on the table - if you don't have any unique indexes then it will never update a record. Even if you have unique indexes just now, the structure of these may change over time as your application evolves, hence I would recommend NOT using REPLACE for OLTP.
In your question you write:
where aboveid='$id' and processed='0' and teamformid=$teamformid
(it would have been helpful if you had published the relevant part of the schema)
'id' usually describes a unique identifier. So there shouldn't be multiple records with the same id, and therefore the remainder of the WHERE clause is redundant (but does provide an avenue for SQL injection - not a good thing).
If the relevant record in carforms is uniquely identifed by a value for 'id' then your code should be something like:
$id=(integer)$id;
$sql = "UPDATE carforms SET processed = $action WHERE aboveid=$id";
But there's another problem here. There are 3 possible states for a record:
not yet processed
declined
approved
But you've only told us about 2 possible states. Assuming the initial state is null, then the code should be:
$action=0;
if (isset($_POST['approved'])) {
$action=1;
}
$id=(integer)$id;
$sql = "UPDATE carforms SET processed = $action WHERE aboveid=$id";
if ($id &&
(isset($_POST['disapproved']) || isset($_POST['approved']))
) {
// apply the SQL to the database
} else {
// handle the unexpected outcome.
}

PHP MySQL While loop for SELECT from two tables?

Hi there i am working on PHP code that is selecting columns from two tables.
Here is my code:
$result2 = mysql_query("SELECT *
FROM `videos`, `m_subedvids`
WHERE `videos.approved`='yes' AND
`videos.user_id`='$subedFOR'
ORDER BY `videos.indexer`
DESC LIMIT $newVID");
while($row2 = mysql_fetch_array($result2))
{
$indexer = addslashes($row2['videos.indexer']);
$title_seo = addslashes($row2['videos.title_seo']);
$video_id = addslashes($row2['videos.video_id']);
$title = addslashes($row2['videos.title']);
$number_of_views = addslashes($row2['videos.number_of_views']);
$video_length = addslashes($row2['videos.video_length']);
}
When i try to print $indexer with echo $indexer; it's not giving me any results.
Where is my mistake in this code?
It seems to me like the key 'indexer' isn't in your results. It's hard to tell, since you haven't listed a definition for your table and you're using SELECT * so we can't see the names.
It makes the program easier to read later, if instead of SELECT *..., you use SELECT col1, col2, .... Yes, SELECT * will save you some typing right now, but you'll lose that time later when you or anyone else who works on your code has to check the table definition every time they work with that line of code.
So, try changing your query to explicitly select the columns you use. If it's an invalid column you'll get an error right away rather than this silent failure you're getting now, and you'll thank yourself later as well.
So long as videos.indexer is a unique field name among all tables used in the query you can change
$indexer = addslashes($row2['videos.indexer']);
to
$indexer = addslashes($row2['indexer']);
You don't need to (or can not) use the table name when referring to the result.

joomla-php mysql not updating a record with data from previous query

I'm counting the right answers field of a table and saving that calculated value on another table. For this I'm using two queryes, first one is the count query, i retrieve the value using loadResult(). After that i'm updating another table with this value and the date/time. The problem is that in some cases the calculated value is not being saved, only the date/time.
queries look something like this:
$sql = 'SELECT count(answer)
FROM #_questionsTable
WHERE
answer = 1
AND
testId = '.$examId;
$db->setQuery($sql);
$rightAnsCount = $db->loadResult();
$sql = 'UPDATE #__testsTable
SET finish = "'.date('Y-m-d H:i:s').'", rightAns='.$rightAnsCount.'
WHERE testId = '.$examId;
$db->setQuery($sql);
$db->Query();
answer = 1 means that the question was answered ok.
I think that when the 2nd query is executed the first one has not finished yet, but everywhere i read says that it waits that the first query is finished to go to the 2nd, and i don't know how to make the 2nd query wait for the 1st one to end.
Any help will be appreciated. Thanks!
a PHP MySQL query is synchronous ie. it completes before returning - Joomla!'s database class doesn't implement any sort of asynchronous or call-back functionality.
While you are missing a ';' that wouldn't account for it working some of the time.
How is the rightAns column defined - eg. what happens when your $rightAnsCount is 0
Turn on Joomla!'s debug mode and check the SQL that's generated in out the profile section, it looks something like this
eg.
Profile Information
Application afterLoad: 0.002 seconds, 1.20 MB
Application afterInitialise: 0.078 seconds, 6.59 MB
Application afterRoute: 0.079 seconds, 6.70 MB
Application afterDispatch: 0.213 seconds, 7.87 MB
Application afterRender: 0.220 seconds, 8.07 MB
Memory Usage
8511696
8 queries logged.
SELECT *
FROM jos_session
WHERE session_id = '5cs53hoh2hqi9ccq69brditmm7'
DELETE
FROM jos_session
WHERE ( TIME < '1332089642' )
etc...
you may need to add a semicolon to the end of your sql queries
...testId = '.$examID.';';
ah, something cppl mentioned is the key I think. You may need to account for null values from your first query.
Changing this line:
$rightAnsCount = $db->loadResult();
To this might make the difference:
$rightAnsCount = ($db->loadResult()) ? $db->loadResult() : 0;
Basically setting to 0 if there is no result.
I am pretty sure you can do this in one query instead:
$sql = 'UPDATE #__testsTable
SET finish = NOW()
, rightAns = (
SELECT count(answer)
FROM #_questionsTable
WHERE
answer = 1
AND
testId = '.$examId.'
)
WHERE testId = '.$examId;
$db->setQuery($sql);
$db->Query();
You can also update all values in all rows in your table this way by slightly modifying your query, so you can do all rows in one go. Let me know if this is what you are trying to achieve and I will rewrite the example.

Categories