Concatenate variables inside of a query - php

What would be the proper way to concatenate this query?
$query2= "SELECT * FROM relationships WHERE user_1= '.$_SESSION['user_id'].'
AND user_2= '.$user_id.' ";
I keep getting this error:
Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE, expecting T_STRING or T_VARIABLE or T_NUM_STRING in C:\xampp\htdocs\beta\profile.php on line 32

What would be the proper way to concatenate this query?
To let your SQL library/client/server do it for you (while escaping special characters for free). Trying to build code by mashing strings together is relatively error prone and involves fiddly combinations of various quote characters that can become hard to maintain.
Use prepared statements and bound arguments instead.

You have an incorrect nesting of single and double quotes.
$query2= "SELECT * FROM relationships WHERE user_1= '" . $_SESSION['user_id'] . "' AND user_2= '" . $user_id . "'";

Either:
$query2 = "SELECT * FROM relationships WHERE user_1='" . $_SESSION['user_id'] . "'AND user_2='" . $user_id . "'";
Or:
$query2 = "SELECT * FROM relationships WHERE user_1='${_SESSION['user_id']}' AND user_2='$user_id'";
fixes your syntax error. However, forming queries through concatenation is a bad idea. At the very least, you should mysql_realescapestring all the arguments, if not move to using PDO.

Related

PHP / SQL error, unexpected variable name

I get the following error:
Parse error: syntax error, unexpected '$studentNo' (T_VARIABLE)
Can somebody tell me what's wrong here? I've read about this kind of error and base on it, it usually happens when there's a missing bracket, parenthesis or semi-colon but in my case I don't think I missed any..Does it have something to do with the variable itself, perhaps?
if(isset($_POST['next'])){
$studentNo = $_POST['sn'];
if(!empty($_POST['sn'])){
$check = ("SELECT * FROM student_info WHERE SN="$studentNo"");
$check1 = mysqli_query($con, $check);
if(mysql_num_rows($check1) > 0){
$errors['sn'] = "Student number already exists";
}
}
}
Your problem is that you have to concatenate the string.
But, before doing this, make sure that your SQL library protects against SQL injections.
To do this, just do:
$check = "SELECT * FROM student_info WHERE SN=" . $studentNo . ";";
// Also, remember to add a semicolon at the end of your SQL query :)
The best way to do this is to use a prepared statement. This site explains it very well.

What's wrong with the PHP syntax here?

