I was using the following code to execute the queries in the database:
$sql = "SELECT * FROM cc_topchoices WHERE location='$location' ORDER BY position asc";
$result = mysqli_query($conn, $sql);
I have read that this way to make the queries is not secure so I want to use the statements prepare() and execute() in php
Now my code looks like this:
$sql = "SELECT * FROM cc_topchoices WHERE location=:location ORDER BY position asc";
$stmt = $conn->prepare($sql);
$stmt->execute(array(":location" => $location));
$result = mysqli_query($conn, $stmt);
But this give me this error:
Fatal error: Call to a member function execute() on boolean
Any idea?
EDIT
Now my code looks like this:
// Create connection
$conn = new PDO("mysql:host=$servername;dbname=$dbname", "$username", "$password");
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->exec("set names utf8"); //BECAUSE I NEED TO WORK WITH CHINESE LANGUAGE
$sql = "SELECT * FROM cc_topchoices WHERE location=? ORDER BY position asc";
$stmt = $conn->prepare($sql);
$stmt->bindParam(':location', $location);
$stmt->execute(array($location));
$result = $stmt->setFetchMode(PDO::FETCH_ASSOC);
if ($result > 0) {
// output data of each row
while($row = $stmt->fetch()) {
echo "<li><div><a href='". $row["rest_url"] ."'><img src='images/top_choices/". $row["image"] ."' alt='". $row["alt_desc"]. "' /></a></div></li>";
}
} else {
echo "0 results";
}
is working :) just need to know if this is a good and secure practice
PDO supports named parameters. MySQLi does not. $stmt is false to show you that the SQL you tried to prepare is syntactically malformed. Use ? instead of :location. Check the MySQLi manual for the correct way to use MySQLi. Or, alternately, switch to PDO.
Use below code to fetch records instead of mysqli_query when using pdo statements if your query returns single row.
$result = $stmt->fetch(PDO::FETCH_ASSOC);
echo $result['db_column'];
And if return multiple rows:
$stmt->setFetchMode(PDO::FETCH_ASSOC);
while ($result = $stmt->fetch()) {
echo $result['db_column'];
}
And one more thing, always put your prepared statement in try{}..catch{} block.
It will work for you.
Related
I am trying to compare php variable in the sql query as follows:
I have used '$a' as the way to compare. Any solution will provided will be quite helpful.
<?php
$username=$_SESSION['alogin'];
$sql = "SELECT kDepartment FROM USERS WHERE kUsername=:username ";
$query= $dbh -> prepare($sql);
$query-> bindParam(':username', $username, PDO::PARAM_STR);
$query->execute();
$results=$query->fetchAll(PDO::FETCH_OBJ);
if($query->rowCount() > 0)
{
foreach($results as $result2)
$a=$result2;
{?>
<?php }}?>
<?php
$sql2 = "SELECT BudgetInput.kBudgetAvailable FROM BudgetInput WHERE BudgetInput.kDepartment='$a' ";
$query2 = $dbh -> prepare($sql2);
$query2->execute();
$results2=$query2->fetchAll(PDO::FETCH_COLUMN, 0);
print htmlentities($a);
?>
I am unable to fetch the result.
When I remove WHERE BudgetInput.kDepartment='$a'; the UI works correctly.
The main issue that I can see with your code is that you are assigning an object ($result2 is the last entry in the array of objects returned by your query) to $a and then trying to use that as a string (I'm not sure why you're using PDO::FETCH_OBJ for your fetchAll call when you are only retrieving a single value but that's another question). Anyway, the fetchAll will return an anonymous object (see the manual) with one property, kDepartment. To use that value, change:
$sql2 = "SELECT BudgetInput.kBudgetAvailable FROM BudgetInput WHERE BudgetInput.kDepartment='$a' ";
to
$sql2 = "SELECT BudgetInput.kBudgetAvailable FROM BudgetInput WHERE BudgetInput.kDepartment='{$a->kDepartment}' ";
The other (minor) issue that I see is that you are using rowCount. This is not guaranteed to work for SELECT statements (see the manual) and since you have already done a fetchAll you don't need it, you can simply change
if($query->rowCount() > 0)
to
if (count($results) > 0)
All you need is a simple join - then you need one query instead of two. A query from the result of another query is rarely the best approach.
Here we prepare a query which selects the available budget from the BudgetInput table, where it has a matching kDpeartment in the USERS table, and a username matching the variable in $username.
<?php
session_start();
$username = $_SESSION['alogin'];
$stmt = $dbh->prepare("SELECT bi.kBudgetAvailable
FROM BudgetInput bi
JOIN USERS u ON u.kDepartment=bi.kDepartment
WHERE u.kUsername=?");
$stmt->execute([$username]);
if ($result = $stmt->fetch()) {
echo $result['kBudgetAvailable'];
} else {
echo "No results found";
}
want i want is to query my db with post variable in the query. It's not really working for me, does anyone know how to do it properly?
Here is what i have so far.
$query = "SELECT column FROM `table` WHERE 'name' = '$_POST[checkname]'";
$result = mysqli_query($db, $query) or die ("no query");
$cod = mysqli_fetch($result);
echo $cod;
Any help is appreciated. Thanks guys.
Mysqli supports prepared statements, which protect against sql injection attacks. It would look like this:
/* Create a prepared statement */
$stmt = $mysqli -> prepare("SELECT column FROM table WHERE name=?");
/* Bind parameters */
$stmt -> bind_param("s", $_POST['checkname']);
/* Execute it */
$stmt -> execute();
/* Bind results */
$stmt -> bind_result($result);
/* Fetch the value */
$stmt -> fetch();
echo $result;
Check the manual for more info.
A quick rundown, in response to the comment:
In $stmt->prepare("..."), you're forming your query, and you hold the place of any variables you intend to use with a "?"
In $stmt -> bind_param(...), you're binding the variables to their corresponding question mark. The first argument is the type, the following arguments are the variables. If you were using a string and an integer, inside the parenthesis it would look like "si", $stringVar, $intVar
In $stmt -> bind_result(...) you are stating what you are binding the results to. If the query was for a name and age, inside the parethesis would look like $name, age
In $stmt->fetch(), you're fetching the result. If it was multiple rows returned, you would do something like:
while($stmt->fetch()) {
//code here
}
Alternatively, you could use PDO. It would look something like this:
/* Create a prepared statement */
$stmt = $pdo->prepare("SELECT column FROM table WHERE name=:checkname");
/* Bind parameters */
$stmt->bindParam(':checkname', $_POST['checkname']);
/* Execute it */
$stmt->execute();
/* Fetch results */
$obj = $stmt->fetchObject();
echo $obj->column;
Check the manual for more info.
//it is apsulutly
// work
if(isset($_POST['checkname']))
{
$post = mysql_real_escape_string(trim($_POST[' checkname ']));
$query = "SELECT column FROM `table` WHERE name = '$post'";
$result = mysqli_query($db, $query) or die ("no query");
$cod = mysqli_fetch_all($result);
echo implode($cod[0]);
echo implode($cod[1]);//For particular cell
}
it works, just try it out like this
following your code...
if(isset($_POST['checkname']))
{
//to avoid SQL injections
$post = mysql_real_escape_string(trim($_POST['checkname']));
$query = "SELECT column FROM `table` WHERE name = '$post'";``
$result = mysqli_query($db, $query) or die ("no query");
$cod = mysqli_fetch($result);
echo $cod;
}
I use fetch_array(MYSQLI_ASSOC) with query but it doesn't work with prepared statements. What is the equivalent of that in prepared statements?
Here it is:
$query = "SELECT `users` FROM `table` WHERE `country` = :country";
$stmt = $pdo->prepare($query);
$stmt->execute(array(
':country' => $country
));
$result = $stmt->fetch(PDO::FETCH_ASSOC); // Here you define how results are fetched
or you can define default FETCH MODE to be an associate array, like this:
$pdo = new PDO(...);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$result = $stmt->fetch(); // The same thing now
In addition to the accepted PDO solution, here is one for mysqli:
The first thing to keep in mind is that mysqli prepared statements do not require results to be bound:
Instead of using bound results, results can also be retrieved through the mysqli_result interface. mysqli_stmt_get_result() returns a buffered result set.
So, for example:
$sql = 'SELECT * FROM mytable ORDER BY column LIMIT ?,' . SOME_CONSTANT;
Once you have bound and executed your statement, you can call get_result():
$stmt = $db->prepare($sql);
$stmt->bind_param('i', $int) || die($db->error);
$stmt->execute() || die($db->error);
$result = $stmt->get_result();
At this point we are functionally equivalent to:
if ($result = $db->query($sql)) {
And can call our familiar fetch_array:
while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
$results[] = $row;
}
Instead of closing the result as we would in the non-prepared equivalent, we close the statement:
$stmt->close();
Can I do a WHERE clause inside an IF statement?
Like I want something like this:
$SQL = mysql_query("SELECT * FROM `table` ORDER BY `row` DESC");
$rows = mysql_fetch_array($SQL);
$email = $_SESSION['email_of_user'];
if($rows["row"] == "1" WHERE `row`='$email' : ?> (Pulls the logged in user's email)
Edit Server
<?php else : ?>
Add Server
<?php endif; ?>
Do I need (" where the WHERE statement is? Because I tried that and it didn't seem to work...
Or can I do it with an if condition inside of a where clause? Not sure of all these terms yet so correct me if I'm wrong...
You cannot mix up a query statement with PHP's statement. Instead write a query extracting desired results and check if there are any rows from that query.
I will show you an example:
$query = "SELECT * FROM `TABLE_NAME` WHERE `field` = '1' && `email`='$email'"; //Create similar query
$result = mysqli_query($query, $link); //Query the server
if(mysqli_num_rows($result)) { //Check if there are rows
$authenticated = true; //if there is, set a boolean variable to denote the authentication
}
//Then do what you want
if($authenticated) {
echo "Edit Server";
} else {
echo "Add Server";
}
Since Aaron has shown such a effort to encourage safe code in my example. Here is how you can do this securely. PDO Library provides options to bind params to the query statement in the safe way. So, here is how to do it.
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass); //Create the connection
//Create the Query Statemetn
$sth = $dbh->prepare('SELECT * FROM `TABLE_NAME` WHERE field = :field AND email = :email');
//Binds Parameters in the safe way
$sth -> bindParam(':field', 1, PDO::PARAM_INT);
$sth -> bindParam(':email', $email, PDO::PARAM_STRING);
//Then Execute the statement
$sth->execute();
$result = $sth->fetchAll(); //This returns the result set as an associative array
I have the following code and I'm getting crazy with calling an auto_increment id
$sql = "INSERT INTO tablename (x1, x2) VALUES(?,?)";
if($query = $db->prepare($sql)){
$query->bind_param('ss', $x1, $x2);
$query->execute();
$id = mysqli_insert_id($query);
For a reason I don't know why this is not working. I also tried
$id = mysqli_insert_id($sql);
And
$id = mysqli_insert_id();
I just decided to work with mysqli. Before that, I only used MySQL where I had no problem with
$id = mysql_insert_id();
You must pass the mysqli link to mysqli_insert_id(), not the query:
$link = mysqli_connect("localhost", "my_user", "my_password", "world");
$sql = "INSERT INTO tablename (x1, x2) VALUES(?,?)"
$result = mysqli_query($link, $sql);
$id = mysqli_insert_id($link);
or since you were using object oriented style:
// ...
$id = $mysqli->insert_id;
Probably something like
$query->commit(); OR $query->close();
It's best to stick to OOP style. It will cause you less confusion. In OOP style you only need to access a property on the object. For example:
$stmt = $db->prepare($sql);
$stmt->bind_param('ss', $x1, $x2);
$stmt->execute();
// Either one will work
$stmt->insert_id;
$db->insert_id;
If you want to use the procedural mysqli style then you have to remember that there are two functions. One if for the mysqli object and the other is for mysqli_stmt object. You need to pick either one of them, but you have to pass the right object to it.
// For mysqli_stmt object
mysqli_stmt_insert_id($stmt);
// For mysqli object
mysqli_insert_id($db);
$result = mysql_query($sql);
if(!$result) {
{
die('Error: ' . mysql_error());
} else {
echo "<p>Done!.</p>";
}
Try this and check the output...