I have this query:
mysql_query("INSERT INTO `63_Activity` (`username`, `time`) VALUES (`$usernann2`, `$date`)");
However, it doesn't do anything. Even when I tried correcting the variables to
". $variable ."
I checked the variables.
I copied the little line of code from somewhere it works.
The database and tables are existing.
I just thought I had things under control, then that happened -.-
Thank you in advance.
PS: I tried adding or die() - but no error. Nothing.
Values need to be in single quotes ('), not backticks (`)
mysql_query("INSERT INTO `63_Activity` (`username`, `time`) VALUES ('$usernann2', '$date')");
You should also make sure you're sanitizing your inputs, as well as preferably not using the mysql_ functions in place of mysqli_
You would be better off using Paramaterized queries as in the following example:
<?php
try {
$usernann2 = "whateverUsernameFits";
$date = new DateTime('2000-01-01');
$stmt = $this->db->prepare ( "INSERT INTO 63_Activity (username, time) VALUES (:usernann2, :date)");
$stmt->bindParam ( ':usernann2', $usernann2 );
$stmt->bindParam ( ':date', $date );
$stmt->execute ();
}catch ( PDOException $e )
{
throw new Exception ( $this->db->errorInfo () . 'Problem inserting object ' );
} catch ( Exception $e ) {
throw new \Exception ( 'Problem inserting object ' );
}
?>
Bound parameters are a staple in preventing SQL Injection attacks. The exceptions thrown would give you a clue as to what might be the problem in your query if there is one. I normally check the query first to make sure it's working with real values. From there it is a process of elimination.
PS. https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet for more information on SQL Injection. You should also be able to find some excellent information and questions here on Stackoverflow regarding SQL Injection.
try to put the query in a variable and echo it, and see if anything wrong, try to run it on php my admin also
Related
I have to deal with large mysql DB. Sql queries with lot of calculations (in select clause) and several kind of conditions in where clauses. So, I decided to use row/direct sql queries to deal with DB by using $db = ConnectionManager::getDataSource('default');
If I use this, how I prevent sql injection in mysql query? "mysql_real_escape_string" no longer exists. Is there any way to use PDO within CakePHP?
You can use this in your controller (or component)
// Initiate PDO connection
$this->_pdocon = $this->WhateverYourModel->getDataSource()->getConnection();
try {
// Select Query
$company = "What";
$stmt = $this->_pdocon->prepare('SELECT * FROM `agents` WHERE `company` LIKE :company LIMIT 2');
$stmt->bindValue(':company', $company, PDO::PARAM_STR);
// Start transaction
$this->_pdocon->begin();
// Loop through the events
if( $stm->execute() ) {
while ($row = $stmt->fetchAll(PDO::FETCH_ASSOC)) {
$stmt2 = $this->_pdocon->prepare("INSERT INTO `company`
(`id`, `name`, `identityno`, `modified`, `created`)
VALUES
(NULL, :name, :identityno, NOW(), NOW())");
$stmt2->bindValue(':name', $row['name'], PDO::PARAM_STR);
$stmt2->bindValue(':identityno', $row['id'], PDO::PARAM_INT);
$stmt2->execute();
}
}
// Commit transaction
$this->_pdocon->commit();
// Get last insert Id
$row_id = $this->_pdocon->lastInsertId();
var_dump($row_id);
} catch (PDOException $e) {
// Rollback transaction
$this->_pdocon->rollback();
echo "! PDO Error : " . $e->getMessage() . "<br/>";
}
This is what I ended-up. Using PDO has been solved thousands of issues. Now the system is fast and no memory exhaust error. And I can not putting all issues, errors what I got, in my question. It's good to giving direct answer rather trying to changing questions in here!
A large part of the point of cakePhp is not to do this. Therefore I would recommend not doing this.
Cakephp has a its own implementation for accessing a DB and you should use it if at all possible. Is there a particular reason you want to go around it?
if you realy want to, you can still use mysqli but I cant recommend it.
it says success but it doesnt really insert the values to Database. idk whats going on.
if($_POST['submit']){
$registerQuery = 'INSERT INTO `user`(firstname`, `lastname`, `email_address`, `password`, `mobile_number`,`location`) VALUES (
"'.$firstname.'",
"'.md5($password).'",
"'.$lastname.'",
"'.$emailaddress.'",
"'.$password.'",
"'.$mobile_number.'",
"'.$location.'");';
echo 'Success';
}
$qry = mysql_query($registerQuery);
Your echo statement is not wrapped in a conditional, and runs before the query is executed. As a result "Success" will be echoed no matter what.
Instead, you want to check the response of mysql_query to see whether it executed successfully, then take action (like echoing 'Success') based on that result.
mysql_query() always returns false on error, so you can check $qry to see if it is false:
if ($qry === false) {
echo "Query failed";
// take action as needed
}
else {
echo "Success";
// take action as needed
}
To see the exact error that caused the failure, use mysql_error(). You can execute this in the 'failed' section of code, above.
In this case, the failure was caused by two errors in your query:
Syntax
There is a missing backtick before 'firstname':
'INSERT INTO `user`(firstname`,
should be
'INSERT INTO `user`(`firstname`,
Column/Value Count Mismatch
Your query specifies that six columns will be filled:
(`firstname`, `lastname`, `email_address`, `password`, `mobile_number`,`location`)
but seven values were provided:
"'.$firstname.'",
"'.md5($password).'",
"'.$lastname.'",
"'.$emailaddress.'",
"'.$password.'",
"'.$mobile_number.'",
"'.$location.'");'
Deprecation Warning
Note: The mysql_* functions are deprecated; they have been replaced by PDO. Consider for safety and stability, consider modifying your code to use PDO.
It doesn't work because there are 7 values and 6 columns and you miss a backtick around the firstname column. The number of values and columns must be the same. You always echo Success because you don't check if $qry is false (it returns false on error). Finally, you should not use mysql_* functions because they are officially deprecated as of PHP 5.5. Use either PDO or MySQLi.
you are also missing a back-tick surrounding firstname...
should be:
$registerQuery = 'INSERT INTO `user`(`firstname`, `lastname`
Here is a part of my insert code that troubles me:
$recepient="test#email.com";
$text="Please track: http://wwwapps.ups.com/WebTracking/processInputRequest?HTMLVersion=5.0&loc=en_US&Requester=UPSHome&tracknum=123456789&AgreeToTermsAndConditions=yes&ignore=&track.x=24&track.y=9";
$date="2013-05-03 08:12:20";
$through="mail";
$status=1;
$q = "INSERT INTO `messages` (`recepient`,`text`,`date`,`through`,`status`) VALUES('".mysql_real_escape_string($to)."','".mysql_real_escape_string($text)."','".date("Y-m-d H:i:s")."','".mysql_real_escape_string($rowuser['through'])."','".intval($status)."')";
try {$db->query($q);} catch(PDOException $ex) {echp" Error: ".$ex.);}
If I remove the link from the $text variable I can see the data added to the database. But in the way I need it to add with the link - the script stops not reporting any errors.
use PDO's powerful prepared statements:
$q = "INSERT INTO messages (recepient,text,date,through,status) ";
$q .= "VALUES (:to,:text,:date,:through,:status)";
$dbinsert = $db->prepare($q);
$dbinsert->execute(array(
':to' => $recipient,
':text' => $text,
':date' => $date,
':through' => $through,
':status' => $status));
This should do it.
Let PDO take care of escaping.
It would appear that you're mixing database libraries, or have wrapped things yourself.
If you're using something like mysqli or PDO for the ->query() call, then mysql_real_escape_string() will NOT work. m_r_e_s() requires an active connection to the DB to operate. Connections established in mysql, mysqli, and PDO are NOT shareable between the libraries.
That means your m_r_e_s() calls will returning a boolean FALSE for failure, and your query will actually look like:
$q = "INSERT .... VAALUES ('', '', '', etc...)";
What's the size of the text column in the database? It's mostly not the reason but I've noticed that your $text is 190 char long.
The problem is with the "?" sign in the $text variable. It is being treated as a placeholder when it is put into the query, and the $db->query expects an array of variables.
The solution is to use a placeholder instead of a $text variable and submit $text variable as params:
$ar[0]=$text;
$q = "INSERT INTO `messages` (`recepient`,`text`,`date`,`through`,`status`)";
$q.= " VALUES('".$to."',?,'".date("Y-m-d H:i:s")."','".$through."',".$status.")";
$db->query($q,$ar);
I'm new to sql and PHP. So far have been able to figure things out but the PREPARE statement is giving me syntax issues (maybe because I'm trying to do several things in one step). If someone could let me know where my syntax is messing up that would be great.
In addition the code I'm writing is trying to update save files on a server and while I believe doing it with a prepare statement is the correct way I would be happy to hear if it is not. Note I plan to change INSERT INTO -> a conditional insert or update.
The error I get is unexpected T_STRING. I've marked the line of the error in the code.
$sql='PREPARE statement FROM "INSERT INTO buildings VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) WHERE id="$id" AND ind="$i""';
$result=mysql_query($sql);
for($i=0;$i<1600;$i+=1){
if(isset($_POST['ind'.$i])){
$bind=$_POST['bind'.$i];
$time=$_POST['time'.$i];
$level=$_POST['level'.$i];
$p1ind=$_POST['p1ind'.$i];
$p1state=$_POST['p1state'.$i];
$p1time=$_POST['p1time'.$i];
$p2ind=$_POST['p2ind'.$i];
$p2state=$_POST['p2state'.$i];
$p2time=$_POST['p2time'.$i];
$p3ind=$_POST['p3ind'.$i];
$p3state=$_POST['p3state'.$i];
$p3time=$_POST['p3time'.$i];
$p4ind=$_POST['p4ind'.$i];
$p4state=$_POST['p4state'.$i];
$p4time=$_POST['p4time'.$i];
$p5ind=$_POST['p5ind'.$i];
$p5state=$_POST['p5state'.$i];
$p5time=$_POST['p5time'.$i];
$sql = 'SET #bind="$bind",'. //<-line of error
'#time="$time",'.
'#level="$level",'.
'#p1ind="$p1ind",'.
'#p1state="$p1state",'.
'#p1time="$p1time",'.
'#p2ind="$p2ind",'.
'#p2state="$p2state",'.
'#p2time="$p2time",'.
'#p3ind="$p3ind",'.
'#p3state="$p3state",'.
'#p3time="$p3time",'.
'#p4ind="$p4ind",'.
'#p4state="$p4state",'.
'#p4time="$p4time",'.
'#p5ind="$p5ind",'.
'#p5state="$p5state",'.
'#p5time="$p5time",'.
'#id="$id",'.
'#ind="$i"';
$result=mysql_query($sql);
$sql='EXECUTE statement USING #id,#time,#level,#p1ind,#p1state,#p1time,#p2ind,#p2state,#p2time,#p3ind,#p3state,#p3time,#p4ind,#p4state,#p4time,
#p5ind,#p5state,#p5time,#ind,#bind';
$result=mysql_query($sql);
if(!$result){
die("saveArry[0]=".mysql_error().";");
}else{
die("saveArry[0]='saved';");
}
}
}
$sql='DEALLOCA PREPARE statement';
$result=mysql_query($sql);
Update I am unable to install PDO on my hosts servers and therefore PDO is unfortunately an unacceptable solution. My answer (now with no errors!):
if(isset($_POST['ind'])){
$ind=sanitizeString($_POST['ind']);
$bind=sanitizeString($_POST['bind']);
$time=sanitizeString($_POST['time']);
$level=sanitizeString($_POST['level']);
$p1ind=sanitizeString($_POST['p1ind']);
$p1state=sanitizeString($_POST['p1state']);
$p1time=sanitizeString($_POST['p1time']);
$p2ind=sanitizeString($_POST['p2ind']);
$p2state=sanitizeString($_POST['p2state']);
$p2time=sanitizeString($_POST['p2time']);
$p3ind=sanitizeString($_POST['p3ind']);
$p3state=sanitizeString($_POST['p3state']);
$p3time=sanitizeString($_POST['p3time']);
$p4ind=sanitizeString($_POST['p4ind']);
$p4state=sanitizeString($_POST['p4state']);
$p4time=sanitizeString($_POST['p4time']);
$p5ind=sanitizeString($_POST['p5ind']);
$p5state=sanitizeString($_POST['p5state']);
$p5time=sanitizeString($_POST['p5time']);
$rot=sanitizeString($_POST['rot']);
$sql="INSERT INTO buildings (id,ind,bind,time,level,p1ind,p1state,p1time,p2ind,p2state,p2time,p3ind,p3state,p3time,p4ind,p4state,p4time,p5ind,
p5state,p5time,rot) VALUES ('$id','$ind','$bind','$time','$level','$p1ind','$p1state','$p1time','$p2ind','$p2state','$p2time','$p3ind','$p3state',
'$p3time','$p4ind','$p4state','$p4time','$p5ind','$p5state','$p5time','$rot') ON DUPLICATE KEY UPDATE bind='$bind',time='$time',level='$level',
p1ind='$p1ind',p1state='$p1state',p1time='$p1time',p2ind='$p2ind',p2state='$p2state',p2time='$p2time',p3ind='$p3ind',p3state='$p3state',
p3time='$p3time',p4ind='$p4ind',p4state='$p4state',p4time='$p4time',p5ind='$p5ind',p5state='$p5state',p5time='$p5time',rot='$rot'";
$result=mysql_query($sql);
if(!$result){
die("saveArry[0]=".mysql_error().";");
}else{
die("saveArry[0]=saved;");
}
}
The single and double quotes are interchanged in that line, should be,
$sql = "SET #bind='$bind',
#time='$time',
#level='$level',
#p1ind='$p1ind',
#p1state='$p1state',
#p1time='$p1time',
#p2ind='$p2ind',
#p2state='$p2state',
#p2time='$p2time',
#p3ind='$p3ind',
#p3state='$p3state',
#p3time='$p3time',
#p4ind='$p4ind',
#p4state='$p4state',
#p4time='$p4time',
#p5ind='$p5ind',
#p5state='$p5state',
#p5time='$p5time',
#id='$id',
#ind='$i'";
I strongly recommend using PDO instead of deprecated mysql_* functions. It is doing the hard work with prepared statements for you transparently.
As EthanB pointed out in comment, your code is vulnerable to SQL injection as you are inserting the values directly from user input ($_POST variable).
With PDO your code would look something like this (simplified):
$statement = $pdo->prepare("INSERT INTO buildings VALUES(:ind, :bind, :time, :level, ...) WHERE id = :id AND ind = :ind");
for( ... ) {
$statement->execute(array(
":ind" => $_POST["ind" . $i],
":bind" => $_POST["bind" . $i], ...
));
}
The PDO will send the PREPARE and EXECUTE queries for you and escape all parameters to prevent SQL injection.
Perplexed here.... This code:
$qry = sprintf("INSERT INTO news_sites_homepage_grab
VALUES ('', %d, '%s', NOW(), NOW())",
$site_id, mysql_real_escape_string($html));
...is executed in a loop where $html changes every time. This code executes once but the next time, the script simply dies. No warnings/errors, nothing. $html is a string representing a webpage so it could be very long. I have upped the memory limit in PHP to 32M and set max_allowed_packet in MySQL to 16M but nothing.
Anyone have any ideas? Thanks!
UPDATE: Here is the function that is called within a loop.
function save_html($site_id, $html) {
global $db;
try {
$qry = sprintf("INSERT INTO site_grab VALUES ('', %d, '%s', NOW(), NOW())",
$site_id,
mysql_real_escape_string($html));
$db->insert($qry);
}
catch(Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
return;
}
My recommendation would be to forgo troubleshooting this issue and switch to PDO. It supports prepared statements, which aren't vulnerable to SQL injection when you use parameters and are much more performant for repeated queries.
Here's a simple refactoring of your function, which assumes $db holds a PDO instance:
function save_html($site_id, $html) {
global $db;
static $insert = Null;
if (isnull($insert)) {
/* explicitly name the columns, in case you later add more to the table
or change their order. I'm also guessing `id` is auto-incrementing,
so I'm leaving it out.
*/
$insert = $db->prepare("INSERT INTO site_grab (sid, site_text, date_added, date_modified) VALUES (?, ?, NOW(), NOW())");
}
try {
$insert->execute(array($site_id, $html));
} catch(Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
return;
}
If date_added has type TIMESTAMP, you can set its default value to CURRENT_TIMESTAMP and leave it out of the insert. Alternatively, add an ON UPDATE CURRENT_TIMESTAMP property to the date_modified column, which means you don't need to explicitly set the field when you update a row. If inserting is going to be more common than updating, do the former; otherwise, do the latter.
You could also store prepared statements in an object so they're accessible from multiple functions and replace the global $db with some sort of service locator (the simplest way is to use a static function or property of some class) or use dependency injection (read "Inversion of Control Containers and the Dependency Injection pattern").
I preffer using PDO and prepared statements but to (try to) answer your question try adding $db as the link identifier to mysql_real_escape_string() function.
Does that help? If not, try echoing the output of the mysql_error() function.
Sorry for the lack of formating, I'm mobile ATM.