Pulling my hair out on this, it has to be obvious, but I can't see it today.
I built a small monitoring tool for an app we have. I want to do a check in the DB to make sure the backend scripts are working and the data isn't stale by more than 15 min. When no records are returned in a certain timeframe it should pop up a message saying to check the script. If they are not returned it should be an empty dataset and I should get a message on it.
Problem is, I can't get empty() or !isset to work. Actually regardless of whether I use !empty(), empty(), isset() or !isset(), my $tripped variable never gets tripped. I have this working for other alerts, but this one seems to be stubborn and I don't see what I'm missing.
PS I know mysql_ is out of date.
The relevant piece of code:
$ldap_check = mysql_query("SELECT
*
FROM ldap_conns
WHERE DATETIME > DATE_SUB(NOW(), INTERVAL 15 MINUTE)
order by DATETIME DESC
LIMIT 1");
while($row = mysql_fetch_array($ldap_check))
{
if (empty($row['DATETIME']))
{
echo '<b><font color=blue>Stale Data: </font> <font color=red>LDAP data is old, check script!</font><br>' . $row['DATETIME'];
$tripped='Yes';
}
}
if ($tripped!='Yes')
{
echo '<b><font color=blue>Stale Data: ' . $row['DATETIME'] . '</font></b> <font color=green> No Problems Found<br></font>';
}
You are doing it wrong... Want just check if there exists any old items? Use count! There is no reason for selectin g ALL fields from ALL records from the table. This is wrong using of database! Use count, and make index on DATETIME field!
$result = mysql_query("SELECT
count(*) old_items
FROM
ldap_conns
WHERE
DATETIME < DATE_SUB(NOW(), INTERVAL 15 MINUTE)");
$row = mysql_fetch_row($result);
if ($row['old_items']) {
echo 'There is '.$row['old_items'].' old items!';
}
You have this condition in your query:
WHERE DATETIME > DATE_SUB(NOW(), INTERVAL 15 MINUTE)
So I don't see how $row['DATETIME'] could ever be empty for any of the rows fetched (although you are actually only fetching one row...).
Related
Google hasn't been much help sadly. I have some pseudo code below to give you an idea of what I'd like to achieve:
if ($time == one week) {
$result = mysql_query("SELECT * FROM table RANDOMLY,$connection");
echo $result[0];
}
I know I should be using mysqli, but I'm augumenting an existing (ageing) system. I'll be utilising mysqli in future, so if you could give me the solution using mysql that would be great!
I don't think it can be done with a single statement.
My best guess would be to use mysql_list_tables, select a random entry from that list and continue from there on.
Perhaps generating a random number between 1 and the value of SELECT Count(ID) from table. Then you have the index of the value you wish to output, you can simply run a SELECT statement for it; and output! :)
if ($time == one week) {
$result = mysql_query("SELECT * FROM table RANDOMLY,$connection");
echo $result[0];
}
Try this:
$weekNumber = date("W");
$result = mysqli_query("SELECT * FROM table RANDOMLY WHERE weeknumber = '\"$weekNumber\"', $connection");
echo $result[0];
}
Of course you’ll need a column in your table called weeknumber with 1 through 52 setup ahead of time.
As others pointed out you shouldn’t use mysql_* anything. I changed it to a mysqli_query.
I am making a meeting room booking system in which there should be no times within the start and end dates so in theory the validation should check for no dates/times within one start and end date time frame.
I have two tables, I can insert into it fine with both start and end dates so the only columns i am interested in at the moment are these
meetingrooms
|------------------------------------||- bookingtime -|-bookingend-|
I understand the principle behind the sanity check and the check i can do in psudocode. Here is the code i have got so far -
>
p4a_db::singleton()->query("INSERT INTO meetingrooms(location_id, bookingtime, bookingend, merono_id)
WHERE bookingtime < " . $date . " AND bookingend > " . $date . "
OR
bookingdate < " . $date . " AND bookingend > " . $dateend . "
VALUES(?,?,?,?)",
array($location, $date, $dateend, $merono));
I don't want to insert data directly into the statement but until i understand how to do this i am stuck, so the question,
How do i perform a sanity check before the data is inserted so that i don't get dates within booked times.
any help would be greatly appreciated.
Edit:
I've been overthinking my answer and I realized that the old solution will not work in your case since you need the time span, comparing the start and end date is useless.
My way of processing this would be:
Save the dates as int, use 24h system (7:40am is 740, 9:50pm is 2150)
Check for stored dates where: (Start<NewStart<End)
Check for stored dates where: (Start<NewEnd<End)
When processing several rooms, just store room number + time as int. That way you can still use the method from 2 and 3.
2 and 3 can be done in a sql query, check out this link.
Old answer (checking for duplicates)
This is an example of how to check for duplicates (in this case email) before inserting the text:
$emailexist = $mysqli->prepare("select email from users where email = ?");
$emailexist->bind_param('s', $email);
$emailexist->execute();
$emailexist->store_result();
if ($emailexist->num_rows > 0) {
$emailexist->close();
$mysqli->close();
return true;
}
else {
$emailexist->close();
$mysqli->close();
return false;
}
It checks if there are rows which contain the string. If so (if number of rows higher than 0) it returns true (which means, the date already exists).
You can just adapt this to you code.
However, you could also just set the columns to UNIQUE. Then you get an error when trying to insert it. It is easier and you won't have problems with concurrent connections.
after a long and intensive search, I have now got a working example of this method, along with a method of protecting against sql injection, here's the code;
if ($this->BookingValue == 1)
{
$sql = "SELECT COUNT(*) as num FROM meeting_room_bookings
WHERE
(
(? < start_at AND ? > start_at)
OR
(? > start_at AND ? < end_at)
)
AND
meeting_room_id = ?";
$result = p4a_db::singleton()->fetchRow($sql, array($date, $date, $date, $dateend, $merono));
if ( 0 == $result["num"] )
{
p4a_db::singleton()->query("INSERT INTO meeting_room_bookings (start_at, end_at, meeting_room_id)
VALUES
(?,?,?)", array($date, $dateend, $merono));
return true;
}
else
{
return false;
There isn't much to explain about this code, but in term of differences, (excluding the change in column names with the table) the query is now prepared before the value is set, then it is possible to use it in an if statement, thus allowing the validation to take place to filter results between different dates.
along with this i have added validation to stop dates from other meeting rooms being included within the statement via the AND statement where the meeting room id is limeted to a single value.
Although now, which will lead on to a separate question is another thrown error that comes from this statement, i know the insert is sound but something from this prepared statement causes the error:
SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens
File: Pdo.php, Line: 234
Although now i am looking into a error that is thrown from the prepared statement and will update this answer when there is a fix, thanks for the help.
Hi since 3 hour I am trying to make this work but not getting the result as I want. I want to display user list with online and offline status.
Here is the table
and here what I tried to get status result.
$loggedtime = time() - 300; // 5 minutes
$query = 'SELECT userid, handle FROM ^users WHERE loggedin = '.$loggedtime.' ORDER BY userid ASC';
// below are scripts function qa_ pleses refer this http://www.question2answer.org/functions.php
$result = qa_db_query_sub($query);
$users = qa_db_read_all_assoc($result);
$row = mysql_fetch_array($result);
if($row['userid'] > $loggedtime){
echo $row['handle'].' is online';
} else {
echo $row['handle'].' is offline';
}
NOT THIS TOO
foreach($users as $user){
if($user['userid'] > $loggedtime){
echo $user['handle']. ' is online';
} else {
echo $row['handle'].' is offline';
}
}
None of above code working. I am new to MYSQL and PHP just know basic so please help me to solve this.
EDIT:
I have tried now this but not working
foreach($users as $user){
if($user['loggedin'] > $loggedtime){
echo $user['handle']. ' is online';
} else {
echo $row['handle'].' is offline';
}
}
EDIT 2
$query = "SELECT
userid, handle,
CASE
WHEN TIMESTAMPDIFF(SECOND, loggedin, NOW()) < 300
THEN 'Online'
ELSE 'Offline'
END AS 'status'
FROM ^users
ORDER BY userid";
$result = qa_db_query_sub($query);
while($user = mysql_fetch_array($result)){
echo $user['handle'] . '<BR/>';
}
NEW APPROACH
Please check this for new approach User online offline status - offline status issue
Since you fixed the user id comparison, let's address the next issue..
You're trying to compare a string DATE versus a unix timestamp. Let's make them the same type and compare:
foreach($users as $user)
{
$user_time = strtotime($user['loggedin']);
if($user_time > $loggedtime)
{
echo $user['handle']. ' is online';
} else {
echo $row['handle'].' is offline';
}
}
Overall not the best way to approach this problem, but it might get this working for you. The database solution above is probably best.
Your structure looks funny to answer the question. Your loggedin field actually looks more like a "the last time they logged in". Just because you know when they logged in doesn't necessarily mean they are "online".
The reason your query isn't working is because you are comparing a UNIX timestamp to a mysql datetime. In addition, you are using = so unless they logged in EXACTLY five minutes ago, this will not work.
At minimum.
SELECT userid, handle FROM ^users WHERE loggedin > '.date('Y-m-d h:i:s', time()-300).'ORDER BY....
Why not just check on the database side?
SELECT
userid, handle,
CASE
WHEN TIMESTAMPDIFF(SECOND, loggedin, NOW()) < 300
THEN 'Online'
ELSE 'Offline'
END AS 'status'
FROM ^users
ORDER BY userid
You can use TIMESTAMPDIFF(unit,datetime_expr1,datetime_expr2) to return datetime_expr2 – datetime_expr1, where datetime_expr1 and datetime_expr2 are date or datetime expressions. One expression may be a date and the other a datetime; a date value is treated as a datetime having the time part '00:00:00' where necessary. The unit for the result (an integer) is given by the unit argument. The legal values for unit are the same as those listed in the description of the TIMESTAMPADD() function.
Take a look at the MySQL Date and Time Functions.
Also, I strongly advise using reserved words for table names.
I want people to be able to "bump" what they've wrote in my database but at the same time only allow the input to be in the table ONCE at a time.
For Example:
Jim's code is 5555. Jim enters his code and it shoots to the very bottom of the table. After 34 minutes he tries to enter his code in again (Because various other people have inputted their code between now and then) but gets a display error letting him know he has 26 minutes to wait still.
Joe inputs his code and waits an hour and five minutes and is able to push his code back to the bottom again.
Basically, I'm displaying data from the bottom up in my table.
Is there any way to easily do this?
function some_more_custom_content() {
$output="<BR>";
ob_start();
if ($_REQUEST['code'] != "") {
$code = $_REQUEST['code'];
$query="INSERT INTO `fc` (`code`,`datetime`) values ('" . mysql_real_escape_string($code) . "', now())";
$result=mysql_query($query);
$entry['datetime'] = strtotime($entry['datetime']);
while ($fetch_array = mysql_fetch_array($result)) {
$seconds = time() - strtotime($fetch_array["datetime"]);
if ((time() - $entry['datetime']) < 60*60) {
echo ("The code " . htmlentities($code) ." was updated less than an hour ago.");
} else {
echo ("Inserted " . htmlentities($code) ." into the top.");
}
}
?>
I get a syntax error. Any idea where it is?
UPDATE: Getting error of:
Parse error: syntax error, unexpected $end
you should create a table with a unique index on the code field and then use a query like:
INSERT INTO CODES (code)
VALUES (555)
ON DUPLICATE KEY UPDATE lastUpdated =
case when NOW() - INTERVAL 5 MINUTE > lastUpdated
then NOW()
else lastUpdated end
this will update the lastUpdated field only in cases when it's older than 5 minutes
Not that hard:
Use a timestamp for the last "bump time".
When a code is entered, check if it already exists in the database.
If it doesn't, insert it and set the bump timestamp to now().
If it does exist, check if the timestamp was within the hour.
If it was, display error.
If it wasn't, reset it to now().
Sort your display data by bump timestamp.
EDIT:
$entry = /* get entry from database, assuming the case where it already exists */;
// depending on the format of timestamp you get from the database,
// you may have to convert it to a UNIX timestamp:
$entry['timestamp'] = strtotime($entry['timestamp']);
if ((time() - $entry['timestamp']) < 60*60) { // 60*60 is one hour in seconds
// display error
} else {
// reset bump
}
I am creating an online calendar for a client using PHP/MySQL.
I initiated a <table> and <tr>, and after that have a while loop that creates a new <td> for each day, up to the max number of days in the month.
The line after the <td>, PHP searches a MySQL database for any events that occur on that day by comparing the value of $i (the counter) to the value of the formatted Unix timestamp within that row of the database. In order to increment the internal row counter ONLY when a match is made, I have made another while loop that fetches a new array for the result. It is significantly slowing down loading time.
Here's the code, shortened so you don't have to read the unnecessary stuff:
$qry = "SELECT * FROM events WHERE author=\"$author\"";
$result = mysql_query($qry) or die(mysql_error());
$row = mysql_fetch_array($result);
for ($i = 1; $i <= $max_days; $i++) {
echo "<td class=\"day\">";
$rowunixdate_number = date("j", $row['unixdate']);
if ($rowunixdate_number == $i) {
while ($rowunixdate_number == $i) {
$rowtitle = $row['title'];
echo $rowtitle;
$row = mysql_fetch_array($result);
$rowunixdate_number = date("j", $row['unixdate']);
}
}
echo "</td>";
if (newWeek($day_count)) {
echo "</tr><tr>";
}
$day_count++;
}
The slowness is most likely because you're doing 31 queries, instead of 1 query before you build the HTML table, as Nael El Shawwa pointed out -- if you're trying to get all the upcoming events for a given author for the month, you should select that in a single SQL query, and then iterate over the result set to actually generate the table. E.g.
$sql = "SELECT * FROM events WHERE author = '$author' ORDER BY xdate ASC";
$rsEvents = mysql_query($sql);
echo("<table><tr>");
while ($Event = mysql_fetch_array($rsEvents)) {
echo("<td>[event info in $Event goes here]</td>");
}
echo("</tr></table>");
Furthermore, it's usually a bad idea to intermix SQL queries and HTML generation. Your external data should be gathered in one place, the output data generated in another. My example cuts it close, by having the SQL immediately before the HTML generation, but that's still better than having an HTML block contain SQL queries right in the middle of it.
Have you run that query in a MySQL tool to see how long it takes?
Do you have an index on the author column?
There's nothing wrong with your PHP. I suspect the query is the problem and no index is the cause.
aside from their comments above, also try to optimize your sql query since this is one of the most common source of performance issues.
let say you have a news article table with Title, Date, Blurb, Content fields and you only need to fetch the title and display them as a list on the html page,
to do a "SELECT * FROM TABLE"
means that you are requiring the db server to fetch all the field data when doing the loop (including the Blurb and Content which you are not going to use).
if you optimize that to something like:
"SELECT Title, Date FROM TABLE" would fetch only the necessary data and would be more efficient in terms of server utilization.
i hope this helps you.
Is 'author' an id? or a string? Either way an index would help you.
The query is not slow, its the for loop thats causing the problem. Its not complete; missing the $i loop condition and increment. Or is this a typo?
Why don't you just order the query by the date?
SELECT * FROM events WHERE author=? ORDER BY unixdate ASC
and have a variable to store the current date you are on to have any logic required to group events by date in your table ex. giving all event rows with the same date the same color.
Assuming the date is a unix timestamp that does not account for the event's time then you can do this:
$currentDate = 0;
while(mysql_fetch_array($result)){
if($currentDate == $row['unixdate']){
//code to present an event that is on the same day as the previous event
}else{
//code to present an even on a date that is past the previous event
//you are sorting events by date in the query
}
//update currentDate for next iteration
$currentDate = $row['unixdate'];
}
if unixdate includes the event time, then you need to add some logic to just extract the unix date timestmap excluding the hours and minutes.
Hope that helps