I am trying to create a script where if the date is later than today then it will display an item from the table in MySQL.
$query = $dbc->query("SELECT event_id, name, location, image, DATE_FORMAT(Date, '%d-%b-%Y') AS Date, Date as FormatDate
FROM events
ORDER BY FormatDate ASC
");
$results = $query->setFetchMode(PDO::FETCH_ASSOC);
while($row = $query->fetch()){
$name = $row['name'];
$image = $row['image'];
$location = $row['location'];
$Date = $row['Date'];
$Date = strtotime($Date);
$Date = date('d-M-Y', $Date);
$Data = explode("-", $Date);
if (strtotime($Date) >= time()){
$page->body("
<div class=\"event\">test
<img src=\"$image\" alt=\"$name\" class=\"event_image\"/>
<p class=\"event_title\">$name</p>
<p class=\"event_location\">$location</p>
<p class=\"event_time\">$Data[0] $Data[1] $Data[2]</p>
</div>
");
}else{
$page->body ("
<!-- alrge grey text 100% span -->
<div class=\"event\">
<p>There are currently no events happening.</p>
</div>
");
}
}
}
When I add an event to the table with a later date than today it adds successfully and the script runs and I can see the event printed out on the page because the date if greater than time().
But if I clear the MySql table of all events then it doesn't bring back the else statement "There are currently no events happening".
I am stumped as to why the else statement doesn't bring back the failed notification if there is nothing in the table that is later than today.
Any help much appreciated.
But if I clear the MySql table of all events then it doesn't bring back the else statement "There are currently no events happening".
The while statement will only execute if there are rows to process. Since you've cleared the table, it will never enter the while loop, and the else branch will never be encountered.
Because there are no rows to fetch and your code is not going inside while loop when your table is empty.
HTH!
Related
i have made a webpage using html and php that allows users to book appointments, but my slots are every 30 minutes but the way i am currently doing it will not add 30 minutes on to the database
<?php ob_start( ); ?>
<html>
<head>
<link rel="stylesheet" type="text/css" href="Nav.css">
<title>Book Barber</title></head>
<body>
<?php
echo " <div class='navigation'><a href='BarberHomeScreen.php'>Home</a><div class='dropdown'><button class='dropdownButton'>Account<i class='fa fa-caret-down'></i></button><div class='dropdownContent'><a href='MyAccount.php'>My Account</a><a href='SignOut.php'>Sign Out</a></div></div></div>";
?>
<h1>Booking a barber appointment for <?php session_start();echo $_SESSION['customerName'];?></h1>
<form method="POST" action="#">
<input type="date" name="selectDate" />
<input type="submit" name="submitDate"/>
<?php
if(isset($_POST['submitDate'])){
//if the submit button has been pressed, connect to the db
//and search for all the available tables on that selected day
$conn = mysql_connect(localhost, "root", "");
if(!$conn){
die("Could not connect: " . mysql_error());
}
$selectedDb = mysql_select_db('booking', $conn);
if(!$selectedDb){
die("Can't use the selected db: " . mysql_error());
}
//selects all the bookings for the date chosen in the form
$query= "SELECT * FROM booking WHERE BookingDate = '" . $_POST['selectDate'] . "' ORDER BY customerID, BookingTime";
$result = mysql_query($query);
//stop php while table headers outputted
?>
<table border="1">
<tr></tr>
<tr>
<th>Barber</th>
<th>9:00</th>
<th>9:30</th>
<th>10:00</th>
<th>10:30</th>
<th>11:00</th>
<th>11:30</th>
<th>12:00</th>
<th>12:30</th>
<th>13:00</th>
<th>13:30</th>
<th>14:00</th>
<th>14:30</th>
<th>15:00</th>
<th>15:30</th>
<th>16:00</th>
</tr>
<?php //start php again to output the bookings available or not
/*The next bulk of php is outputting the table showing which slots are booked and which are available.
two while loops are needed, the outer one loops through the tables, the inner while loops through
each of the times for the table.
Then while the loops are repeating they check if this booking
is for the current timeslot and table being looked at. If so it puts an X in the td and carries out mysql_fetch_assoc
again to get the next booking from the $result. This continues for each of the slots in the table.
*/
$row = mysql_fetch_assoc($result);
$time = 9;
echo "<tr>";
echo "<td>" . $count . "</td>";
while($time <= 16){//time begins at 9 and stops at 16. Would be better to get this from the db too.
if((Time($row['BookingTime'])==$time)){
echo "<td style='background-color:lightCoral'>X</td>";
$row = mysql_fetch_assoc($result);
}else{
echo "<td style='background-color:lightGreen'><a href='MakeBarberBooking.php?&time=" . $time. "&date=" . $_POST['selectDate'] ."'>Book</a></td>";
}
$time=$time+0.5;
}
echo "</tr>";
}//end while
//end if submit pressed
?>
</table>
</form>
</body>
</html>
<?php
ob_end_flush( );
?>
the system loops through each time slot using the time=time+0.5 but that records the time as 10.5 instead of 10:30 for instance
Besides that ProEvilz already commented about Sql Injection, adding .5 will not magically make it into a date/time format.
Work with the date object (or DateTime class in php5.4+) and for each iteration you use this:
Initial value would be
$currentTime = "09:00";
$nextTime = date("H:i", strtotime($currentTime ." +30 MINUTE"));
$nextTime would be 09:30..
You could use PHP's DatePeriod function.
First create the start and end times. Then create a date interval and loop over the object.
N.B. its worth noting you may need to add the interval to the dtEnds to get the loop to include the last period.
// set format the date string is formatted as
$format = 'Y-m-d H:i:s';
// set the start and end date
$dtStarts = new DateTime();
$dtEnds = new DateTime::createFromFormat($format, '2017-12-01 06:00:00');
// create intervals that we would like to loop over
// i.e. 1 day at a time, or every 45 minutes
$dtInterval = DateInterval::createFromDateString('1 days');
$dtIntraDayInterval = DateInterval::createFromDateString('45 minutes');
// set day period/range
$dpPeriod = new DatePeriod( $dtCalStarts, $dtInterval, $dtCalEnds );
// loop oveer each period in the day
foreach ( $dpPeriod as $dtDay ){
echo "<pre>";
var_dump($dtDay);
echo "</pre>";
}
I have a mysql database with a field called DATE, storing data as a date. I am trying to get the php date to select records for the next 31 days from the current date.
This is what I have...
$start_THISMONTH = "-1";
if (isset($to_date)) {
$start_THISMONTH = $to_date;
}
$finish_THISMONTH = "-1";
if (isset($from_date)) {
$finish_THISMONTH = $from_date;
}
mysql_select_db($database_WHTSON, $WHTSON);
$query_THISMONTH = sprintf("SELECT * FROM CALENDAR WHERE DATE BETWEEN %s AND %s AND APPROVED = 1 ORDER BY DATE ASC", GetSQLValueString($start_THISMONTH, "date"),GetSQLValueString($finish_THISMONTH, "date"));
$THISMONTH = mysql_query($query_THISMONTH, $WHTSON) or die(mysql_error());
$row_THISMONTH = mysql_fetch_assoc($THISMONTH);
$totalRows_THISMONTH = mysql_num_rows($THISMONTH);
-
The code to set up the two variables is
$from_date = date("Y-m-j");
$to_date = date('Y-m-j', strtotime("+31 days"));
And my php code in the body is
<h4><strong><font color="#FF0000"><?php echo $row_THISMONTH['EVENT_NAME']; ?></font></strong></h4>
<?php $date = date_format($row_THISMONTH['DATE'], 'jS F'); ?>
<h5><em><?php echo $date; ?>, <?php echo $row_THISMONTH['TIMES']; ?><br />
<?php echo $row_THISMONTH['LOCATION_ADDRESS']; ?>, <?php echo $row_THISMONTH['LOCATION_TOWN']; ?> <?php echo $row_THISMONTH['LOCATION']; ?></em><br />
</h5>
<p><?php echo $row_THISMONTH['EVENT_DETAILS']; ?><br />
</p>
No results are showing up. This is a new build database, and only one record is in there, with a date of Valentines Day. If I change the code to a simple "find all records" query it shows up great (though the date_format doesn't display a date.
This is my nemesis, please help me understand what I've done wrong?
If you have a date field column in mysql(YYYY-MM-DD) then try date('Y-m-d') instead of date('Y-m-j')
I have been staring at this for so long, but I think I have found one answer. I tried to be logical and use $to_date and $from_date, and then put them in the wrong order in the query. So although I haven;t actually solved the issue, I thinnk the issue is my untidyness on this occasion. I learnt a lot from the discussion too, thank you very much - time for a cleen sheet and a slower pace :)
I have recently noticed on my website that a news page is repeating news articles from all "May"'s in the database (you will notice by looking here: www.darlingtontowntwinning.co.uk/news_&_events)
I know that the coding is messy and possibly out of date, however, the website was built for us, and I don't have the skills (yet - I am learning!) to change the entire website at this time.
Is there a way to stop this from occuring - since I believe I have already got a limit of one of each record to display:
<div id="right" class="news">
<h3>Archive</h3>
<? $news=$session->getNews("","","",1);?>
<? while($article=mysql_fetch_array($news)){?>
<?
$date = $article['thedate'];
$year = date('Y', $date);
$month = date('F', $date);
?>
<h4><?=$month." - ".$year;?></h4>
<nav class="small">
<? $innernews=$session->getNews("",$month,$year);?>
<? while($innerarticle=mysql_fetch_array($innernews)){?>
<a href="/news/<?=$innerarticle['ftitle']?>" <? if($title==$innerarticle['ftitle']){?> class="active"<? }?>><?=$innerarticle['title']?></a>
<? }?>
</nav>
<? }?>
</div>
Get news function is:
function getNews($title,$month,$year,$group){
global $database;
return $database->getNews($title,$month,$year,$group);}
$database->getNews function is:
//get news
function getNews($title,$month,$year,$group){
if($title){
$q=$this->query("SELECT * FROM ".TBL_NEWS." WHERE ftitle = '$title'" );
return mysql_fetch_array($q);
}else if($year && $month){
$q=mysql_query("SELECT * FROM ".TBL_NEWS." WHERE (FROM_UNIXTIME(thedate, '%Y') = '$year') AND (FROM_UNIXTIME(thedate, '%M') = '$month') ORDER BY thedate DESC");
return $q;
}else if($group){
$q=$this->query("SELECT * FROM ".TBL_NEWS." GROUP BY (FROM_UNIXTIME(thedate, '%Y')),(FROM_UNIXTIME(thedate, '%M')) ORDER BY thedate DESC" );
return $q;
}else{
$q=$this->query("SELECT * FROM ".TBL_NEWS." ORDER BY thedate DESC" );
return $q;
}
}
The code appears to be working
//get news from group 1
$news=$session->getNews("","","",1);
// for each article work out the date
while($article=mysql_fetch_array($news))
$date = $article['thedate'];
$year = date('Y', $date);
$month = date('F', $date);
...
// then select everything again after working out the date (odd way of doing it)
$innernews=$session->getNews("",$month,$year);
// and output each
So, because there are two event in May, it's outputting the header twice. Let me go over that...
Get news grouped by date (allegedly)
June, just 1 article
1:
Output the header
Select the articles
Output the article
May, 2 articles
1:
Output the header
Select the articles
Output the article
2:
Output the header
Select the articles
Output the article
This group by SELECT * FROM ".TBL_NEWS." GROUP BY (FROM_UNIXTIME(thedate, '%Y')),(FROM_UNIXTIME(thedate, '%M')) ORDER BY thedate DESC is not behaving as expected and is returning two results for May
Try this code
<div id="right" class="news">
<h3>Archive</h3>
<?
$news=$session->getNews();
$bydate=array(); // articles by date
while($article=mysql_fetch_array($news)){
$k=date('YF', $date);
if (!isset($bydate[$k])) $bydate[$k]=array(); // create sub array
$bydate[$k][]=$article; // push article to this sub array
}
foreach ($bydate as $date->$articles){ // run through top array
?><h4><?= substr($date,4) . " - " . substr($date,0,4); ?></h4><nav class="small"><?
foreach ($articles as $innerarticle){ // now each article within this date
?><a href="/news/<?=$innerarticle['ftitle']?>" <? if($title==$innerarticle['ftitle']){?> class="active"<? }?>><?=$innerarticle['title']?></a><?
}
?></nav><?
}
?></div>
and please change
function getNews($title,$month,$year,$group){
to
function getNews($title=NULL, $month=NULL, $year=NULL, $group=NULL){
Welp. There's your problem.
Your function says, if($title). Since $title comes in as a required parameter in the function, I think PHP is registering it as, yes, that's a variable that is set. So, basically what happens, then, is you're getting back a mysql_fetch_array result, which you are then running mysql_fetch_array for a second time.
Try:
//in your function getNews()
if($title){
$q=$this->query("SELECT * FROM ".TBL_NEWS." WHERE ftitle = '$title'" );
return $q;
}
//rest of function down here
That could work. The issue I see is, doing that, you WILL CAUSE ISSUES ANYWHERE ELSE THAT FUNCTION IS CALLED. So be careful! The fix above is the fix to ensure you get code into a better state. If you want a hack, try this:
<? $innernews=$session->getNews("",$month,$year);?>
<? foreach($innernews as $innerarticle) {?>
<a href="/news/<?=$innerarticle['ftitle']?>" <? if($title==$innerarticle['ftitle']){?> class="active"<? }?>><?=$innerarticle['title']?></a>
<? }?>
The foreach loop should give you what you want!
I have load of data in the DB and each row has a date column
Currently im pulling all the results onto a page but i want to split it up into months.
I have buttons on my page that when clicked should display only the appropriate results, for example when the button January 2012 is click all the results for that month will be displayed
Heres an example of what im trying to achieve:
http://i.stack.imgur.com/PY7iN.jpg
=================================================================================
<?php
$con = mysql_connect("localhost", "username", "pass");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("database", $con);
$result = mysql_query("SELECT * FROM tablename");
$num_rows = mysql_num_rows($result);
echo "<table border='0' cellspacing='0'>";
while($row = mysql_fetch_array($result))
{
$i++;
if($i%2==0) $class="cell1"; else $class="cell2";
echo "<tr class='$class'>";
echo "<td>".$row["firstname"]." ".$row["lastname"]." thinks that it will happen on
<span class=datecolor>".date('l jS F Y',strtotime($row['date']))."</span></td>";
echo "</tr>";
}
echo "</table>";
mysql_close($con);
?>
=========================================================================
Im looking for a little help on how i can display the results for each month by clicking on the buttons without it appearing all at the one time.
Also the when the page is first viewed id like it to automatically show the results for the current month, for example it if viewed now it would display the August results
Hope you can help
To address your first question (displaying one month at a time), your best bet is to make your database do all of the work for you. Right now your SQL SELECT statement looks like
SELECT * FROM tablename
You want to add a WHERE clause that will restrict this query to only show you rows for a certain month… something like
SELECT * FROM tablename WHERE date BETWEEN '05/01/2011' AND '05/31/2011'
You may need to tweak this for your particular database engine or setup. Here's one WHERE tutorial; you can find tons more on the web.
You can have all your buttons be links to the page with a query string that specifies the month (for example: www.mysite.com/mypage?month=september). Then get the month from the query string and only select the rows that are in that month.
See:
PHP parse_str()
$_SERVER['QUERY_STRING']
MySQL Select a Date Range
Something like
$month = isset($_GET['month']) ? intval($_GET['month']) : 0;
$year = isset($_GET['year']) ? intval($_GET['year']) : 0;
if( empty($month) ){
$month = date('n');
}
if( empty($year) ){
$year = date('Y');
}
$query = mysql_query('SELECT * FROM table_name WHERE MONTH(date_field)="'.$month.'" AND YEAR(date_field)='.$year.'"');
// or maybe use BETWEEN syntax
while( false!==($row=mysql_fetch_assoc($query)) ){
// do something...
}
Year is needed because one month number may belong to diffent year number (03-2010,03-2011 etc..), and, so when your data covers dates from different years, you cannot determine what data you need only having month
Bit of a strange problem here...
I've got an update query that isn't working, and I can't for the life of me work out why!
My table has two three fields - 'id' (int, auto increment), 'date' (date), and 'amountraised' (decimal). Part of the app I'm developing calculates the fundraising total each week made by a charity bookstall. The 'date' field uses a date column type as elsewhere on the site I'm using the dates in calculations.
Elsewhere within the system I've got other update queries that are working just fine, but I suspect the problem with this one is that as well as updating the record I'm also trying to manipulate the date format as well (so that I can enter dates in the British dd-mm-yyyy format and then use the PHP to convert back into the MySQL-friendly yyyy-mm-dd format.
This is the strange bit. According to the confirmation page on the site, the query has run okay, and the update's been made, but when I check the database, nothing's changed. So I could check what the output of the query is I've tried echoing the result to the web page to see what I'm getting. The expected values show up there on the page, but again, when I check the database, nothing's been updated.
This is my update form with the date conversion function:
function dateconvert($date,$func) {
if ($func == 1){ //insert conversion
list($day, $month, $year) = split('[/.-]', $date);
$date = "$year-$month-$day";
return $date;
}
if ($func == 2){ //output conversion
list($year, $month, $day) = split('[-.]', $date);
$date = "$day/$month/$year";
return $date;
}
} // end function
require_once('/home/thebooks/admins/connect.php');
$id = $_GET['id'];
$dateinput = $_GET['dateinput'];
$query = "SELECT * FROM fundraisingtotal WHERE id='$id'";
$result = mysql_query($query);
$row = mysql_fetch_array($result);
extract($row);
$date = $row['date']; //your mysql date
$realdate = dateconvert($date,2); // convert date to British date
$amountraised = stripslashes($amountraised); //amount raised
mysql_close();?>
<div id="title">Update Fundraising Total</div>
<form id="updatetotals" action="updated.php" method="post">
<div class="row"><label for="dateinput" class="col1">Date </label><span class="col2"><input id="dateinput" name="dateinput" type="text" size="25" value="<?php echo $realdate ?>" maxlength="10" /></span></div>
<div class="row"><label for="amountraised" class="col1">Fundraising Total </label><span class="col2"><input id="amountraised" name="amountraised" type="text" size="25" value="<?php echo $amountraised ?>" maxlength="7" /></span></div>
<div class="submit"><input type="submit" name="submitted" value="Update" /><input type="reset" name="reset" value="Clear the form" /></div>
<input type="hidden" name="id" value="<?php echo $id ?>" />
</form>
...and this is the form processing/query page:
require_once('/home/thebooks/admins/connect.php');
$dateinput = $_POST['dateinput'];
// Date conversion from: http://www.phpbuilder.com/annotate/message.php3?id=1031006
// using type 1
$convdate = $_POST['dateinput']; // get the data from the form
$convdate = dateconvert($convdate, 1); // Would convert to e.g. 2005-12-19 which is the format stored by mysql
function dateconvert($convdate,$func) {
if ($func == 1){ //insert conversion
list($day, $month, $year) = split('[/.-]', $convdate);
$date = "$year-$month-$day";
return $date;
}
if ($func == 2){ //output conversion
list($year, $month, $day) = split('[-.]', $convdate);
$date = "$day/$month/$year";
return $date;
}
}
$date = "$convdate";
$amountraised = $_POST['amountraised'];
$update = "UPDATE fundraisingtotal SET date = '$date', amountraised = '$amountraised' WHERE id='$id' ";
$result = mysql_query($update);
$realdate = dateconvert($date,2); // convert date to British date
if ($result) {
echo "<p class=\"dbpara\">Thank you. Your update to the record was successful.</p>";
echo "<p class=\"dbpara\">The record has been amended to a date of <b>$realdate</b> and amount of <b>$amountraised</b>.</p>";
}
else {
echo "<p>Nothing has been changed.</p>";
}
mysql_close();
The weird thing is that the confirmation text "The record has been amended to...etc." displays exactly as expected, but when I check the database, the record hasn't been updated at all.
I'm sure it must be something I'm missing with messing with the date formats or I've got something in the wrong order, but I've tried so many different variations on this now I can't see the wood for the trees. Anyone any ideas what I'm doing wrong here?
I see some red-flags here. You are getting the date from a form and inputing it into MySQL without any form of validation - that could lead to SQL-injections.
Start by changing dateconvert function to something more secure. This function will always return a correct formated date, even if the user tries to abuse the system.
Edit 1: Forgot to put a : after case 'en_en' but fixed it now. Thanks neonblue.
Edit 2: Forgot to feed the date() function with the timestamp. Fixed!
Edit 3: A preg_replace to convert frontslashes to dashes
// this function always returns a valid date
function dateconvert($date = NULL, $date_type = 'sql') {
$date = preg_replace("/", "-", $date);
$timestamp = strtotime($date);
switch($date_type) {
default: case 'sql' : return date('Y-m-d', $timestamp); break; // prints YYYY-MM-DD
case 'en_EN' : return date('d-m-Y', $timestamp); break; // prints DD-MM-YYYY
}
}
You can always have a look into Zend_Date that will let you work with dates on your own format.
Change
$result = mysql_query($update);
to
$result = mysql_query($update) or die(mysql_error());
And you should see what the problem is when the query fails.
Three things I would look for:
Is the code attaching to the same database you are looking at? (I spent a few hours on this one ;)
Is another update statement (or this one) running immediately afterwards that would change the values back? Here you need some logging to figure it out.
If you echo the sql, what happens when you run it directly yourself?
If you see the table is not changing any value but the query does not show you any error, then WHERE id = '$id' is not hitting the register you intended to.
Don't forget to sanitize your queries as others are telling you.