sql_exec (($sql = "insert into posts (user_id, body, picture_url, stamp) values ($userid, '". sql_escape ($body). "','$picture_url', minute(), hour())"));
sql_exec function
function sql_exec ($sql)
{
global $my_conn;
$result = mysqli_query($my_conn, $sql);
return $result;
}
My problem is with the minute() and hour() they are not working
Are you getting a column count error? You appear to be trying to insert 5 values in to 4 columns.
If you are looking to store a timestamp against each post you might find it easier, and a lot more practical for querying, to define the stamp column as
`stamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
This will get you both date and time which will allow you sort the posts properly and the column default will mean you don't even have to supply a value for it, mysql will do it for you.
As far as my knowledge goes, PHP doesn't have any minute() nor hour() functions. What I do know, however, is that you can get both of them using PHP's date() function.
To get the current hour and minutes, you can use:
$hour = date('H');
$minute = date('i');
Please let me know if this helped you :)
Related
I am providing 24 hours trial membership in my android application. I do not know more about PHP. I want check user registration time and want disable trial membership if 24 hours got passed. I have made little PHP file for that.
$sql = "SELECT id, email, registration_time FROM user WHERE trial = 1";
$result = $conn->query($sql);
if($result) {
while($row = $result->fetch_row()) {
$id = $row[0];
$email = $row[1];
$registrationTime = strtotime($row[2]);
$currentTime = strtotime("-1 day");
if($currentTime > $registrationTime) {
$update = "UPDATE user SET trial = 0 WHERE email = '$email'";
$conn->query($update);
$update = "UPDATE number_list SET disable = 1 WHERE user_id = $id";
$conn->query($update);
}
}
}
Its not providing any result even I have one user which time passed more than 48 hours.
How can I solve this issue?
try this and check
$currentTime=date('m-d-Y',strtotime($registrationTime . "-1 days"))
You should use a prepared statement to update the database for all the users with the same email (your first update query). Also see the documentation.
If someone registers with an e-mail address like test'; DROP ALL TABLES; --#gmail.com1 this code will dutifully remove your database. Never put user data into code directly like that.
Now let's look at the example code;
$sql = "SELECT id, email, registration_time FROM user WHERE trial = 1";
$result = $conn->query($sql);
if($result) {
while($row = $result->fetch_row()) {
You're saying there is no result at all. I assume that you've tested the output with a debug statement. E.g. putting echo 'users exist'; in between here. The first thing to do would be to check your user table if there are any rows. Does this SQL query produce results?
Assuming that it does, there doesn't appear to be anything wrong with the SQL statement. Assuming you have a table called user with four columns id, email, registration_time, and trial it should produce results.
Next, what you want to do is read the query function documentation. As you can see there, when a query fails, for whatever reason, it returns FALSE. Try writing an 'else' code block and logging the error that occurs. You can fetch it using the error function mysqli::error. Try appending this code;
} else {
echo "MySQL Error: " . $conn->error;
}
Where you can replace the echo with your error handling of choice.
It's probably a good idea to write a wrapper for mysqli if you're going to execute more than a few queries in your application. That way, you can write error handlers in your wrapper class for what your application should do if a query or database connection fails.
What could also be the case is that, while your initial query succeeds and fetches some rows, the time check fails. You may want to do some stricter date/time parsing than using strtotime and hoping for the best. Assuming you're using a TIMESTAMP column to store the data, you can use this:
function readDatabaseTimestampValue($value) {
$dateTime = date_create_from_format("Y-m-d H:i:s", $value);
$timestamp = $dateTime->getTimestamp();
return $timestamp;
}
Check the exact time data returned from your database. Dates and times are complicated, and if things are reinterpreted, say the day number in SQL may become the year in the PHP app, which can cause strange bugs. E.g. you can do this by doing say:
echo "24 hours ago: " . strtotime("-1 day") . ", user data: " . $row[2];
Next, you probably have some bugs in the logic. '24 hours ago' is better done by doing this, as using '-1 day' will cause weird issues when people mess with the calendar:
$timestamp = time() - 86400;
There's 86,400 seconds in a day (well, excluding DST and leap seconds, but you want 24 hours of subscription time, not 23 hours around the 21st of March).
Finally, there's problems if the same E-mail address is present more than once in the table. You will set 'trial' to 0 for one user, but may set the 'disable' flag for another if two users register within the same 24-hour period with the same e-mail. If the latter is guaranteed to be unique then this is no issue. Otherwise, you may want to update by id in both tables.
Next, we can look at some optimization. Right now, you fetch everything from the database. But you can do much better/faster by having an index on registrationTime, and using the database's sorting features. E.g. let's say we know the exact date/time of 24 hours ago as $yesterday in PHP we can write a query like:
SELECT id, email, registration_time FROM user WHERE trial = 1 AND registration_time > ?
Bind the $yesterday variable to the parameter. Now you no longer need the if() statement; the database does it for you. Also, as your database grows, you're not checking the old records one-by-one every time the code runs.
1Note, that may not be a legal e-mail address, but there's probably ways to do evil things even with a legal mail address.
This all worked before I added the section to update "last_update".
if((time() - $last_update) > 7200){
$sql = $dbh->prepare("UPDATE item_list SET quantity=:quantity, price=:price, last_update=:now WHERE item_name=:itemname");
$sql->bindParam(':quantity', $json->volume);
$sql->bindParam(':price', $json->lowest_price);
$sql->bindParam(':itemname', $row['Item_Name']);
$sql->bindParam(':now', "NOW()"); //This doesn't work
$sql->execute();
}
When this is called I want to make last_update the date and time now. In the database it is currently a DATETIME, and when I last_update I origianly set them to NOW();
Doing this I get the error Fatal error: Cannot pass parameter 2 by reference in.... Directory
I know it expects a variable, I'm not sure how to fix it though. I tried setting
$now = "NOW()";
$sql->bindParam(':now', $now);
No prevail. Any help?
Why you need to bind, just put NOW() directly
$sql = $dbh->prepare("UPDATE item_list SET quantity=:quantity, price=:price, last_update=now() WHERE item_name=:itemname");
If your last_update column is looking for a UNIX timestamp, then do :
$now = time();
$sql->bindParam(':now', $now);
If it's after a different time format, use date(), and the relevant formatting it has to set the date and time
You can keep your bind query as it is & remove the last_update column from the query.
Since you are updating other things in the record via another query, then you can set the default value of the field last_update to CURRENT_TIMESTAMP & set it's attribute as ON UPDATE CURRENT_TIMESTAMP. That will ensure it automatically updates itself with the current time now() whenever that record is updated.
It wouldn't be the best thing to remove bind() as you rightly said to prevent SQL injection attempts.
I am working on a project in which the dates in the sql table needs to be checked with current date. If the ticket goes past the current date, then the status of ticket go from Active to Expired.
I am not good at php. This is what I came up with. I wrote this function at top of the page so that each time the page loads, it checks for the date and compares. date format is yyyy-mm-dd.
What am I doing wrong. Can anyone please help me out?
$result= "SELECT date, status FROM TABLE1";
while($row = sqlsrv_fetch_array($result)){
if(strtotime($row['date']) > strtotime(date('Y-m-d'))){
$updatequery = " UPDATE TABLE1 SET $row[status] = 'Expired' ";
}}
I would advise using the PHP DateTime class it has the date diff function so you could implement like this
$today = new DateTime('today');
$expires = new DateTime($datefromdb);
$diff = $today->diff($expires);
if($diff < 1)
{
$updatequery = " UPDATE TABLE1 SET $row[status] = 'Expired' ";
}
You can use
$result= "SELECT UNIX_TIMESTAMP(date) AS unixdate, status FROM TABLE1";
and then compare
if ($row['unixdate']) > strtotime(date('Y-m-d')))
Your sql database may be on a server whose time is different from the time on the machine where you are running the code, so I would recommend doing the check and update all on the sql server side.
(Disclaimer: I use mysql, so that's how I've written my answer. I assume you can translate to whatever sql database you use)
I would recommend using MySql's date functions, which you can see here.
UPDATE TABLE1 SET status='Expired' WHERE DATEDIFF(CURDATE(), date) < 0
Below code working for me, just a single line of update query will updated less than of current date
UPDATE TABLE_NAME SET status='expired' WHERE DATEDIFF(date, CURDATE()) < 0
Thank.
In my MySQL database, I have this Time data type as one of my values: 06:00:00. I have the following query that checks the time as one of the conditions that has to be satisfied
$time = "06:00:00";
$getdetails=SELECT First_Name, Last_Name, EMAIL
FROM parents
WHERE Email_Receive_Time = $time;
$results=mysql_query($getdetails);
However I do not get any results. On further research I have seen that it is because I am comparing a STRING type value ($time) to a TIME type value (value in my database). Is there a way i can compare the two without changing my database structure to a varchar? All help will be appreciated.
MySQL is perfectly capable of comparing a string to a TIME value. You just need to have the proper query syntax. In your case, you need to quote the comparison value:
$time = "06:00:00";
$getdetails = "SELECT First_Name, Last_Name, EMAIL
FROM parents
WHERE Email_Receive_Time = '$time'";
$results=mysql_query($getdetails);
And if it is user-supplied, well you should escape it.
You are wrong.
Your mistake is much simpler, it has nothing to do with data formats, but with query format.
Ask yourself what does mean 06:00:00 in terms of SQL syntax.
Btw, running query this way will help you A LOT:
$results=mysql_query($getdetails) or trigger_error(mysql_error()." in ".$getdetails);
always run all your queries this way and get in touch with every error occurred
This will work when comparing against TIME type of field:
To compare against DATETIME or TIMESTAMP, I'd suggest running the $time variable through strotime() first.
$time = "06:00:00";
$getdetails = "SELECT First_Name,
Last_Name,
EMAIL
FROM parents
WHERE Email_Receive_Time = '$time'";
$results = mysql_query($getdetails);
Try using STR_TO_DATE function, it should work for you.
Thanks
Ravi Mudaliar
How can i only save one profilevisit per hour? So if you visited at 10:10 then it wont save when you view the profile at 12:10 ?
My code right now that saves evrytime you visit:
$date = time();
$BuID= mysql_real_escape_string($v["id"]);
$uID= mysql_real_escape_string($showU["id"]);
mysql_query("INSERT INTO users_profilevisits (uID, BuID, date) VALUES ('$uID', '$BuID', '$date')") or
die(mysql_error());
update
function save(){
mysql_query("INSERT INTO users_profilevisits (uID, BuID, date) VALUES ('$uID', '$BuID', '$date')") or
die(mysql_error());
$_SESSION['saved']=time();
}
if(isset($_SESSION['saved'])){
$time = time();
if($time-$_SESSION['saved'] > 3600){
save();
}
}else{
save();
}
select the timestamp and conditionally execute the save based on timestamp. alternatively, set a session variable and conditionally execute based on that value.
if(isset($_SESSION['saved']){
$time = time();
if($time-$_SESSION['saved'] > 3600){
save($uid,$buid);
}else{
save($uid,$buid);
function save($uid,$buid){
//save stuff here
$_SESSION['saved']=time();
}
If you always set the minutes/seconds of the provided time to 0, you can create a key over date and BuID, so it wont be able to insert more than 1 row within a hour(without any checks, session-vars or subqueries).
If you need the minutes/seconds for further operations, create a new column for implementing the described method.
assuming the following table:
date INT(11)
uID INT(11)
BuID INT(11)
date2 TIMESTAMP
UNIQUE KEY `BuID` (`BuID`,`date2`)
the following query should match your needs:
INSERT INTO users_profilevisits (uID, BuID, date, date2)
VALUES ('$uID', '$BuID', '$date',FROM_UNIXTIME(UNIX_TIMESTAMP(),'%Y%m%d%H0000'))
As you have a unique key over BuID and date2(date2 will have a value of the current time with minutes and seconds set to 0), it wont be able to insert duplicate rows with the same date2+BuID
But you have to remove the or die() , because if you try to insert a duplicate key, this will result in an error.
Using this method you dont need a programming logic, the table-structure itsselve will do the work for you.
Just give the MySQL table an additional field and set it to unique. When you save the visit, save a string like "visitoruserid+year+month+day+hour" to that field. That way MySQL takes care of only allowing one per hour per user without the need for additional PHP code, sessions and time checks.
Edit:
Add. benefit: If you later choose to loose the "once per hour" condition or change it to once per day or add more conditions, you only have to change the string saved to that field without any more changes to your code.