array_merge() issue with PDO - php

I have a function which should return me an array like this
Array
(
[company1] => position1
[company2] => user2
)
I have a proper SQL query which fetches me the required data just fine (tested in MySQL workbench and by dumping the data.
The function that does the thing (see the comment in CAPS at the line with issue):
function check_user_status ($db){
try {
$log = new PDO("mysql:host=".$db['server'].";dbname=".$db['db'], $db['mysql_login'], $db['mysql_pass'], array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
// set the PDO error mode to exception
$log->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// prepare sql and bind parameters
$stmt=$log->prepare ("select a.companyname,b.role from companies a, roles b where a.companyid=b.companyid and (b.uid = :uid and b.suspended = 0);");
$stmt->bindParam(":uid", $_SESSION['uid'], PDO::PARAM_INT);
$stmt->execute();
$count=$stmt->rowCount();
//echo "<br>count = $count<br>"; //outputs the numbner of resulting rows for debuging
if($count >=1) {
unset ($_SESSION['status']); //purge any previous user_status
$_SESSION['status'] = array();
while ($userRow = $stmt->fetch(PDO::FETCH_ASSOC)) {
//echo "<br>{$userRow['companyname']} => {$userRow['role']}<br>"; outputs the data for debuging
array_merge ($_SESSION['status'], array($userRow['companyname'] => $userRow['role']));// THIS DOESN'T WORK FOR SOME REASON
}
return true;
}
else
{
//return false;
}
}
catch(PDOException $e) {
return false;
echo 'error: '. $e->getMessage();
}
}
Now this:
check_user_status($db);
var_dump ($_SESSION['status']);
Outputs me empty array:
array(0) { }
array_merge_recursive() doesn't work either. Notices are enabled, no notice is thrown. Any help would be highly appreciated.

RTM: http://php.net/array_merge
Return Values: Returns the resulting array.
You have:
array_merge ($_SESSION['status'], array($userRow['companyname'] => $userRow['role']));
// THIS DOESN'T WORK FOR SOME REASON
"for some reason" = you're completely IGNORING the return value, which is your merged array.

Related

var_dump and print_r show nothing, can't check it item exists in Database

I have a PDO that is querying a non-existant user in the database to handle user registration. The problem is, var_dump and print_r both do not print anything if the user is not found.
try {
$stmt->execute();
while($row = $stmt->fetch()) {
var_dump($row);
print_r($row);
if($row = null) { // Not working
# if(!isset($row)) { // Not working
# if(empty($row)) { // Also not working
echo "User not found";
} else {
echo $row['realname']."<br>";
}
}
} catch(PDOException $e) {
echo "FATAL ERROR OCCURED:".$e->getMessage();
}
What is happening here? The page is just blank.
php -l index.php repors no syntax errors and the page is not throwing error 500.
Nothing in view source either.
Here is connection details:
try {
$dbh = new PDO('mysql:host=127.0.0.1;dbname=PHP_PDO', "root", "root", array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
));
} catch(PDOException $e) {
die("FATAL ERROR OCCURED");
}
$stmt = $dbh->prepare("SELECT realname FROM users WHERE name = :name" );
$stmt->bindParam(":name", $name);
$name = "mivuckovaca"; // NOT IN DATA BASE
The reason why it's not working, is that you are "assigning" in if($row = null) using 1 equal sign, rather than "comparing" if($row == null) with 2 equal signs (or 3 "if identical", depending on what you want to check for).
Consult: The 3 different equals here on Stack about this.
References:
http://php.net/manual/en/language.operators.assignment.php
http://php.net/manual/en/language.operators.comparison.php
PHP sees the "assignment" as being valid syntax and that is why you are not receiving any errors.
Turns out i had to reorganize the code a bit.
I took the $row = $stmt->fetch(); out of the while loop, and checked the $row seperately. Like this:
$stmt = $dbh->prepare("SELECT realname FROM users WHERE name = :name" );
$stmt->bindParam(":name", $name);
$name = "mivuckovaca"; // NOT IN DATABSE ON PURPOSE
try {
$stmt->execute();
} catch(PDOException $e) {
echo "FATAL ERROR OCCURED:".$e->getMessage();
}
$res = $stmt->fetchAll(); # Replaced fetch() with fetchAll()
if(empty($res)) {
echo "User not found";
} else {
foreach($res as $row) { # replaced while() with foreach()
echo $row['realname'];
}
}

PDO Results to array

I moved over from plain MYSQL to PDO MYSQL and started using prepared statements. With my old system I was able to query the database and store the information in a array. I would then use usort to sort the table by money amount.
Since I've moved to PDO I'm having trouble using the array I get out of it. My origional code is as follows:
$sql = "SELECT name, item, cash, props FROM Donators";
$result = $conn->query($sql);
$result_array = array();
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
$result_array[] = $row;
//var_dump($result_array);
}
} else {
echo "You have yet to join our servers!";
}
$conn->close();
function custom_sort($a,$b) {
return $a['cash']<$b['cash'];
}
usort($result_array, "custom_sort");
This results in the table being sorted by the column 'cash'. The code below is from my PDO code.
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $conn->prepare("SELECT name, item, cash, props FROM Donators");
$stmt->execute();
// set the resulting array to associative
$result = $stmt->setFetchMode(PDO::FETCH_ASSOC);
$result_array = array();
foreach(new TableRows(new RecursiveArrayIterator($stmt->fetchAll())) as $k=>$v) {
$result_array[$k] = $v;
}
}
catch(PDOException $e) {
echo "Error: " . $e->getMessage();
}
$conn = null;
function custom_sort($a,$b) {
return $a['cash']<$b['cash'];
}
//print_r($result_array);
usort($result_array, "custom_sort");
$length = count($result_array);
usort will cause this error:
Warning: Illegal string offset 'cash'
Printing the array $result_array shows
Array ( [name] => Жэка90 [item] => none [cash] => 1000 [props] => 0 )
I use the following code:
// In case an error occured during statement execution, throw an exception
if (!$stmt->execute()) {
// Error handling with $stmt->errorInfo()
}
// Fetch all results
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
It doesn't need a foreach loop to process the data afterwards.
Changing the for loop to
foreach($stmt->fetchAll() as $k=>$v) {
Fixed this.

Getting MSSQL Stored Proc Results with PHP PDO

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.

Why does my code not retrieve/display the PDO record set?

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().

PHP & PDO: Can connect to DB; can't seem to query

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

Categories