Prepared statement with string interpolation fails with syntax errors - php

I'm trying to use prepared statements to do a simple insert with PHP and Postgres. So far, I've done this:
<?php
$conn_string = "host=localhost port=5432"; // plus us/pw
$dbconn = pg_connect($conn_string);
$table = 'business_primary_category';
$column = 'primary_category';
$tag = 'restuarant';
// Prepare a query for execution
$result = pg_prepare($dbconn, "my_query", 'SELECT * FROM $table WHERE $column = $1');
// Execute the prepared query. Note that it is not necessary to escape
// the string "Joe's Widgets" in any way
$result = pg_execute($dbconn, "my_query", array("$tag"));
?>
I've taken it basically from the page on php.net, and can't figure out what I've done wrong. Do I need to install a library to use it or something. Thanks!
These are the errors I get:
Warning: pg_prepare() [function.pg-prepare]: Query failed: ERROR: syntax error at or near "$" at character 15 in /home/url **......** pdo.php on line 11
Warning: pg_execute() [function.pg-execute]: Query failed: ERROR: prepared statement "my_query" does not exist in /home/url **......** pdo.php on line 15
Warning: pg_execute() [function.pg-execute]: Query failed: ERROR: prepared statement "my_query" does not exist in /home/url **......** pdo.php on line 18

If you want your variables to be interpolated, then you need to use double quotes; else PHP treats it as a string literal. Try:
$result = pg_prepare($dbconn, "my_query", "SELECT * FROM $table WHERE $column = $1");

First thing that jumps out... Use double quotes on 'SELECT * FROM $table WHERE $column = $1'.

Related

PHP/Oracle - OCI doesn't like my data type?

