It appears I can connect to my database using PDO, but can't execute any queries with it. Example:
private function connect() {
try {
$link = new PDO("mysql:host=$this->sHost;dbname=$this->sName", $this->sUser, $this->sPass);
}
catch (PDOException $e) {
die ($e);
}
print_r($link);
$result = $link->query("select * from mt3_users");
var_dump($result);
$row = $result->fetch($result);
die("Your id is: ".$row["id"]);
//$link = mysql_connect($this->sHost, $this->sUser, $this->sPass);
if (!$link) {
echo "Failed to connect to $this->sHost!";
return false;
}
return $link;
}
This returns the following:
PDO Object ( ) bool(false)
Fatal error: Call to a member function fetch() on a non-object in Database.php on line 32
So basically, $link is coming back as a PDO object (I changed my username and password to see if an exception was caught; it was) and PDOConnection::Query is returning null for some reason. This is my first time dealing with PDOs -- am I doing something funny?
Most likely the query fails, are you sure of the name of the table mt3_users and that you have selected the right database? That error message shows that $result is not an object and that's due to an error in the query.
Also:
$row = $result->fetch($result);
should be
$row = $result->fetch();
unless you want to specify options to fetch(), but you don't pass the object as argument.
Array ( [0] => 00000 [1] => 1046 [2] => No database selected ) Array ( )
Nevermind, I guess. It turns out that while migrating from using regular MySQL functions, I wasn't setting $this->sName ($this->sName was null. I'm half surprised it didn't throw an exception. Only half, though)
Fixed.
But thank you guys for the answers :)
can you give this a try
private function connect() {
try {
$link = new PDO("mysql:host=$this->sHost;dbname=$this->sName", $this->sUser, $this->sPass);
return $link ;
}
catch (PDOException $e) {
die ($e);
}
}
$pdolink = $this->connect();
$rows = $pdolink->query("select * from mt3_users");
foreach($rows as $row ){
echo("Your id is: ".$row["id"]);
}
and if you need to stick with fetchAll function
private function connect() {
try {
$link = new PDO("mysql:host=$this->sHost;dbname=$this->sName", $this->sUser, $this->sPass);
return $link ;
}
catch (PDOException $e) {
die ($e);
}
}
$pdolink = $this->connect();
$q = $pdolink->prepare("select * from mt3_users");
$q->exectue();
$rows = $q->fetchAll();
var_dump($rows);
foreach($rows as $row ){
echo("Your id is: ".$row["id"]);
}
In order to get the error in your query:
$result = $link->query(...);
if($result===FALSE){
print_r( $link->errorInfo);
exit();
}
// the correct way to fetch one row
$link->fetch(PDO::FETCH_ASSOC); // or whatever way you want to fetch data
Related
I'm moving PHP code from mysql to ms sql server.
This will execute my query:
$r = $db_conn->prepare($sql);
$r->execute();
Before I start processing, I need to count how many rows were returned.
old code:
$r->num_rows;
new code:
$rows = $r->fetchAll(PDO::FETCH_ASSOC);
$rcount = count($rows);
All good, but when I try to access values from 1st row I'm getting nothing...
try {
$row = $r->fetch(PDO::FETCH_ASSOC);
} catch (Exception $ex) {
return 0;
}
I need to repoint to 1st row in my recordset after doing the count, how can I do this without having to requery the database again?
I'm new to PHP, sorry for dumb and probably obvious question.
Thanks in advance.
There isn't a way in PDO to reset the pointer. You could execute the query again, but given that you've already fetched all the data with your call to fetchAll, that is wasteful. Instead, to access the data, simply loop over the $rows array e.g.
foreach ($rows as $row) {
// do something
}
Note that if you expect an exception on fetch, it is likely you might get one on fetchAll too, so you should wrap the call to fetchAll in a try/catch block:
try {
$rows = $r->fetchAll(PDO::FETCH_ASSOC);
} catch (Exception $ex) {
return 0;
}
One possible approach, if you use PHP Driver for SQL Server, is to use PDOStatement::rowCount and client-side cursor. With this type of cursor row count is available after a query is executed, but this type of cursor should be used for small (medium) result sets.
<?php
# Connection
$server = 'server\instance,port';
$database = 'master';
$uid = 'uid';
$pwd = 'pwd';
# PDO Connection
try {
# SQL authentication
$conn = new PDO("sqlsrv:server=$server;Database=$database", $uid, $pwd);
# Windows authentication
#$conn = new PDO("sqlsrv:server=$server;Database=$database");
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch( PDOException $e ) {
die( "Error connecting to SQL Server".$e->getMessage());
}
# Client-side cursor
try {
$options = array(
PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL,
PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED
);
$stmt = $conn->prepare("SELECT * FROM master.sys.server_principals", $options);
$stmt->execute();
echo 'Row count: '.$stmt->rowCount().'<br>';
while ($row = $stmt->fetch(PDO::FETCH_ASSOC) ){
echo 'Login name: '.$row['name'].'<br>';
}
} catch( PDOException $e ) {
die( "Error executing query".$e->getMessage() );
}
# End
$stmt = null;
$conn = null;
?>
I have a reasonably complicated stored procedure in MSSQL 2008 R2 that, in the end, results in a small table being returned. The PHP will be called from javascript and I want it to return the array as JSON to be used in table in the javascript.
I am using PHP to access it and, using the profiler, can see that I am calling the SP and passing the correct parameters to it.
My PHP looks like this:
try {
$dbh = new PDO("sqlsrv:Server=(local);Database=cddDispo");
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
echo json_encode("Error connecting to the server.");
die ();
}
$lot = $_POST["lot-input"];
$layerAdder = $_POST["layer-input"];
$adder = substr($layerAdder,-3,3);
$adder = str_replace('=','',$adder);
$layer = substr($layerAdder,0,strpos($layerAdder,' '));
$sth = $dbh->prepare('EXEC dbo.pullDispo ?,?,?');
$sth->bindParam(1,$lot,PDO::PARAM_STR);
$sth->bindParam(2,$layer,PDO::PARAM_STR);
$sth->bindParam(3,$adder,PDO::PARAM_STR);
$array = array();
try {
$sth->execute();
while($row = $sth->fetch(PDO::FETCH_ASSOC)) {
//I want to build my output array here
}
}catch (PDOException $e) {
echo "Error getting data, please try again.";
die();
}
header('Content-type: application/json');
echo json_encode($array);
This is the first time that I have tried to return table results from a stored procedure and even with several PHP Manual/ Google searches I have not figured out how to capture the table back in the PHP. I have a less elegant workaround (write the SP table to a static table and call that table later in the PHP) but would rather figure out if I can do in a more elegant manner. Any advice is much appreciated.
I thought it might be useful if I posted my final code:
function array_push_assoc($array,$key,$value) {
$array[$key] = $value;
return $array;
}
header('Content-type: application/json');
try {
$dbh = new PDO('sqlsrv:Server=(local);Database=cddDispo');
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
echo json_encode('Error connecting to the server.');
die ();
}
$lot = $_POST['lot'];
$layer = $_POST['layer'];
$adder = $_POST['adder'];
$sth = $dbh->prepare('EXEC dbo.pullDispo ?,?,?');
$sth->bindParam(1,$lot,PDO::PARAM_STR);
$sth->bindParam(2,$layer,PDO::PARAM_STR);
$sth->bindParam(3,$adder,PDO::PARAM_STR);
$results = array();
$combinedArray = array();
$array = array();
$count = 0;
try {
$sth->execute();
do {
$results[] = $sth->fetchAll(PDO::FETCH_ASSOC);
}while ($sth->nextRowset());
foreach($results as $row) {
if($count == 0) {
$headerArray =
[
'Lot' =>$row['Lot'],
'Layer' =>$row['Measured Layer'],
'Product' =>$row['MES Product'],
'Adder' =>$row['Adder Chart']
];
$combinedArray = array_push_assoc($combinedArray,'header',$headerArray);
}
$count++;
//This is for formatting of final table
if($row['UDL'] == 0) {
$udl = 'NA';
} else {
$udl = round($row['UDL'],4);
}
$infoArray =
[
'Wafer' =>$row['Wafer'],
'Type' =>$row['Type'],
'Count' =>$row['Count'],
'CDD' =>round($row['CDD'],3),
'UCL' =>round($row['UCL'],4)
];
array_push($array,$infoArray);
}
$combinedArray = array_push_assoc($combinedArray,'detail',$array);
}catch (PDOException $e) {
echo json_encode('Error running stored procedure.');
die();
}
echo json_encode($combinedArray);
Could it be that your stored procedure is returning multiple result sets? This includes output like warning messages or number of rows affected. Try adding SET ANSI_WARNINGS OFF or SET NOCOUNT ON at the top of your stored procedures after the AS. You can also try advancing to the next result set in PHP before trying to get the results by calling $stg->nextRowset() before $sth->fetchAll().
Use fetchAll() to get your resultset, then encode that array as your json response:
$array = array();
try {
if($sth->execute()){
$array = $sth->fetchAll(PDO::FETCH_ASSOC);
}else{
$array = array('error'=>'failed to execute()')
}
}catch (PDOException $e) {
echo "Error getting data, please try again.";
die();
}
header('Content-type: application/json');
echo json_encode($array);
When you are calling a stored procedure with multiple result sets, you probably do not want to add SET NOCOUNT ON into every procedure you have; you always can add
$dbh->setAttribute(constant('PDO::SQLSRV_ATTR_DIRECT_QUERY'), true);
$dbh->query("SET NOCOUNT ON");
before of
$dbh->prepare($query);
and it will work.
I'm trying to call my function, but she's wrong.
I believe it is in connection variable.
Connection:
$conn = mysqli_connect('','','', '');
if(mysqli_connect_errno()) {
header("Location: error.php");
exit();
}
Function:
function t_car($id) {
global $conn;
$s_t_car = "SELECT *
FROM t_car
WHERE session='$id'";
$s_t_car_return = mysqli_query($conn, $s_t_car) or die("Erro SQL.".mysqli_error());
return $s_t_car_return;
}
Call Function:
$s_t_car_return = t_car($conn, $_SESSION['session_client']);
if(mysqli_num_rows($s_t_car_return )!=0) {
while($r_t_car = mysqli_fetch_array($s_t_car_return )) {
}
}
Error:
Catchable fatal error: Object of class mysqli could not be converted to string
At first you need to enter your settings from your MySQL server (mysql db).
$connection = mysqli_connect("HOSTNAME","USERNAME", "PASSWORD","DATABASE");
You can then use an if statement to check if the connection to the server has been made, if so, continue execution of following code, otherwise die();
If you want to fetch the data see below here:
$res = $connection->query("SELECT finger FROM hand WHERE index = 3");
while($row = $res->fetch_array())
{
print_r($row);
}
mysqli_query() returns a result. You have to fetch the result to do something with it.
$res = mysqli_query($conn, $s_t_car) or die("...");
$s_t_car_return = mysqli_fetch_row($res);
Using the code below, I get the error, "Call to undefined method stdClass::fetchObject()".
function getProdDetails2SaveInInvoice($data) {
global $dbh;
try {
$sth=$dbh->prepare("
SELECT
AES_DECRYPT('alt_id', ?),
AES_DECRYPT('prod_name', ?),
AES_DECRYPT('prod_desc', ?)
FROM
products
WHERE
prod_id = ?
");
$sth->execute($data);
$rs = $sth->query(PDO::FETCH_ASSOC);
return $rs;
}
catch(PDOException $e) {
echo "Something went wrong. Please report this error.\n";
file_put_contents(
$_SERVER['DOCUMENT_ROOT']."/PDOErrors.txt",
"\n\nScript name : ".SCRIPT."\nFunction name : ".__FUNCTION__."\n".
$e->getMessage(), FILE_APPEND);
throw new failedTransaction();
}
}
$data = array(
DBKEY, /* field 1 */
DBKEY, /* field 2 */
DBKEY, /* field 3 */
$prodid /* comparison */
);
$rs = getProdDetails2SaveInInvoice($data);
while ($row = $rs->fetchObject()) {
echo $row->prod_name;
}
Unfortunately, this doesn't work and returns the error mentioned above.
I can confirm that the $dbh database connection is working as it's the same connection working for the inserts and updates. Thanks.
UPDATE
This is how I've amended my code based on the suggestions below, but I'm still getting nothing returned:
try {
$dbh = new PDO("mysql:host=".CO_DB_HOST.";dbname=".CO_DB_NAME, CO_DB_UNAME, CO_DB_PWORD);
$dbh ->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
}
catch(PDOException $e) {
echo $e->getMessage();
}
function getProdDetails2SaveInInvoice($data) {
global $dbh;
try {
$sth=$dbh->prepare("
SELECT
AES_DECRYPT('alt_id', ?),
AES_DECRYPT('prod_name', ?),
AES_DECRYPT('prod_desc', ?)
FROM
products
WHERE
prod_id = ?
");
$sth->execute($data);
while ($row = $sth->fetchObject()) {
// PROCESS ROW
$rs = array($row->alt_id, $row->prod_name, $row->prod_desc);
}
return $rs;
}
catch(PDOException $e) {
echo "Something went wrong. Please report this error.\n";
file_put_contents(
$_SERVER['DOCUMENT_ROOT']."/PDOErrors.txt",
"\n\nScript name : ".SCRIPT."\nFunction name : ".__FUNCTION__."\n".
$e->getMessage(), FILE_APPEND);
throw new failedTransaction();
}
}
// Fetch additional info from invoice_products.
$data = array(
DBKEY, /* field 1 */
DBKEY, /* field 2 */
DBKEY, /* field 3 */
$prodid /* comparison */
);
$rs = getProdDetails2SaveInInvoice($data);
print_r($rs);
If I hardcode the 'where' argument (19), it still does not retrieve the result. Ideally I think I should retrieve the result in an object so that it can be streamed, but right now, I'd be happy even if it came in a box!
The data is definitely existing in the database and can be pulled using a traditional query.
This is the output of the print_r($rs):
Array
(
[0] =>
[1] =>
[2] =>
)
You should loop over the prepared statement, and not call query on the prepared statement. Basic usage of prepared statements is as follows:
$sth = $dbh->prepare("YOUR QUERY");
$sth->execute();
$results = array();
while ($row = $sth->fetchObject()) {
$results[] = array(
'alt_id' => $row->alt_id,
'prod_name' => $row->prod_name,
'prod_desc' => $row->prod_desc
);
}
return $result;
As an alternative you could also use $sth->fetchAll() which returns an array with all rows that are the result of your query, see PDOStatement::fetchAll().
I have a problem with the PDO::FETCH_OBJECT argument. I want to fetch an object and not an array, but when I try this:
try {
$conn = new PDO('mysql:host=localhost;dbname=washngo', $config['DB_USERNAME'], $config['DB_PASSWORD']);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //Fetch errors by default ( display any errors during the development process )
$stmt = $conn->prepare('SELECT * FROM news');
$stmt->execute();
while($row = $stmt->fetch(PDO::FETCH_OBJECT)) { //By default, it fetch an array. The "PDO::FETCH_OBJECT" argument allows us to fetch an object
print_r($row);
}
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
I get
Fatal error: Undefined class constant 'FETCH_OBJECT' in index.php on line 18.
When I try to let the fetch() by default (without PDO::FETCH_OBJECT()), it works fine.
Correct is not PDO::FETCH_OBJECT but PDO::FETCH_OBJ