mysql to mysqli connect code failing? - php

I've seen this code that's been floating around, and also the fixed? version. Basically I've gotten this to work:
mysql_connect("host","client_name","client_pw");
mysql_select_db("database");
$q=mysql_query("SELECT * FROM table");
while($e=mysql_fetch_assoc($q))
$output[]=$e;
print(json_encode($output));
mysql_close();
but for some reason I feel it should be in mysqli. I'm new, and tried to write an equivalent mysqli OO code:
$mysqli = new mysqli("host", "client_name", "client_pw");
$mysqli->select_db("database");
$q = "SELECT * FROM table";
while($e=$mysqli->fetch_assoc($q))
$output[]=$e;
print(json_encode($output));
mysql_close();
It fails. I've tried other combinations, such as preparing a query and executing it, and setting that as $e, but all fail.
Do I have to manually build the array for the json_encode or something?
Maybe a better question is why I want to reinvent the wheel, but this has been bothering me.

Ah, I see you are not one with the database. Let us perform an exercise.
Close your eyes, breathe in, breathe out.
Relax.
You are one with the database.
You are one with the code.
Repeat after me.
Prepare.
Bind.
Execute.
Repeat it.
Again.
This is your new mantra, my friend.
You've accidentally skipped a step in your existing code. Let's throw it out and start over.
I am going to show you how to use PDO, one of the better ways PHP has to communicate with a database. It's less convoluted than the mysqli extension.
// Make sure these variables contain the correct data.
$pdo = new PDO("mysql:host=$hostname;dbname=$database", $username, $password);
// Ask PDO to throw exceptions instead of warnings.
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Here's our SQL. We're getting back a PDOStatement object here.
$sh = $pdo->prepare('SELECT * FROM Foo WHERE bar = ?');
// That question mark is a placeholder. bindValue lets us replace the question mark
// with the specified data. This is called a prepared statement. The end result is
// *complete and total immunity* from SQL Injection, if performed correctly.
$sh->bindValue(1, "I'm looking for a bar that is equal to this.");
// Okay, we've bound everything, let's run the query.
$sh->execute();
// And assuming there are no errors (note my severe lack of error handling),
// we should now have our complete list of data from the database.
print_r($sh->fetchAll(PDO::FETCH_ASSOC));
// Alternatively, we could pass bound variables as an array to execute:
$sh = $pdo->prepare('SELECT * FROM Foo WHERE bar = ?');
$sh->execute(array( "I'm a bar!" ));
// And of course, we can use variables in the binding...
$bar = 746;
$sh = $pdo->prepare('SELECT * FROM Foo WHERE bar = ?');
$sh->bindValue(1, $bar);
$sh->execute();
PDO's support for prepared statements and placeholders makes it one of the best choices for database access in modern PHP.
(mysqli also has access to prepared statements, but it forces you to also bind result variables, and that can be damned awkward under a lot of circumstances.)
fetchAll(PDO::FETCH_ASSOC) returns a multidimensional array. The outer array is numerically indexed, each value being a row. Each row is a string-keyed array, where the keys are column names and the values are the data from the database. There are a few other things that fetchAll can do, though I haven't found many of them to be useful. You can also fetch one row at a time
You can probably pass the results directly to json_encode, if you'd like, and not suffer too many problems.
Understand that you will want to add appropriate error detection to this code. I have omitted it here for brevity.

