PHP MYSQL PREPARE synstax issue (unexpected T_STRING) - php
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.
Related
mysqli_real_escape_string doesn't insert into db
I propose the following question ... I have to make sure that the following query also accept values with the quotes inside .. I tried using mysqli_real_escape_string but it did not work .. I am attaching my attempts .. 1° Put the function during the post $idCantiere = $_POST["idCantiere"]; $nomeCantiere = mysqli_real_escape_string($_POST["nomeCantiere"]); $sql = "INSERT INTO Cantiere( idCantiere, nomeCantiere) VALUES( '$idCantiere', '$nomeCantiere')"; if (mysqli_query($mysqli, $sql)) { echo "<script type='text/javascript'>alert('Cantiere Inserto'); </script>"; } else { echo "Error: " . $sql . "" . mysqli_error($mysqli); } 2° Put the function during the query $idCantiere = $_POST["idCantiere"]; $nomeCantiere = $_POST["nomeCantiere"]; $sql = "INSERT INTO Cantiere( idCantiere, nomeCantiere) VALUES( '$idCantiere', mysqli_real_escape_string('$nomeCantiere'))"; if (mysqli_query($mysqli, $sql)) { echo "<script type='text/javascript'>alert('Cantiere Inserto'); </script>"; } else { echo "Error: " . $sql . "" . mysqli_error($mysqli); } How can I solve the problem?
Drop the mysqli_real_escape_string() and just use prepared statements which is simple and prevents sql injections. <?php $idCantiere = isset($_POST['idCantiere']) ? $_POST['idCantiere'] : null; $nomeCantiere = isset($_POST['nomeCantiere']) ? $_POST['nomeCantiere'] : null; $sql = $mysqli->prepare("INSERT INTO Cantiere (idCantiere,nomeCantiere) VALUES(?.?)"); $sql->bind_param("is",$idCantiere,$nomeCantiere); if($sql->execute()){ //success message }else{ //return error } ?> A prepared statement is a feature used to execute the same (or similar) SQL statements repeatedly with high efficiency. Prepared statements basically work like this: Prepare: An SQL statement template is created and sent to the database. Certain values are left unspecified, called parameters (labeled "?"). Example: INSERT INTO MyGuests VALUES(?, ?, ?) The database parses, compiles, and performs query optimization on the SQL statement template, and stores the result without executing it Execute: At a later time, the application binds the values to the parameters, and the database executes the statement. The application may execute the statement as many times as it wants with different values Compared to executing SQL statements directly, prepared statements have three main advantages: Prepared statements reduce parsing time as the preparation on the query is done only once (although the statement is executed multiple times) Bound parameters minimize bandwidth to the server as you need send only the parameters each time, and not the whole query Prepared statements are very useful against SQL injections, because parameter values, which are transmitted later using a different protocol, need not be correctly escaped. If the original statement template is not derived from external input, SQL injection cannot occur.
You are wrong to pass parameters to the mysqli_real_escape_string () function before inserting the post you must put the connection string with which you access the DB $connection=mysqli_connect("localhost","USER","PASSWORD","DB"); $nomeCantiere= mysqli_real_escape_string($connection, $_POST['nomeCantiere']); your second attempt is wrong reuses my line of code in the first .. during the post
You have to pass the connection variable as first parameter Eg: $con=mysqli_connect("localhost","my_user","my_password","my_db"); $age = mysqli_real_escape_string($con, $_POST['age']); Checkout documentation for more detail. http://php.net/manual/en/mysqli.real-escape-string.php
You can try to replace quote with php $nomeCantiere = $_POST["nomeCantiere"]; str_replace("'", "''", $nomeCantiere ); if you insert 2 quotes ( '' ) instead of one mysql will put that value in the table with only 1 quote
You are missing one parameter in function mysqli_real_escape_string($con,$sql);
In Cakephp, how to prevent sql injection if I use direct mysql queires rather than using models?
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.
How to use PHP variables with SELECT and INSERT INTO SQL Statements
Below is the code i'm trying to get to work: $y= "SELECT ('PRV_IDX') FROM LLS_PRIVILEGES WHERE `PRV_NAME` = 'Reader';"; mysql_query($y); $x= "SELECT ('USER_IDX') FROM LLS_USERS WHERE `USR_LOGIN` = '".$_SESSION['tool_user']."';"; mysql_query($x); $w= "INSERT INTO LLS_USERS_PRIVILEGES (USP_USR_IDX,USP_PRV_IDX) VALUES ($x,$y); "; mysql_query($w); I want to insert these values from the select statements into the final table. However, I am not sure if my Syntax is correct and I have been unable to find a solution online. I wasn't sure if you had to do the mysql_query each time for the select statement to actually take hold in and place it in the $variable. Sorry, I'm new to SQL, but thank you for the help!
mysql_* functions are deprecated. Use PDO instead : $y=$dbh->query("SELECT ('PRV_IDX') FROM LLS_PRIVILEGES WHERE `PRV_NAME` = 'Reader'"); $x=$dbh->prepare("SELECT ('USER_IDX') FROM LLS_USERS WHERE `USR_LOGIN` = ?"); $x->execute(array($_SESSION['tool_user'])); $w=$dbh->prepare("INSERT INTO LLS_USERS_PRIVILEGES (USP_USR_IDX,USP_PRV_IDX) VALUES (?,?)"); $y="SELECT ('PRV_IDX') FROM LLS_PRIVILEGES WHERE `PRV_NAME` = 'Reader'"; $x="SELECT ('USER_IDX') FROM LLS_USERS WHERE `USR_LOGIN` = '".$_SESSION['tool_user']."'"); $w->execute(array($x,$y)); More About PDO : http://www.php.net/manual/en/book.pdo.php
MySQL INSERT INTO doesn't do anything - not even error
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
How to optimize a query with MySQL multi-query?
I need to optimize a script for high performance so the question is how can I add MySQL multi-query to this code? foreach($multiContent as $htmlContent) { $email = urldecode($email['1']); $user = $user['1']; //store in db $db->query("UPDATE eba_users SET mail = '$email' WHERE username = '$user'"); //echo "email is $email and user is $user\n"; } //close if ($array_counter % 200 unset($array_counter); unset($data); }
If you're using mysqli or PDO already, you should be using prepared statements for your queries since they are supported. This will also have a slight increase in performance since the entire query doesn't need to be sent again to the DB server. However the biggest advantage is the increased security that prepared statements provide. Other than this, try adding an index on username to speed this query up if you haven't already. Edit: If you want to do it all in one query, as you seem to suggest, you could also use ON DUPLICATE KEY UPDATE as mentioned as an answer to this question: INSERT INTO eba_users (`username`, `mail`) VALUES ('username1','$email1'), ('username2','$email2'), ('username3','$email3'), ('username4','$email4'), .... ('usernameN','$emailN'), ON DUPLICATE KEY UPDATE `mail`=VALUES(mail); However this may not be as fast as using prepared statements with a regular UPDATE. Edit2: As requested, here is probably a close approximation of what you should be doing to bind the parameters in mysqli: if ($stmt = $mysqli->prepare("UPDATE eba_users SET mail= ? WHERE username= ?")) { /* loop through array of users */ foreach ($array as $username => $newemail) { /* bind parameters for markers */ $stmt->bind_param("ss", $newemail, $username); /* execute query */ $stmt->execute(); } } Of course this doesn't provide any sort of error messages in case this fails. For that, you can look into mysqli::error