What is the best way to count page views for dynamic pages like the url example below? I'm using PHP and MySQL. A brief explanation would help. Thanks!
http://www.example.com/posts/post.php?id=3
Usually the table structure looks like this:
table pages:
id | name | ...
==========================
1 Some Page
2 Some Other Page
table pages_views:
page_id | views
================
1 1234
2 80
where pages_views has a unique index on page_id
The MySQL statement to increment the views then looks as follows:
INSERT INTO `pages_views` SET views=1 WHERE page_id=?
ON DUPLICATE KEY UPDATE views=views+1 ;
Since pages_views.page_id is unique, the row for the page will get created if it doesn't exist; if it exists (that's the "duplicate key" clause), the counter will be incremented.
I chose two separate tables here, as CMS pages usually aren't updated too often (and therefore, their load is mostly reads), whereas page views are read and updated, well, with each page view.
This is my code and it's working properly when I open the page or When I refresh the page, page views is incrementing by 1. If the page_id doesn't exist it will insert a record with views = 1, if page_id exists it will increment the views
`INSERT INTO pages_views ( pages_id, views) VALUES ( $page_id, 1) ON DUPLICATE KEY UPDATE views=views+1`
With PDO you will have something like this
$sql = "INSERT INTO pages_views ( pages_id, views) VALUES ( :pageId, 1) ON DUPLICATE KEY UPDATE views=views+1";
$q = $conn->prepare($sql);
$q->execute(array(':pageId'=>$pageId));
Well, you can simply add a field pageviews to your pages table and do UPDATE pageviews = pageviews +1 WHERE id = 1 query on each page load
For the sake of viewing statistics by day/week/month/year, I have made two tables. The first archives all visits to the site with my page and id saved on the same row. The second table records tallys, such as Piskvor describes.
The benefit is that I can view stats for any page and ID I want over time (but that'll be a lot of rows over time...) or I can simply view total pageviews. For the visitors of my site, I serve information from this second table, but my admin panel makes full use of the first table.
statsEach
- statID
- page (example: page 100 is index.php, or 210 is news.php)
- id (example: 1 is news story 1, 2 is news story 2,...)
- date
- time
- user
and
statsTotal
- statTotalID
- page
- id
- total
I don't know what you need/want to do, or even if my table structure is best, but this works for me.
Just increase an integer on the post you currently serve.
A simple example can be found at http://www.configure-all.com/page_view_counter.php
Related
I'm going to be building a page counter for a site to determine views of different pages. Basically, I have users that I'd like to track with respect to page views of about 120 specific pages.
I'm having trouble determining the most efficient way to do this as well as the logic behind it. I was trying 3 tables, but this would end up in many unnecessary rows. I thought storing an array in a single field then updating the array, but I'm not sure this will grow or if it is even possible. Below is my way of limiting the number of requests. Basically every 100 will count 100. Any ideas for structuring this?
$sample_rate = 100;
if(mt_rand(1,$sample_rate) == 1) {
//update set query
}
Based on our conversation in the comments I would recommend the following simple design:
TblPages
--------
Page_Id (pk)
Page_URL (unique)
TblViews
--------
View_Page_Id
View_User_Id
View_Count
(pk is View_Page_Id + View_User_Id)
Whenever a user views a page, you execute a stored procedure that will either insert a record to the TblViews table if there is no record for that user and page, or update the View_Count of the existing record.
To get all the views for a page you use SUM(View_Count) and group by View_Page_Id, to get all the page views by a user you group by View_User_Id, etc.
I am building a site where I'm constantly adding new links. The links are organized in a mysql database with id being the main index starting at 1. I only want to display the top five links from the database on my site so, in my php code I assign the database to an array so I can only call the top 5 links to the site. My problem is that every time I add new links to the database I have to change the id numbers manually. I want the newest link to start at id number 1 and the one below that to automatically become id number 2 and so on. Is there a way to do that or is there a better way to organize my database?
dont make any changes to the id(if you're auto incrementing),just modify your Mysql Query to retrieve data from your table by ID in descending order.
SELECT * FROM your_table ORDER BY id DESC LIMIT 5
I have this page table structure to store all the website page information,
page_id
page_url
page_title
page_subtitle
page_description
page_introduction
page_content_1
page_content_2
page_content_3
page_content_4
...
You can see that I have page_content_1 to page_content_4, instead of just page_content. The reason why I do this because I might want to store different types of page content for each page.
But I doubt whether this is a good practice or not? What if other developer comes to further develop on this page table, would you find this structure redundant?
I am thinking maybe I should create another table to store additional page content like this below?
table page_additional_content,
content_id
content_additional_1
content_additional_2
content_additional_3
content_additional_4
page_id
Is this better?
Or there is better standard idea that I should look into?
Building on Quentin's answer, if you want to be able to reuse content across pages (such as headers or footers), you could create a table structure like:
page_content:
content_id (primary key)
actual_content (actual content of the page)
page_structure:
page_id (foreign key of the page)
content_id (foreign key of the content)
order_in_page (order of the content in the page)
You content can grow to as many sections as you want without adding additional tables (just add a new row in page_structure and increment the order_in_page counter).
When you start having columns with the same name, but with a numerical suffix then you should usually start thinking "New table + foreign key".
You would probably be better off with something along the lines of a content table structured like:
document_id | page | content
1 | 1 | foo, bar, baz
1) How do I add a simple page counter to a PHP page and insert the values in a MySQL table? Also I would need the MySQL table value to be updated with each new visit.
2) The trick is that the PHP page is a template for a variety of user generated landing pages. For example, I would like each of these pages to have their own separate counters:
examplesite.com/template.php?getvalue=bob
examplesite.com/template.php?getvalue=sam
examplesite.com/template.php?getvalue=samantha
My impression is that if I put the counter on the "template.php" file then it will add up all the visits from each user to a grand total. The output that I would like is to have each user only get counts for the individual landing page.
So, if there are a total of 12 visits, dispersed as follows:
examplesite.com/template.php?getvalue=bob had 4 visits
examplesite.com/template.php?getvalue=sam had 2 visits
examplesite.com/template.php?getvalue=samantha had 6 visits
then I would want bob's page counter to read as '4', sam's as '2' and samantha's as '6.' Am I correct in assuming that if I just put the counter on template.php that each user's landing page would read as '12?' Do you have a solution for an easy way to fix this?
That's pretty simple:
pdo::prepare( 'UPDATE counter SET hits = hits+1 WHERE value = ?');
pdo::execute($_GET['getvalue']);
if ( pdo::rowCount() == 0 ) {
pdo::prepare('INSERT INTO counter (?,0)');
pdo::execute($_GET['getvalue']);
}
Well, just as you are able to separate the requests for bob and sam when generating the page, you can do the same for the counter?
You'll probably do something with $_GET['getvalue']. Just use that value (escaped, paramterized etc) in a query to update your counter....
UPDATE yourtable SET count = count + 1 WHERE pagename = ?
and then bind the getvalue...
You would want to have a row in your MySQL table for each user. When you go to update the table, update the appropriate row for that user by reading the getvalue. Then do the same for displaying the user's page counter.
I write some simple article scripts. Now I want add some article counter.
If there have 3 possibility it should make an article counter.
the article has been opened for read.(only one whole article per page, it will count 1 time)
the article has been searched in a content search list(with title and short content description 5 items per page, it will count 1 time. then if open to read whole article content, it will count another 1 time.)
the article has been showed in the home page by Random (with title and short description, it will count 1 time)
Is there any good suggestion how to do these better?
Which database design is better? put article and count number in one table? or make two tables?
Can anyone recommend me some php article counter script, if the main rules write into a file like class.php then include into my every page.
Thanks.
If you are counting the number of hits on an article, create a column and add one to it every time somebody accesses the page.
Something like:
$sql = "UPDATE table SET count=count+1 WHERE id='$id'";
mysql_query($sql);
Would increment the column count in the table table by 1. Then you could just retrieve that value.
What you could do is use the database that auto increments and just increment that value when the page is viewed, and display that value if you want.
Here is how you can setup the auto increment.
Then update the "value" (you don't have to actually update anything it will AI)
mysql_query("UPDATE COUNTER SET HITS = ''");
Then just display the view
$result = mysql_query("SELECT * FROM PAGEVIEWS");
while($row = mysql_fetch_array($result))
{
echo $row['COUNTER'];
}
This is off the top of my head - it should work.