I'm new to OCI, but just trying to do a basic oci_bind_by_name in PHP to get it working. But even with a simple select statement and a dummy variable, it rejects the variable type.
Here's the code:
$conn = oci_connect($username, $password, $database);
$dummy = "dummy#dummy.com";
$u = oci_parse($conn, "select ca_email from pwv_google_group");
oci_bind_by_name($u, ':ca_email', $dummy);
But it just returns:
Warning: oci_bind_by_name(): ORA-01036: illegal variable name/number
Since this is a very simple query/parameter, I can only assume my syntax is wrong or something might be off on the Oracle side (ca_email really should be a varchar, but I'm using Datagrip which doesn't allow DESC command, so I don't know how to validate that). Is something else wrong?
oci_bind_by_name() is expecting you to bind a value for some form of input to the SQL statement - from the manual
bv_name The colon-prefixed bind variable placeholder used in the
statement. The colon is optional in bv_name. Oracle does not use
question marks for placeholders.
So for your example, it would be more like
$u = oci_parse($conn, "select * from pwv_google_group where ca_email = :ca_email");
oci_bind_by_name($u, ':ca_email', $dummy);
As you are trying to retrieve the values from the data you just need to fetch the data as in (hacked from example #3 in manual)
$u = oci_parse($conn, 'select ca_email from pwv_google_group');
oci_execute($u);
$row = oci_fetch_array($u, OCI_ASSOC+OCI_RETURN_NULLS);
foreach ($row as $item) {
print $item."<br>\n";
}

pg_query(): Query failed: ERROR: column doesnot exist

i did follow the solution here : Warning: pg_query(): Query failed: ERROR: syntax error at or near but i still got the following error :
Warning: pg_query(): Query failed: ERROR: column "rosmoffi" does not exist LINE 1: ... FROM public."espece" where "espece"."Code_Espece" =Rosmoffi ^
this is my code :
$conn = pg_connect($conn_string);
$query = 'SELECT * FROM public."espece" where "espece"."Code_Espece" ='.$idd ;
if (!$result = pg_query($conn, $query)){
echo pg_result_error ($conn);
return false;
}
$result = db($result);
return $result;
$query = 'SELECT * FROM public."espece" where "espece"."Code_Espece" ='.$idd ;
Do not do this. If you were to output what you get here you'd see the error, as you should from the error message. Whatever is in the variable $idd will be put into the query as is and it will not be considered a string. It's just a part of the query. So since there are no quotes it will in this case be understood as a column name.
The worst part of this is that if $idd is coming from the user think what will happen when someone sets it to 1; truncate table espece. Or something worse. Learn how to use parameters immediately.
Using parameters your code would be:
$query = 'SELECT * FROM public."espece" where "espece"."Code_Espece" =$1';
if (!$result = pg_query_params($conn, $query, array($idd))){
This way the variable is given properly to the database and there is no injection vulnerability.
NB! For those who keep saying the double quotes should be removed, no. They should not. If the column name is capitalized as Code_Espece then PostgreSQL will not recognize it without the quotes. Capitalization is usually not recommended.

odbc_prepare for procedure with datetime input parameters

Somewhat new to odbc_prepare statements and am having an issue when trying to execute a stored procedure that requires datetime input parameters.
If I am to execute using odbc without using the prepared statement as displayed below I have no issue...
$dblink = db_connect();
$query = "EXEC dbo.[ProcedureName] '" . $dateinput . "'";
odbc_exec($dblink, $query);
Using the odbc_prepare I'm getting an error (only for procedures with DateTime inputs parameters). Example below...
function execute_db($dblink, $query, $params){
$n = sizeof($params);
for($i=0; $i<$n; $i++){
if($i != 0){
$query = $query . ', ?';
}
else{
$query = $query . ' ?';
}
}
$statement = odbc_prepare($dblink, $query);
odbc_execute($statement, $params);
return $statement;
}
$dblink = db_connect();
$query = "EXEC dbo.[ProcedureName]";
$params = array($dateinput);
$result = execute_db($dblink, $query, $params);
This returns the following error:
Warning: odbc_execute(): SQL error: [Microsoft][ODBC SQL Server
Driver]Invalid character value for cast specification, SQL state 22005
in SQLExecute
The date string I'm passing in is in 'mm/dd/yyyy' format and works fine without using prepare. Is there a workaround for this other than changing the stored procedure's input type?
Use the proper ODBC syntax for calling a procedure and use the proper syntax for date times and it might get you further. The call syntax is {call procname(arguments)}. The datetime syntax is {ts ''} - see Date, Time, and Timestamp Escape Sequences and ODBC Datetime Format

MySql database query not working when I use _GET inside

I am a php beginner.
I have the following script which works if I do not use _GET['version'] in the query, but works if I remove it. There is no error; I am not sure why it is not working.
<?php
// Specify your table name
$hostname = 'localhost';
$dbname = 'stats';
$table_name = 'st_stats';
$username = 'test';
$password = 'test';
try
{
$conn = new PDO("mysql:host=$hostname;dbname=$dbname",$username,$password);
//By default mode is silent and exception is not thrown. So I it to throw ex
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// If the query is like this no error is given but page shows up blank
$stmt = $conn->query("SELECT * FROM $table_name where version = $_GET['version']", PDO::FETCH_ASSOC);
// This works if uncomment below line instead and comment line above
//$stmt = $conn->query("SELECT * FROM $table_name", PDO::FETCH_ASSOC);
$count = $stmt->rowCount();
echo("<h1>currently $count records</h1>");
}
catch(PDOException $e)
{
echo 'ERROR: ' . $e->getMessage();
}
?>
I want to access the page like this
http://www.mydomain/records.php?version=1.2
Note that version column does exit in the table
You could try to avoid a bit of sql injection here by preparing the statement properly:
$v_term = $_GET['version'];
$query = "SELECT * FROM $table_name where version = :term";
$result = $conn->prepare($query);
$result->bindValue(":term",$v_term);
$result->execute();
Also, run the statement straight from the db if you can to make sure you are getting records back. Other than that, there is no other way to debug this for you from what you given us.
Maybe version is not an integer therefore need quotes ?
"SELECT * FROM $table_name where verion = '".$_GET['version']."'",
Anyway you are vulnerable to sql injection and also misusing PDO
You should at least bindParam/bindValue
Or use execute() and past the $_GET value
As documented under Variable parsing:
There are two types of syntax: a simple one and a complex one.
[ deletia ]
Example #8 Simple syntax example
[ deletia ]
echo "He drank some $juices[koolaid1] juice.".PHP_EOL;
[ deletia ]
Complex (curly) syntax
This isn't called complex because the syntax is complex, but because it allows for the use of complex expressions.
[ deletia ]
// Works, quoted keys only work using the curly brace syntax
echo "This works: {$arr['key']}";
That is, you can reference associative arrays from within a double-quoted string in one of two ways:
// simple - don't quote your keys
"... $_GET[version] ..."
// complex - you may quote your keys, but must surround the expression in braces
"... {$_GET['version']} ..."
HOWEVER, you shouldn't be doing either here. You should instead be using a parameterised statement in order to prevent SQL injection attacks:
$stmt = $conn->prepare("SELECT * FROM $table_name WHERE verion = ?");
$stmt->execute([$_GET['version']]);
This doesnt work because you're trying to access $_GET['version'] an array variable within a string here
"SELECT * FROM $table_name where version = $_GET['version']", PDO::FETCH_ASSOC
placing {} around the variable will fix this one issue
$stmt = $conn->query("SELECT * FROM $table_name where verion = {$_GET['version']}", PDO::FETCH_ASSOC);
But you should also sanitize this value before you put it right int a sql statement
You have verion rather than version in your query. You're also not passing the value of $_GET['version'], you're passing the string "$_GET['version']" right into the query. Update your query to this:
$stmt = $conn->query("SELECT * FROM $table_name where version = {$_GET['version']}", PDO::FETCH_ASSOC);
Wrapping a variable that's inside a double quoted string ("") in curly braces ({}) evaluates to the value of the variable.
If you do this you will be wide open to SQL injection attacks. Be sure to sanitize the variable before you run the query, or better yet consider prepared statements.

Simple mysqli query not working

I'm trying to get simple info from a database and echo it to screen, but it's not working for me.
$con=mysqli_connect("SERVER.COM","USERNAME","PASSWORD", "DATABASE");
function GetTeamFixtures($team)
{
$queryget = mysqli_query($con, "SELECT * FROM 'mlsfixtures' WHERE team='$team' LIMIT 1");
$row = mysqli_fetch_assoc($queryget);
$gw1 = $row['gw1'];
$gw2 = $row['gw2'];
echo $team.' '.$gw1.' '.$gw2.'<br>';
}
$team = "Chicago Fire"; GetTeamFixtures($team);
$team = "Chivas USA"; GetTeamFixtures($team);
$team = "Colorado Rapids"; GetTeamFixtures($team);
//continue for all teams - removed for simplicity
Here are the error messages I get (line 46 is the $queryget= one and line 49 is the $row = one).
Warning: mysqli_query() expects parameter 1 to be mysqli, null given in server.com\teamfix.php on line 46
Warning: mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, null given in server.com\teamfix.php on line 49
Any idea why? I'm not sure if there's an easier way of doing the same thing but for 19 different teams.
One of the errors i've found, aside from the two users that explained about connection, is the invalid use of single quotes.
Tables names should not be wrap with single quotes as they are identifiers and not a string literals. Remove the single quotes and it should work,
SELECT * FROM mlsfixtures WHERE team='$team' LIMIT 1
MySQL - when to use single quotes, double quotes, and backticks?
As a sidenote, the query is vulnerable with SQL Injection if the value(s) of the variables came from the outside. Please take a look at the article below to learn how to prevent from it. By using PreparedStatements you can get rid of using single quotes around values.
How to prevent SQL injection in PHP?
Another way to access variables outside a function instead of using global variables is to add it up in its parameters
E.g
function GetTeamFixtures($team,$con)
{
// query inside
}
Also as J W says in your query remove '' or replace it with `` backticks..
(This is my attempt at combining all the other answers in a concise manner.)
There are two problems.
First, the global variable $con is not accessible from within your function without a global statement. The global statement can be used to create a reference to $con from within your function.
global $con; // is equivalent to:
$con =& $GLOBALS['con'];
Second, the table name cannot be enclosed in single quotes. Remove the quotes.
// By the way, this should be using mysqli::prepare and mysqli_stmt::bind_param
// to prevent SQL injection
$queryget = mysqli_query($con, "SELECT * FROM mlsfixtures WHERE team='$team' LIMIT 1");
You don't have access to $con from within your function. This should work:
$con = mysqli_connect("SERVER.COM","USERNAME","PASSWORD", "DATABASE");
function GetTeamFixtures($team)
{
global $con;
$queryget = mysqli_query($con, "SELECT * FROM `mlsfixtures` WHERE `team`='$team' LIMIT 1");
$row = mysqli_fetch_assoc($queryget);
$gw1 = $row['gw1'];
$gw2 = $row['gw2'];
echo $team.' '.$gw1.' '.$gw2.'<br>';
}
P.S. If the $team you're passing in to GetTeamFixtures comes from user input, you should prepare your statement, to prevent SQL injection.
$con isn't visible within the function. If you want a global variable to be in scope in a function, you must declare it global:
function GetTeamFixtures($team) {
global $con;
# ...
}

Categories