try
{
$db = new mysqli("your_host_ip", "your_username", "your_pass", "your_db", 3306);
if ($db->connect_errno) throw new exception(sprintf("Could not connect: %s", $db->connect_error));
$sqlCmd = "select * from users order by username";
$result = $db->query($sqlCmd);
if(!$result) throw new exception(sprintf("Invalid query : %s", $sqlCmd));
...

$q=mysql_query("SELECT * FROM table");
Here is how to do it with mysqli OOP
After the line $q= etc. -add the following code..
<?php
$result=$mysqli->query($q);
while($e=$result->fetch_assoc()){
$output[]=$e;
}
print(json_encode($output));
?>

Related

Assign MySQL database value to PHP variable

I have a MySQL Database Table containing products and prices.
Though an html form I got the product name in a certain php file.
For the operation in this file I want to do I also need the corresponding price.
To me, the following looks clear enough to do it:
$price = mysql_query("SELECT price FROM products WHERE product = '$product'");
However, its echo returns:
Resource id #5
instead a value like like:
59.95
There seem to be other options like
mysqli_fetch_assoc
mysqli_fetch_array
But I can't get them to output anything meaningful and I don't know which one to use.
Thanks in advance.
You will need to fetch data from your database
$price = mysql_query("SELECT price FROM products WHERE product = '$product'");
$result = mysql_fetch_array($price);
Now you can print it with
echo $result['price'];
As side note I would advise you to switch to either PDO or mysqli since mysql_* api are deprecated and soon will be no longer mantained
If you read the manual at PHP.net (link), it will show you exactly what to do.
In short, you perform the query using mysql_query (as you did), which returns a Result-Resource. To actually get the results, you need to perform either mysql_fetch_array, mysql_fetch_assoc or mysql_fetch_object on the result resource. Like so:
$res = mysql_query("SELECT something FROM somewhere"); // perform the query on the server
$result = mysql_fetch_array($res); // retrieve the result from the server and put it into the variable $result
echo $result['something']; // will print out the result you retrieved
Please be aware though that you should not use the mysql extension anymore; it has been officially deprecated. Instead you should use either PDO or MySQLi.
So a better way to perform the same process, but using for example the MySQLi extension would be:
$db = new mysqli($host, $username, $password, $database_name); // connect to the DB
$query = $db->prepare("SELECT price FROM items WHERE itemId=?"); // prepate a query
$query->bind_param('i', $productId); // binding parameters via a safer way than via direct insertion into the query. 'i' tells mysql that it should expect an integer.
$query->execute(); // actually perform the query
$result = $query->get_result(); // retrieve the result so it can be used inside PHP
$r = $result->fetch_array(MYSQLI_ASSOC); // bind the data from the first result row to $r
echo $r['price']; // will return the price
The reason this is better is because it uses Prepared Statements. This is a safer way because it makes SQL injection attacks impossible. Imagine someone being a malicious user and providing $itemId = "0; DROP TABLE items;". Using your original approach, this would cause your entire table to be deleted! Using the prepared queries in MySQLi, it will return an error stating that $itemId is not an integer and as such will not destroy your script.

PDO isn't binding PostgreSQL query

I'm using PDO to develop an application with PostgreSQL.
The problem is that the binding functions as PDOStatement::bindValue and PDOStatement::bindParam aren't working at all.
I have the following code:
<?php
try{
$db = new PDO("pgsql:dbname=test;host=localhost", "user", "password");
$all = '*';
$sql = $db->prepare("SELECT :all FROM schema.table");
$sql->bindValue(':all', $all);
var_dump($sql->queryString);
var_dump($sql->execute());
}
catch(PDOException $e){
print $e->getMessage();
}
?>
I just cannot understand the reason $sql->queryString's value still is SELECT :all FROM schema.table, as it var_dump()'d here.
PDOStatement::bindParam does exactly the same thing.
Any tips?
EDIT: This query is for debugging purposes only! Please, don't care about the query itself but in the method that isn't binding.
Prepared statements don't work like that. You can only bind values, not entities.
As far as your statement is concerned, you're executing the query SELECT '*' FROM schema.table, Not, SELECT * FROM schema.table
If you want variable entities (which implies a design flaw about 80% of the time), you will have to resort to string interpolation (or concatenation -- you get the point).

PHP PDO named queries from an array

I've been playing around with switching over to the PDO way of doing database work in PHP. In my java life, I am able to place named queries into an associative array and call the prepared statement using the index. It's a bit more complex than that, but...
Anyways I thought it would be cool to do the same type of thing in PHP.
$NamedQueries['SelectBlackBoxById'] = "select name, category, rating from blackbox where id = :blackbox_id";
So I can prepare my statements this way:
$sth = $dbh->prepare($NamedQueries['SelectBlackBoxById']);
$sth->execute(array('blackbox_id' => '1'));
$sth->setFetchMode(PDO::FETCH_OBJ);
return $sth->fetch();
Instead of this way:
$sth = $dbh->prepare("select name, category, rating from blackbox where id = :blackbox_id");
$sth->execute(array('blackbox_id' => '1'));
$sth->setFetchMode(PDO::FETCH_OBJ);
return $sth->fetch();
I'm sure I am overlooking something, because my preferred way returns false. Any ideas would be greatly appreciated.
$sth->execute(array('blackbox_id' => '1'));
Should be
$sth->execute(array(':blackbox_id' => '1'));
You have to include the :
Did you try to dump out your Array value before you use it to prepare the query?
Overall, I don't see anything wrong with how the PDO would use it, you could also var_dump() your $sth variable after you prepare it to see what might be in there.
In general, as others pointed out the ':' is something you should include when you bind variables, although in this case I don't necessarily think it is the root problem as you said your second example worked, which uses the same syntax, the only difference is using the query from the array instead of a raw string. Thinking that since it is only 1 variable to bind, not having the ':' is not causing problems (though you should add it)
So, your real problem is lack of error handling. And it persists.
error_reporting(E_ALL);
to be notified of variables that out of scope.
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
after connect to be notified of empty queries and whatever else PDO errors

Getting a basic PDO statement to execute

I am attempting to get the following PDO statement to work and running into issues. When I am trying to get the number of rows, I keep getting 0, yet I know there should be 1 row. When I ran it as a mysqli statement( before trying to change it to PDO) it worked perfectly.
Here is the code:
require_once ('pdo.php');
$isbn = $_POST['isbn'];
// check to see if the isbn is a "problem" isbn or not
$problem = $conn->prepare("select isbn, note from problem where isbn = :isbn");
$problem->bindParam(":isbn", $isbn);
$problem->execute();
print_r($problem);
$num_rows = $problem->rowCount();
print_r($num_rows); die;
EDIT: Here is pdo.php:
<?php
function db_connect()
{
$db = new PDO("mysql:host=localhost; db=bookcell_BCOS_final", "xxxxx", "xxxxx");
return($db);
}
?>
I know that my connection works, but I get 0 for $num_rows. What mistakes am I making here?
Besides a little quirk and a optimalisation your code looks fine to me. The posted value isbn could be the reasong that you are getting no data:
$problem = $conn->prepare("select isbn, note from problem where isbn = :isbn");
$problem->bindParam(":isbn", $_POST['isbn'], PDO::PARAM_STR); // <-- thats what parameter binding is for
$problem->execute();
print_r($problem);
$num_rows = $problem->rowCount(); // <-- gives the number of rows, not columnCOunt
print_r($num_rows); die;
The Syntax for $num_rows = $problem->columnCount(); is totally correct. You may try,
$problem->execute(array("isbn" => $isbn));
instead of bindParam.
for getting the no. of rows, you need to use pdo::rowCount() -- manual here
In PDO to verfiy if your execute statement did work, check the return value (bool):
$success = $problem->execute();
if (!$success) {
$arr = $problem->errorInfo();
print_r($arr);
}
Also you might be looking for rowCount() instead of columnCount() but I think the error handling is your furthermost issue.
Additionally you can make PDO throw an exception each time an error appears, compare:
Switching from PHP's mysql extension to PDO. Extend class to reduce lines of code
How do I raise PDOException?
Depending on the database driver and the mode it's running, PDO may not be able to give you a row count. Look carefully at the documentation for PDOStatement::rowCount():
If the last SQL statement executed by the associated PDOStatement was a SELECT statement, some databases may return the number of rows returned by that statement. However, this behaviour is not guaranteed for all databases and should not be relied on for portable applications.
This is because in many cases the database uses a cursor rather than fetching the full results and buffering them (which is how the old mysql_* functions behave). In this case the database doesn't know how many rows there are until you have looked at all the rows. Think of a cursor as something like a filesystem pointer--you can't know the filesize until you seek to the end of the file.

How do you connect/retrieve data from a MYSQL database using objects in PHP?

Generally I connect and retrieve data using the standard way (error checking removed for simplicity):
$db = mysql_select_db("dbname", mysql_connect("host","username","passord"));
$items = mysql_query("SELECT * FROM $db");
while($item = mysql_fetch_array($items)) {
my_function($item[rowname]);
}
Where my_function does some useful things witht that particular row.
What is the equivalent code using objects?
Since version 5.1, PHP is shipped with the PDO driver, which gives a class for prepared statements.
$dbh = new PDO("mysql:host=$hostname;dbname=$db", $username, $password); //connect to the database
//each :keyword represents a parameter or value to be bound later
$query= $dbh->prepare('SELECT * FROM users WHERE id = :id AND password = :pass');
# Variables are set here.
$query->bindParam(':id', $id); // this is a pass by reference
$query->bindValue(':pass', $pass); // this is a pass by value
$query->execute(); // query is run
// to get all the data at once
$res = $query->fetchall();
print_r($res);
see PDO driver at php.net
Note that this way (with prepared statements) will automatically escape all that needs to be and is one of the safest ways to execute mysql queries, as long as you use binbParam or bindValue.
There is also the mysqli extension to do a similar task, but I personally find PDO to be cleaner.
What going this whole way around and using all these steps gives you is possibly a better solution than anything else when it comes to PHP.
You can then use $query->fetchobject to retrieve your data as an object.
You can use the mysql_fetch_object()
http://is2.php.net/manual/en/function.mysql-fetch-object.php

Categories