I'm trying to write a system that shows who is logged into my website.
I've tried so many things, and I feel like I'm onto something with this - but it isn't working. I need help trying to find where I am going wrong.
Here is my display code (I know I shouldn't format with tables, but I am using it for testing):
<?
$loggedInUsers2 = "SELECT * FROM techs WHERE Level='0' AND LastTimeSeen>DATE_SUB(NOW(), INTERVAL 5 MINUTE)";
$loggedInUsers3 = "SELECT * FROM techs WHERE Level>'0' AND LastTimeSeen>DATE_SUB(NOW(), INTERVAL 5 MINUTE)";
?>
<div class="col-sm-4">
<div class="thumbnail">
<center><h4 style="height:35px;">Users Online</h4></center>
<div class="modal-body" style="min-height:498px;">
<table>
<tr><td>
<?
mysqli_query($con, $loggedInUsers2) or die("Error " . mysqli_error($con));
while($row2 = mysqli_fetch_array($loggedInUsers2)) { //if level less than 1
echo $row2['Name']."<br/>";
}
?>
</td><td>
<?
mysqli_query($con, $loggedInUsers3) or die("Error " . mysqli_error($con));
while($row3 = mysqli_fetch_array($loggedInUsers3)) { //if level more than 1
echo $row3['Name']."<br/>";
}
?>
</td></tr>
</table>
</div>
</div>
</div>
Here is my saving to the database:
$userId = $_SESSION['UserId'];
$loggedInUsers1 = "UPDATE techs SET LastTimeSeen=NOW() WHERE UniqueID='$userId'";
mysqli_query($con, $loggedInUsers1) or die("Error " . mysqli_error($con));
This outputs to my database (In the LastTimeSeen field) to something like 2015-12-21 08:35:43 (Updates every few seconds via jquery reloading the footer of the page)
Basically, there is just no output in the tables from the first page.
EDIT:
It was suggested to use the login button to set a user active, and the logout button to set them inactive - here is my response to that:
"The problem with that is people won't use the logout button. They will just close the browser. I want this to keep track of only users that are online. The footer updates the time in the database, every couple of seconds, and then the table is listed on a part of the page that reloads every few seconds aswell, so they are both always up to date. It should only list people that have been on a page in the past 5 minutes."
When you use mysqli_query it returns a result object. You need to pass this object into mysqli_fetch_array not the query string.
<?
$loggedInUsers2 = "SELECT * FROM techs WHERE Level='0' AND LastTimeSeen>DATE_SUB(NOW(), INTERVAL 5 MINUTE)";
$loggedInUsers3 = "SELECT * FROM techs WHERE Level>'0' AND LastTimeSeen>DATE_SUB(NOW(), INTERVAL 5 MINUTE)";
?>
<div class="col-sm-4">
<div class="thumbnail">
<center><h4 style="height:35px;">Users Online</h4></center>
<div class="modal-body" style="min-height:498px;">
<table>
<tr><td>
<?
$results1 = mysqli_query($con, $loggedInUsers2) or die("Error " . mysqli_error($con));
while($row2 = mysqli_fetch_array($results1)) { //if level less than 1
echo $row2['Name']."<br/>";
}
?>
</td><td>
<?
$results2 = mysqli_query($con, $loggedInUsers3) or die("Error " . mysqli_error($con));
while($row3 = mysqli_fetch_array($results2)) { //if level more than 1
echo $row3['Name']."<br/>";
}
?>
</td></tr>
</table>
</div>
</div>
</div>
I think because last seen = now is only equal to NOW when the query runs no? meaning that its set to now for only the split second? i could be wrong but throwing ideas out there. to be honest I think there is an easier way to do this aswell!
When you log a user in also run a query to update a field.. so on log in
//Code to log in
if password and email comp is found in database then log user in
//Code to set user active
UPDATE user WHERE username& password match, SET active = TRUE or 1 or something of the sort.
Then on logout set active = to false or 0, I hope you see the logic im trying to explain here, I would write the code but been too deep in laravel and not touched vanilla db management for a while now.
I think this task shouldn't be done with MySQL at all. Because you're going to face a huge overload and database deadlocks when there will be thousands of visitors opening a new page every second.
You would be better off by using a RAM-based database, like Redis (http://redis.io).
In Redis, you can set automatically expiring entries (let's say, for 5 minutes) for currently active visitors. If that entry is not updated for 5 minutes, it would be automatically deleted. I would suggest to use Redis command SETEX for that.
You wouldn't need to worry about people who are not logging out and you would achieve exactly what you want in an efficient way.
So as spotted earlier you will want to change the following on both lines of code.
mysqli_query($con, $loggedInUsers2) or die("Error " . mysqli_error($con));
while($row2 = mysqli_fetch_array($loggedInUsers2)) { //if level less than 1
echo $row2['Name']."<br/>";
}
TO
$query_1 = mysqli_query($con, $loggedInUsers2) or die("Error " . mysqli_error($con));
while($row2 = mysqli_fetch_array($query_1)) { //if level less than 1
echo $row2['Name']."<br/>";
}
The problem is that the parameters passed into the mysqli_fetch_array is not the query object, Meaning the loop was just going through a MySQL statement not the object.
Related
Ok so eventually I will have let's say 100 products in mysql database. The product page pulls all info from database (such as partnumber, material, color, etc...) and inputs it into the areas of the page that I designate it, all this using php. The previous page will show all 100 products and when user click's on one product it'll go to that product page. Just like all websites right...
I don't believe I need to make 100 individual html pages for each product right? Can I make just 1 main html page that is the templet for the 100 different products? Basically when user clicks the image tag of the product(1st example of code) it'll open the main html templet but somehow call to the database on open and load that specific info? Then other products will have the same process but for they're specific data from database. The 1st sample code is one product on the page that'll display all 100 products with the href containing the image that'll get clicked to show user actual product page retrieved dynamically without page reload, into a predestined section. I'm sure there is a name for what I'm looking to do but all the research I've done I haven't found what I'm looking for. Is there a better way then what I'm explaining? Also I hope this makes sense, Thank you for any input.
<td><img class="td-Image" src="image.jpg">
</td>
<td class="td-manufacturer">
<h6>MANUFACTURER</h6>
<p>Lowes</p>
</td>
<td class="td-addComponent">
<p>$104.99</p>
<button class="add-button">ADD</button>
</td>
<td class="td-material">
<h6>MATERIAL</h6>
<p>Aluminum 7075-t6 Forged</p>
</td>
<td class="td-platform">
<h6>PLATFORM</h6>
<p>Large</p>
</td>
<td class="td-america">
<h6>AMERICAN MADE</h6>
<p>YES</p>
</td>
Actual product page where php gets info from database example
<?php
$sql = "SELECT * FROM Parts;";
$result = mysqli_query($conn, $sql);
$resultCheck = mysqli_num_rows($result);
if($resultCheck > 0) {
while ($row = mysqli_fetch_assoc($result)) {
?>
<div class="description">
<h3>Descrption</h3>
<p>
<?php
echo $row['Description'];
?>
</p>
</div>
<?php
}
}
?>
Editor Note: I edited the question to reflect what he want based on thread on my answer below.
In this scenario you would need to pass in a unique identifier i.e product-id and create a query to fetch from the database product info by product-id
$product-id= $_GET['id'];
$strSQL = "SELECT * FROM AR15Parts WHERE id='$product-id'";
$rs = mysql_query($strSQL);
if (!$rs) {
echo 'Could not run query: ' . mysql_error();
exit;
}
$row = mysql_fetch_assoc($rs);
//display your data
if($row){
echo $row['field'];
}
Add an unique Id to your products in your mysql database, using the Auto Increment option (A_I checkbox in phpmyadmin). Then you can pass that id into a link to the product page ```href=“individualProduct.php?id=” while rendering all the products on the all products page.
Then in individualProduct.php you can get that id and retrieve the data
$sql = SELECT * FROM Parts WHERE id =?”;
$stmt = mysqli_prepare($sql);
$stmt->bind_param($_GET[“id”]);
$stmt->execute();
$result = $stmt->get_result();
// Do stuff with $result as it is the individual product corresponding to that id
Optimally, you'll need 2 files:
index/list of products
detail information of the selected product
index files (maybe call it index.php)
Here, you need to select products and make it a list:
$stmt = $pdo->query("SELECT * FROM Parts");
while ($row = $stmt->fetch()) {
echo '' . $row['name']."<br />\n";
}
Since you want the detail to be shown to the index/list page, let's add a container area:
<div id="container-detail">
</div>
Add a little javascript code to handle AJAX request:
<script type="text/javascript">
function loadDetail(itemId){
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://website.address/path/to/detail.php?id=" + itemId, true);
xhr.onreadystatechange = function ()
{
if (xhr.readyState==4 && xhr.status==200)
{
document.getElementById("container-detail").innerHTML=xhr.responseText;
}
}
xhr.send();
}
</script>
detail page (let's call it detail.php)
In this screen, we fetch details for only one part, specified by HTTP GET id parameter. The one that's being supplied from index.php (the ?id= part).
$stmt = $pdo->query("SELECT * FROM Parts WHERE id = '" . $_GET['id'] . "'");
$part = $stmt->fetch();
echo "Name: " . $part['name'] . "<br />\n";
echo "Manufacturer: " . $part['manufacturer'] . "<br />\n";
echo "Price: " . $part['price'] . "<br />\n";
That's it, you should get it working with a few adjustments based on the table and template you have.
A little note is that I used PDO mechanism to do the query. This is because mysql_* function has been deprecated for so long that it is now removed from PHP 7.0. Also, the current PHP version has been PHP 8. So, be prepared, a lot of web hosting might gonna remove older PHP versions, moving forward.
my question is related to PHP/SQL.
I know how to limit the results returned by using 'LIMIT 5'. How do I limit the allowed input? So that a user can't add more tasks until he deletes one of the existing ones? So basically how do I limit the input instead of the results. At this moment I can still add tasks, but with only the limited results it pushes the older tasks out of view. I want it to be impossible to add more tasks unless one is deleted when it has reached the list limit.
UPDATE: Shared code:
(Yes, I know I need to use prepared statements)
Head:
<?php
$errors = "";
$db = mysqli_connect("localhost", "root", "", "certanet");
if (isset($_POST['submit'])) {
if (empty($_POST['task'])) {
$errors = "";
}else{
$task = $_POST['task'];
$sql = "INSERT INTO tasks (task) VALUES ('$task')";
mysqli_query($db, $sql);
header('location: dashboard.php');
}
}
if (isset($_GET['del_task'])) {
$id = $_GET['del_task'];
mysqli_query($db, "DELETE FROM tasks WHERE id=".$id);
header('location: dashboard.php');
}
?>
Tasklist:
<div class="todobox">
<div class="menutitle" id="category">
Persoonlijke takenlijst
</div>
<div class="inhoud">
Hieronder is het mogelijk om je eigen taken bij te houden.
<form method="post" action="dashboard.php" class="input_form">
<?php if (isset($errors)) { ?>
<p><?php echo $errors; ?></p>
<?php } ?>
<input type="text" name="task" class="task_input">
<button type="submit" name="submit">Toevoegen</button>
</form>
<table>
<tbody id="todo">
<?php
$tasks = mysqli_query($db, "SELECT * FROM tasks ORDER BY id DESC LIMIT 7");
$i = 1; while ($row = mysqli_fetch_array($tasks)) { ?>
<tr>
<td> <?php echo $i; ?> </td>
<td class="task"> <?php echo $row['task']; ?> </td>
<td class="delete">
x
</td>
</tr>
<?php $i++; } ?>
</tbody>
</table>
</div>
</div>
While you are asking for a solution in SQL, this is really more of an application / business requirement than a database concern. If the business logic of your application requires a limit on user-created records, then it is the application which should query for the existing number of records and present appropriate messaging to the user.
It's not apparent from your insert SQL whether the row being inserted into the tasks table includes a column to identify which user entered it. This may be fine if this is a single-user application, or perhaps your underlying framework handles this automatically. If neither of those is true, we'll need to add a column to that table to capture a user ID or other identifying information to associate each task record with its respective user (e.g., depending on your use case, IP address or a session ID may suffice).
Assuming the above is all true, there are a few changes we should implement:
Never display the form to the user, as this crates an affordance for functionality which is not supported/allowed. Instead, we'll replace the form with a message to provide appropriate feedback to the user.
If we receive a POST request from a user attempting to add a new record after they've exceeded the limit, reject the request and display a message to the user.
Add a userId column, or some datum to associate the user, to the tasks table.
Set the value of this new column when inserting new tasks.
Whether a GET or POST, we're going to want to query for the user's existing records before rendering the page.
<?php
$errors = "";
$maxUserTasks = 7;
$db = mysqli_connect("localhost", "root", "", "certanet");
// Before even handling the request, query for the user's existing records
$sql = "SELECT task FROM tasks WHERE userId = 123"
$userTaskCountQuery = mysqli_query($db, $sql);
$userTaskCount = $userTaskCountQuery->num_rows();
if (isset($_POST['submit'])) {
if (empty($_POST['task'])) {
$errors = "";
}else if ($userTaskCount > $maxUserTasks){
$errors = "You already have $maxUserTasks tasks."
}else{
// Here is where you'll first want to check
$task = $_POST['task'];
$sql = "INSERT INTO tasks (task) VALUES ('$task')";
mysqli_query($db, $sql);
header('location: dashboard.php');
}
}
// Presumably, your page markup and form are somewhere down here
if ($userTaskCount > $maxUserTasks){
// display our error message here
}else{
// otherwise, display our form
}
?>
I am creating a website that stores information of homes like address, city etc. I got the upload to database part done and I got the search the database and display the information done.
But now my plan with that is you get the search results and from there your suppose to get the option to view the full profile of that home via link. Displaying the full profile with the information gathered from the database is already done through a separate php file. Now when I link the php file it will only display the last column in the database. How can I link it so when I click on "view full profile" it will connect to the correct data/profile that corresponds to the different address or price. Or if i cant use an html link what can I use? Is that impossible?
here is the code that displays the search results I have successfully been able to search the database and display it
<?php
if($sql->num_rows){
while ($row = $sql->fetch_array(MYSQLI_ASSOC)){
echo '<div id="listing">
<div id="propertyImage">
<img src="images/'.$row['imageName1'].'" width="200" height="150" alt=""/>
</div>
<div id="basicInfo">
<h2>$'.$row['Price'].'</h2>
<p style="font-size: 18px;"># '.$row['StreetAddress'].', '.$row['City'].', BC</p>
<p>'.$row['NumBed'].' Bedrooms | '.$row['NumBath'].' Bathrooms | '.$row['Property'].'</p>
<br>
<p>View Full Details | Get Directions
</div>
</div>';
height="150" alt=""/>';
}
}
else
{
echo '<h2>0 Search Results</h2>';
}
?>
Here is the php to display the information outputtest.php
<?php
mysql_connect("localhost","root","31588patrick");
#mysql_select_db("test") or die( "Unable to select database");
$query="SELECT * FROM propertyinfo";
$result=mysql_query($query);
$num=mysql_numrows($result);
mysql_close();
$i=0;
while ($i < $num) {
$varStreetAddress=mysql_result($result,$i,"StreetAddress");
$varCity=mysql_result($result,$i,"City");
$varProperty=mysql_result($result,$i,"Property");
$varNumBed=mysql_result($result,$i,"NumBed");
$varNumBath=mysql_result($result,$i,"NumBath");
$varPrice=mysql_result($result,$i,"Price");
$varEmail=mysql_result($result,$i,"Email");
$varPhone=mysql_result($result,$i,"Phone");
$varUtilities=mysql_result($result,$i,"utilities");
$varTermLease=mysql_result($result,$i,"TermLease");
$varNotes=mysql_result($result,$i,"Notes");
$image1=mysql_result($result,$i,"imageName1");
$image2=mysql_result($result,$i,"imageName2");
$image3=mysql_result($result,$i,"imageName3");
$image4=mysql_result($result,$i,"imageName4");
$i++;
}
?> html code will go after this
Thanks
edit its working
<?php
////////////using mysqli to connect with database
$mysqli = new mysqli("localhost","root","31588patrick", "test");
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
///////////set variables
$record_id = $_GET['record_id'];
$sql = $mysqli->query("select * from propertyinfo where StreetAddress like '%$record_id%'");
if($sql === FALSE) {
die(mysql_error()); // TODO: better error handling
}
if($sql->num_rows){
while ($row = $sql->fetch_array(MYSQLI_ASSOC)){
$varStreetAddress=$row['StreetAddress'];
$varCity=$row['City'];
$varProperty=$row['Property'];
$varNumBed=$row['NumBed'];
$varNumBath=$row['NumBath'];
$varPrice=$row['Price'];
$varEmail=$row['Email'];
$varPhone=$row['Phone'];
$varUtilities=$row['utilities'];
$varTermLease=$row['TermLease'];
$varNotes=$row['Notes'];
$image1=$row['imageName1'];
$image2=$row['imageName2'];
$image3=$row['imageName3'];
$image4=$row['imageName4'];
}
}
If the link you are using is only fetching the last record in the database table, then the underlying query that is used must be fetching the last record instead of the intended record. Am I correct in understanding the problem you are having? That any link you use is just returning the last record in the database?
Posting a code snippet will help the community take a closer look.
in your php file, you run a query for all records, but ...
$record_id = mysql_real_escape_string($_GET["record_id"]);
$query="SELECT * FROM propertyinfo WHERE id=$record_id";
your link needs to attach a parameter that will allow you to query for a specific record.
a href="outputtest.php&record_id=8"
AND you would also want to check what is in the GET parameter before sticking it into the query! I know mysql_real_escape_string is outdated.
I have a reviews system on my site where users can rate other users. When a user logs in they can go to their pending reviews section where they can either approve or delete a review.
I pull through the reviews from the table ptb_reviews and list them on the page reviews.php. Each review then has an approve or delete link which goes to either approve_review.php or delete_review.php and in there is the SQL function to set the relevant column in my table, so approve or delete, from 0 to 1.
So if a user approves a review it updates approve in the table to 1 where that specific review has been chosen to be approved and then its the same for deleted.
I'm having a problem in that when I try to approve or delete a review, I echo out the query to test it to see what's happening and to see if its doing what I'm asking it to do and I get this:
UPDATE ptb_reviews SET approved = 1 WHERE id = '' LIMIT 1
this is implying that it cant find the review id and it wont therefore apply the update to 1 in the table where appropriate for that review.
here's my code for reviews.php where the reviews are pulled through:
<?php
$reviews_set = get_new_reviews();
while ($reviews = mysql_fetch_array($reviews_set)) {
$review_id = (int) $_GET['review_id'];
// Just this, is a great security enhancement. Forces the variable to be int (like all id's are).
// You can also check if its a numeric by doing
if (is_numeric($review_id)){
// continue with the update query
} else {
// something fishy is going on..
}
?>
<div class="prof-content-pend-reviews" id="reviews">
<div class="pend-review-content">
<?php echo "{$reviews['content']}"; ?>
</div>
<div class="message_pic">
<?php echo "<img width=\"50px\" height=\"50px\" src=\"data/photos/{$reviews['from_user_id']}/_default.jpg\" />";?>
</div>
<div class="forum-text">
<?php echo "Posted by {$reviews['display_name']}"; ?> <?php echo "".$age." days ago"; ?>
</div>
<div class="approve"></div>
<div class="delete"></div>
</div>
<? } ?>
And next is my code that carry's out the SQL function for approve_review.php:
<?php
require_once("session.php");
require_once("functions.php");
require('_config/connection.php');
$query = "UPDATE ptb_reviews SET approved = 1 WHERE id = '$review_id' LIMIT 1";
mysql_query($query, $connection);
echo $query;
die();
// See what is really sent to MySQL
if (!mysql_query($query, $connection)){
die(mysql_error());
}
?>
I'm basically asking is the reason nothing updates because it can not find the id for the review which is being either approved or deleted and what can I do to get it to update and so that it knows which review I'm asking it to approve or delete?
I'm still learning PHP and MySQL so if someone could show me or explain what to do that'd be great.
You are getting the query variable like this:
$review_id = (int) $_GET['review_id'];
But in your link you use:
<a href="includes/approve_review.php?review=<?php echo $reviews['review_id']; ?>">
^^^^^^
So your review ID is stored in $_GET['review'] and not $_GET['review_id'].
To start you should change that line to (or the other way around...):
$review_id = (int) $_GET['review'];
<?php $name=$_POST['name']; ?>
<form method="POST" action="<?php echo $_SERVER['PHP_SELF']; ?>">
<input type="text" name="name">
<input type="submit" value="GO" name="submit">
</form>
<?php
include ('db.php');
if(isset($_POST['submit']))
{
mysql_query ("INSERT INTO example (name) VALUES('$name')") or die(mysql_error());
}
if (!isset($_GET['startrow']) or !is_numeric($_GET['startrow'])) {
$startrow = 0;
}
else {
$startrow = (int)$_GET['startrow'];
}
$query = "SELECT * FROM example ORDER BY id DESC LIMIT $startrow, 20";
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_array($result)){
echo "<li>";
echo $row['name'] ." "." <a href= 'like.php?quote=" . urlencode( $row['name'] ) . "'>Click Here</a>";
echo "</li>";
}
echo 'Next';
?>
I want to make my page links hidden , how can i make then hidden so that a user cant edit it.
2nd question,
currently i am showing total 10 records on each page and then a next page button , but the next button is keep showing even when there is no more records...! how to remove a next page button when records ended. ??
line number 28 is the link to pages which can be easyily editable by any user, i wnat to make them secure (using ID)
and line 35 is n'next' page link , this link should not be appear when number of records ended
I can't think of a reason why you really should hide the page numbers from the user in the link. Keeping them in the query string as $_GET variables is probably the most common practice i know of in this specific case of paging.
I would do validation on the numebrs being recieved in the $_GET variables, since this could often lead to SQL Injection and other problems... Make sure it's a number, possibly divisible by 10 (if that's how you like the site to be), perhaps not bigger than a certain defined number, etc...
If you REALLY still don't agree, and you want to hide it, then you could always do that by saving cookie on the user's computer (this is still exposed to user in some way) or save the page number in the session (although this seems like a big waste of server resources to me!).
About your second question - There are so many possibilities to this...
Here's one way :
Create an sql query that queries how many rows are there to your table.
Let's say the number is 55. You put that into a hidden value.
If you're displaying 10 items on a page then you know the last page is number 6 (showing items 50-55, if you start counting at page number 1).
Simple php check when page loads: if ($_GET['page'] == 5) then you don't display the next button.
something like this (skipping out validation checks and the sql query) :
<input type="hidden" value="<?php echo $itemCount;?>">
<?php
if ($_GET['page'] < ($itemCount \ 10))
{
echo "<a href=\"items.php?page=".($_GET['page']+1)."\">";
}
?>
Using this, I would add a check to make sure the user doesn't enter a number bigger than this number as well, and if they do, just redirect them to the last number they can.