im trying to select date from mysql between dates with this code
if(isset($_REQUEST['datefrom']) and $_REQUEST['datefrom']!=""){
$condition .= ' AND date LIKE "%'.$_REQUEST['datefrom'].'%" ';
}
if(isset($_REQUEST['dateto']) and $_REQUEST['dateto']!=""){
$condition .= ' AND date LIKE "%'.$_REQUEST['dateto'].'%" ';
}
Please help
THX
Assuming your date are timestamps, date, etc.
This is the most secure way to prevent SQL injection, using PHP PDO.
<?php
$dbh = new PDO('your_server', 'your_user', 'your_password');
$sth = $dbh->prepare('SELECT * FROM table WHERE date BETWEEN :from AND :to');
// Bind date params
$sth->bindParam('from', $_REQUEST['datefrom']);
$sth->bindParam('to', $_REQUEST['dateto']);
// Execute query
$sth->execute();
// This a test
print_r($sth->fetchAll());
?>
More here.
It seems you are trying to use the LIKE operator because your dates are stored as strings in your database.
You should convert them to dates, then you can just use the BETWEEN operator with them. It shouldn't be too dificult and I'm sure you can find how to do it in this site. I suggest that you do it by storing the conversion in a new column first.
Related
I want to send a reminder to my subscribers a month before their subscription ends, i have columns validity and reminder (type VARCHAR) in my MYSQL DB
date stored in those columns are saved using php date function
$validity = date('d/m/Y',strtotime("6 months"));
$reminder = date('d/m/Y',strtotime("5 months"));
now i want to send a mail when the current date is equals reminder date
I have a test entry with reminder value 22/06/2017 and $date variable echo the same value.
$date = date('d/m/Y');
$q = 'SELECT * FROM subscriptions WHERE reminder = "$date"';
$r = mysql_query($q);
if(!$r){
echo 'query err';
}
$a = mysql_num_rows($r);
echo 'No of rows returned '.$a;
*mailing script after this line*
this script outputs No of rows returned 0
Can someone give me some idea how i should approach this
First i suggest you your date format is change in database and type change datetime.
This format follow for you insert reminder date
$reminderdate = date('Y-m-d');
Then compare with currentdate when fetch data from database:
$date=date('Y-m-d');
if($r['reminder']==$date)
{
echo 'Mail sent here';
}
else
{
echo 'date not match';
}
Your script is at risk for SQL Injection Attacks, see this
The issue is here:
'SELECT * FROM subscriptions WHERE reminder = "$date"';
change it to:
"SELECT * FROM subscriptions WHERE reminder = '".$date."'";
to compare date, you have to wrap it into single quotes '
A few suggestions:
the reminder column may be redundant depending on your logic
in the future please use different approach to connect to the database, for example: http://php.net/manual/en/mysqli.quickstart.prepared-statements.php
the validity column should rather be DATETIME format
Now to your main question - it can be because of datetype mismatch so switch in database to DATETIME and in PHP use date('Y-m-d').
First Of all You should not store date in varachar.
Now to compare dates in varchar first you have to convert the string(varchar) into date.
for that you can use mysql's function:
str_to_date
You can get the example how to convert it and then compare it to get the result.
$q = "SELECT * FROM subscriptions WHERE reminder = '{$date}'";
I Know You have selected the answer already and ignored the comments, because you just want to get this done with and move on no matter how you did it. I will just make this answer a community WIKI.
Below are the things you need to note :
The API that you are using have depreciated for a long time ago rather use mysqli or even better PDO with prepared statements.
Also What I'm sure when the use subscrips on your website, you should have a column that stores the duration of the subscription and the actual expire date and a flag to identify expired subscriptions.
Mysql does provide its own date time functions, which you can use and use the date type on these columns.
Use API that is still active and maintained that is mysqli_* or pdo they both support prepared statements.
$host = '127.0.0.1';
$db = 'DBNAME';
$user = 'root';
$pass = '';
$charset = 'utf8';
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$opt = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false
);
$dbh = new PDO($dsn, $user, $pass, $opt);
$stmt = $dbh->query("SELECT * FROM subscriptions WHERE subscriptionsExpireColumn = DATE_ADD(CURDATE(), INTERVAL 1 MONTH)");
if (!$stmt) {
echo "\nPDO::errorInfo():\n";
print_r($dbh->errorInfo());
} else {
$results = $stmt->fetchall();
if (count($results) > 0) {
foreach ($results as $row) {
//DO WHAT EVER YOU WANT TO DO WITH THE RESULTS
}
} else {
echo "no records found";
}
}
?>
I have a crazy phenomenon in my php script. I have defined a column as a timestamp in a mysql table. I fill it with the function:
date("Y-m-d H:i:s");
The data in the table then look like this: 2017-04-19 17:08:45
When I query this column with mysqli as a unix timestamp again:
SELECT UNIX_TIMESTAMP (timestamp) as timestampUnix FROM posts
Then binding the result using bind_result to the variable $timestampUnix.
I can echo the variable with
echo $timestampUnix;
and it outputs a correct timestamp like this: 1492614559
however if i do the following:
$timestampUnix2 = $timestampUnix;
echo $timestampUnix2;
there is simply no echo output... What is the reason?
I tried this because I actually want echo only the date in an other format with:
date('d.m.Y', $timestampUnix)
and it gave me 01.01.1970 and i wondered why the timestamp must be 0 but it isnt since when i directly echo it it gives me a correct one.
however when i do
Date('d.m.Y', 1492614559)
it gives me the correct date.. no clue what is going on there!
i know there are many other questions about mysql php Date output, but no one have this issue as i think i cannot do something with the variable i got from the query.
thanks in advance!
edit: i attach the complete code in question:
---the query that inputs the data in the db----
$timestamp = date("Y-m-d H:i:s");
mysqli_query($mysqli,"INSERT INTO posts (timestamp)
VALUES ('$timestamp')");
---the query that fetches the data----
$results = $mysqli->prepare("SELECT UNIX_TIMESTAMP(timestamp) as timestampUnix FROM posts");
$results->execute(); //Execute prepared Query
$results->bind_result($timestampUnix); //bind variables to prepared statement
$postdate = date('d.m.Y',$timestampUnix)
echo $postdate;
I'm trying to get mySQL to send me posts between two dates. Since the dates are user input I use Prepared Statements. The query I use looks like this:
SELECT * FROM butiken_orderregister
WHERE datum_skapad BETWEEN :datum_skapad_0 AND :datum_skapad_1
ORDER BY datum_skapad LIMIT 9999;
:datum_skapad_0 = 2014-10-20
:datum_skapad_1 = 2014-10-23
The column datum_skapad is in date format.
The query runs fine, but only returns posts where the column matches :datum_skapad_1. However, when I use MySQL Workbench I can get the results I want by using the query:
SELECT * FROM butiken_orderregister
WHERE datum_skapad BETWEEN "2014-10-20" AND "2014-10-23"
ORDER BY datum_skapad LIMIT 9999;
To me, these should be equivalent, but I evidently don't get the same results. I've tried using parenthesis like this:
SELECT * FROM butiken_orderregister
WHERE (datum_skapad BETWEEN :datum_skapad_0 AND :datum_skapad_1)
ORDER BY datum_skapad LIMIT 9999;
but it changes nothing.
Is there an obvious mistake I've made here or could the problem lie somewhere else?
Addendum:
This is the PHP that takes care of binding the parameters:
$stmt = $con->prepare($sql);
foreach ($flat_data as $field => $value) {
$stmt->bindParam(':' . $field, $value);
$out .= ':' . $field . ' = ' . $value . "\n";
}
if ($return_query) {
$out = $sql . "\n\n" . $out . "\n\n";
} else {
try {
$stmt->execute();
$out = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch(PDOException $error) {
$out = $error->getMessage();
}
}
$flat_data is an array with all values and the names I've used for them in the SQL. $con is a PDO object.
The following comment by Ryan Vincent solved my issue:
I suggest that you try using 'bindValue' rather than 'bindParam': questions/1179874/pdo-bindparam-versus-bindvalue – Ryan Vincent Oct 23 at 17:06
If you write your comment as an answer, Ryan, I can mark it as the accepted one. Until then I'll mark this one.
I really can't find that I'm changing the variables between my binding and my execution though, but since this solved my issue I suppose it is just one of those PHP quirks. It's a strange and wonderful language...
I agree with #exussum, check the variables. Also check the column types and date format used.
Maybe you could try explicitly converting the col and parameters to dates, are you using date or datetime?
SELECT * FROM butiken_orderregister
WHERE (
datum_skapad BETWEEN
DATE(:datum_skapad_0) AND DATE(:datum_skapad_1)
)
ORDER BY datum_skapad LIMIT 9999;
another way to cast dates:
SELECT * FROM butiken_orderregister
WHERE (
datum_skapad BETWEEN
CAST(:datum_skapad_0 AS DATE) AND CAST(:datum_skapad_1 AS DATE)
)
ORDER BY datum_skapad LIMIT 9999;
Maybe the problem is with how PHP handles the parameters, you should post the PHP code where you do this.
Might not resolve the issue but I would avoid using BETWEEN.
Instead use (for your example) Date >= '2014-10-20' and Date < '2014-10-24'
More info on why
I must modify a simple project to display some values in a different way.
I got a MySQL database, in which are stored reservations.
I want to get all data from a reservation, selecting the room and the period.
that's my query:
function getReservation($idroom,$date){
$db=JFactory::getDbo();
$query=$db->getQuery(true);
$datecheck=$date->format('%Y-%m-%d');
$query
->select($db->quoteName(array('idroom','status','idguests','nguests','value_paid','value_pending','value_full','valid_from','valid_to','today','extra_ids','nchilds')))
->from($db->quoteName('#__bookitbooking'))
->where($db->quoteName('idroom')."=".$idroom)
->and ( $db->quoteValue($datecheck) . "BETWEEN" . $db->quoteName('valid_from') . "AND" . $db->quoteName('valid_to'));
$db->setQuery($query);
$res = $db->loadObjectList();
return $res;
}
But the and clause seems to not have effect, in fact when I get the count of reservation stored from the query, I got all that matches with the $idroom value.
With that function I want to know if for a particular date exists a reservation, and if it exists I want to get all the parameters.
Where's my mistake?
Obviously I can obtain at maximum just one reservation object.
There is an error with your syntax. The "and" is assumed in the second where clause, where you check the dates, when using the core Joomla DBO class. Change the second where clause line to:
->where(INSERT DATE QUERY HERE);
* EDIT *
Another couple of things I noticed are the date formatting and your method for wrapping values in quotes for the table name and the $datecheck variable. Not to say the date formatting you're using shouldn't or won't work, but traditionally I've always formatted my dates using MySQL syntax. Try this, which accounts for the MySQL date formatting and using the DBO method intended for wrapping table names:
function getReservation($idroom,$date){
$db=JFactory::getDbo();
$query=$db->getQuery(true);
$datecheck= date('Y-m-d H:i:s');
$query
->select($db-quoteName(array('idroom','status','idguests','nguests','value_paid','value_pending','value_full','valid_from','valid_to','today','extra_ids','nchilds')))
->from($db->quote('#__bookitbooking'))
->where($db->quoteName('idroom')."=".$idroom)
->where( $db->quoteName($datecheck) . "BETWEEN" . $db->quoteName('valid_from') . "AND" . $db->quoteName('valid_to'));
$db->setQuery($query);
$res = $db->loadObjectList();
return $res;
}
I'm trying to pass a MySQL's NOW() function into PDO's assigned value through PHP and it's failing. I found that I must pass this directly into MySQL statement. But in my case, sometimes the datetime field can be empty.
Is it even possible to pass NOW() as PHP's assigned value?
Some code:
I'm building query dynamically and the datetime is dependent on some other variable's value.
if(isset($accountStatus)&&$accountStatus!=""){
$tmp[':account_status']=$accountStatus;
if($accountStatus==0){
$tmp[':vCodeExpire']="NOW() + INTERVAL 1 WEEK";
$tmp[':verified']=0;
}else{
$tmp[':verified']=1;
}
}
Building SQL query:
$sql="";
foreach($tmp as $k=>$v){
$sql.=str_replace(":","",$k)."=".$k.",";
}
$sql=substr($sql,0,strlen($sql)-1);
Then, I run PDO query:
$db=$pdo->prepare("UPDATE users SET $sql WHERE id=:id");
$db->execute($tmp);
I tried replacing double-quotes with single-quote around NOW() + INTERVAL 1 WEEK with no luck.
I also tried with single-quote around PDO query, but then $sql is passed directly, not using an assigned values.
is it possible?
No.
There are 2 solutions.
Calculate expiration date using PHP. Something like date('Y-m-d',strtotime('+1 week'))
Create a conditional part for the query
if(isset($accountStatus)&&$accountStatus!=""){
$tmp[':account_status']=$accountStatus;
if($accountStatus==0){
$accSql = "NOW() + INTERVAL 1 WEEK,";
$tmp[':verified']=0;
}else{
$accSql ='';
$tmp[':verified']=1;
}
$db=$pdo->prepare("UPDATE users SET $accSql $sql WHERE id=:id");
Use strtotime() instead of MySQL to get date values.