I'm having hard time to figure out whats wrong in this code. I tried many variations but still getting error in this line:
$query= "INSERT INTO publish (name, email, title, content)" .
"VALUES ('$row['Name']','$row['Email']',$row['title'],$row['content'])";
What could be wrong?
here's the rest of the code:
<?php
// connect to the database
include('config2.php');
// check if the 'id' variable is set in URL, and check that it is valid
if (isset($_GET['id']) && is_numeric($_GET['id']))
{
// get id value
$id = $_GET['id'];
$dbc = mysqli_connect('localhost', 'x', 'x', 'x')
or die('Error');
$name = $row['Name'];
$email = $row['Email'];
$title = $row['title'];
$content = $row['content'];
$result = mysql_query("select *stories WHERE id=$id")
or die(mysql_error());
$row = mysql_fetch_array( $result );
$query= "INSERT INTO publish (name, email, title, content)" .
"VALUES ('$row['Name']','$row['Email']',$row['title'],$row['content'])";
or die('Error querying database.');
mysqli_close($dbc);
}
?>
Error message: "parse error expecting identifier (t_string) ' or variable (t_variable) ' or number (t_num_string) '"
You probably want to use complex string syntax to properly interpolate those variables. For example:
$query= "INSERT INTO publish (name, email, title, content)" .
"VALUES ('{$row['Name']}','{$row['Email']}',{$row['title']},{$row['content']})";
Though that will only fix one of the issues with the code.
Do note there are plenty of other ways to resolve this one too, such as concatenation instead of interpolation, or string replacements, etc etc.
It might also be worth reading the documentation on strings at some point.
You forgot the "." between your variables and your strings. Like so:
$query= "INSERT INTO publish (name, email, title, content)" .
"VALUES (".$row['Name'].','.$row['Email'].','.$row['title'].','.$row['content'].")";
However, it looks like you may have some additional issues going on there with the actual SQL query.
The best practice in PHP is to use single quote ' for strings. Cos PHP looks for variables inside double quoted strings and keeps on sniffing whether there is a variable (or multiple variables) inside the string.
So for example: "A very very long string... $var1 .. long string .. $var2 string" this will run slower compared to 'A very very long string... ' . $var1 . ' .. long string .. ' . $var2 . ' string'; cos when PHP sees single quote it won't sniff for variables inside it thus it's faster.
From my experience, in my early age I worked on a very large php script and used double quotes everywhere. After the above explanation from an expert I converted the whole script to single quote and the performance was much better.
So for your situation I'd suggest and request to use single quotes and it'll avoid confusions as well. Also using mysql_real_escape_string() is a good practice to avoid SQL Injection.
$query= 'INSERT INTO publish (name, email, title, content)
VALUES (
\'' . mysql_real_escape_string ($row['Name']) . '\',
\'' . mysql_real_escape_string ($row['Email']) . '\',
\'' . mysql_real_escape_string ($row['title']) . '\',
\'' . mysql_real_escape_string ($row['content']) . '\')';

PHP SQL Statement not accepting Variable

I'm trying to use the following code however it is giving me errors.
Code:
$id = $_GET['id'];
$action = '['command'=>'get','target'=>'location']';
$query = "UPDATE ZeusUsers SET action = '$action' WHERE notification_id = '$id'";
$result = mysqli_query($link,$query) or exit("Error in query: $query. " . mysqli_error());
Error:
Parse error: syntax error, unexpected 'command'
If I change the $action to a standard word the statement works fine, it just seems to have issues with the single quotes and square brackets.
I've also tried using \ in front of the single quotes and it still fails.
Any ideas?
let php build the json string for you
$action = json_encode(array('command'=>'get','target'=>'location'));
You are starting and stoping a string literal with the single quotes so php is interpreting command as php code but it doesn't know what that keyword is.

PDO/prep statement/whitelisting/set charset, is that safe enough to prevent injection

I am converting from extension mysql to PDO and after reading all I could from you gurus in SO and elsewhere, I have some residual doubts. I came up with the following to address sql injection for a typical query. I am just wondering if that's enough or may be I am going a bit overboard with the whitelisting, before I replicate this to all my application.
It's not clear to me if I did the whitelisting properly, ie, if I should also escape somehow.
Also, I am not sure if I should setAttribute emulate to false for every query or just once for the script.
$link = new PDO("mysql:host=$hostname;dbname=$database;charset=utf8", $username, $password);
$link->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$arr_i=$arr_k='';
$m_act=$v_act='Y';
$table = array('prices', 'versions', 'models');
$allowedTables = array('prices', 'versions', 'models');
$field = array('model_id', 'version_id', 'price', 'models.active', 'versions.active');
$allowedFields = array('model_id', 'version_id', 'price', 'models.active', 'versions.active');
if(count( array_diff($field, $allowedFields))==0 AND count( array_diff($table, $allowedTables))==0){
$sql = "SELECT COUNT(DISTINCT `" . $field[0] . "`) as ctmod FROM `" . $table[0] . "`
INNER JOIN `" . $table[1] . "` USING (`" . $field[1] . "`)
INNER JOIN `" . $table[2] . "` USING (`" . $field[0] . "`)
WHERE `" . $field[2] . "` BETWEEN :arr_i AND :arr_k
AND " . $field[3] . " = :m_act
AND " . $field[4] . " = :v_act";
$stmt = $link->prepare($sql);
$stmt->bindParam(':arr_i', $arr_i, PDO::PARAM_INT);
$stmt->bindParam(':arr_k', $arr_k, PDO::PARAM_INT);
$stmt->bindParam(':m_act', $m_act, PDO::PARAM_STR);
$stmt->bindParam(':v_act', $v_act, PDO::PARAM_STR);
for ($i=0; $i < $ctpri; $i++){
$k=$i+1;
$arr_i=$arr_pri[$i]+1;
$arr_k=$arr_pri[$k];
$stmt->execute();
while ($r = $stmt->fetch(PDO::FETCH_ASSOC)) {
$ctmod[] = $r['ctmod'];
}
}
}
else{die();}
I suspect that you indeed going a bit overboard with the whitelisting. And not only with whitelisting but even with prepared statements too. And to satisfy your wrong views, you over-engineered your query to the point of totally uncomprehensible mess.
What you need to understand is that any constant value is safe by design. So, there is absolutely no point in using nor whitelisting nor prepared statements for it.
So, instead of
AND " . $field[3] . " = :m_act
you should write just
AND versions.active = 'Y'
without any binding or whitelisting.
All you need to protect is dynamical values only. So, you have to use prepared statements for $arr_i and $arr_k only. All other query parts have to be written into query directly, just like you did it before.
Yes, your code is thoroughly safe from SQL injection. Good job.
Though as #YourCommonSense points out, there's no reason in the example you show to make table and columns names into variables at all. It would be simpler to just write them into the query literally.
Therefore, I assume you're asking this question because you do sometimes choose table and column names through application logic or variables, even though you haven't shown it in this particular example.
The only tips I would offer are:
All the string concatenation, with ending double-quotes, using . and re-starting double-quotes makes the code look untidy and it can be confusing to keep track of which double-quotes you've started and stopped. An alternative style of PHP string interpolation for variables is to enclose in curly braces, like the following:
$sql = "SELECT COUNT(DISTINCT `{$field[0]}`) as ctmod FROM `{$table[0]}`
INNER JOIN `{$table[1]}` USING (`{$field[1]}`)
INNER JOIN `{$table[2]}` USING (`{$field[0]}`)
WHERE `{$field[2]}` BETWEEN :arr_i AND :arr_k
AND `{$field[3]}` = :m_act
AND `{$field[4]}` = :v_act";
And for yet another alternative, you can use here documents, so you don't have to worry about delimiting the string at all. Nice if you have literal double-quotes inside your string, because you don't have to escape them:
$sql = <<<GO
SELECT COUNT(DISTINCT `{$field[0]}`) as ctmod FROM `{$table[0]}`
INNER JOIN `{$table[1]}` USING (`{$field[1]}`)
INNER JOIN `{$table[2]}` USING (`{$field[0]}`)
WHERE `{$field[2]}` BETWEEN :arr_i AND :arr_k
AND `{$field[3]}` = :m_act
AND `{$field[4]}` = :v_act
GO;
Finally, it has nothing to do with SQL injection, but a good practice is to check the return value from prepare() and execute(), because they return false if an error occurs in parsing or execution.
if (($stmt = $link->prepare($sql)) === false) {
trigger_error(PDO::errorInfo()[2], E_USER_ERROR);
}
(That example uses PHP 5.4 syntax to dereference an array returned from a function.)
Or else you can configure PDO to throw exceptions, so you don't have to check.
$link->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

getting T_ENCAPSED_AND_WHITESPACE error in PHP

I am creating an App in php
in which i am getting an error on this line #
$sql="INSERT INTO table ( `rollnum`,'sessionid', `class`, `subject`, `theory`, `practical`, `type_of`, `term`) VALUES ('$students['rollnum']', '$session','$class','$subject['id']','$_REQUEST[$subject['id'].'_'.$students['rollnum'].'_th']','$_REQUEST[$subject['id'].'_'.$students['rollnum'].'_pr']', '$examtype', '$examsubtype')";
I dont knoe what's wrong with this line.
i even checked at an online platform.They said the same that there is error on Line #(above).
Anyone who can help me with this
Thanks
you likely need to surround the variables in a double quoted string with braces.
$string = "I want to use {$variable1} and {$variable['thisKey']}";
or the following, which is a little faster to run;
$string = 'I want to use'.$variable1.'and '.$variable['thisKey'];
So that should solve your immediate problem, however your query is very open to an injection which can be very bad, especially if your using $_REQUEST right in your query string. I'd recommend looking into preparing your query statements before running them and ensuring all the dangerous stuff is escaped.
I answered another question that includes a safe way of doing a query over here with this answer
If your PHP environment had had these settings: display_errors = On; error_reporting = E_ALL, you would have seen:
PHP Parse error: syntax error, unexpected '' (T_ENCAPSED_AND_WHITESPACE), expecting identifier (T_STRING) or variable (T_VARIABLE) or number (T_NUM_STRING)
Like in this example:
$array['value'] = 'test';
echo "$array['value']";
It should be like that:
echo "".$array['value']."";
echo "{$array['value']}";
Anyway, you can use numeric keys:
$array[0] = 'test';
echo "$array[0]";
You need to surround your variable names with braces inside the string:
$sql="INSERT INTO stdexamrecord ( `rollnum`,'sessionid', `class`, `subject`, `theory`, `practical`, `type_of`, `term`) VALUES (
'${students['rollnum']}',
'$session',
'$class',
'${subject['id']}',
' " . $_REQUEST[ $subject['id'] . '_' . $students['rollnum'] . '_th'] . "',
' " . $_REQUEST[ $subject['id'] . '_' . $students['rollnum'] . '_pr'] . "',
'$examtype',
'$examsubtype')";
try to use dreamweaver or net bean that might help you to find the error at the correct place

Categories