Hey guys im having a little trouble with the PDO in php as the error it is returning is an undefined index. The code for the function and query and return of result is this:
function getUserDetails($user) {
$db = connect();
try {
$stmt = $db->prepare('SELECT name,addr AS address,team
FROM TreasureHunt.Player LEFT OUTER JOIN TreasureHunt.MemberOf ON (name=player)
LEFT OUTER JOIN TreasureHunt.PlayerStats USING (player)
WHERE name=:user');
$stmt->bindValue(':user', $user, PDO::PARAM_STR);
$stmt->execute();
$results = $stmt->fetchAll();
$stmt->closeCursor();
} catch (PDOException $e) {
print "Error : " . $e->getMessage();
die();
}
return $results;
}
However when running the code for the index page i get an error that says Notice: Undefined index: name
The Code for the index is this:
try {
$details = getUserDetails($_SESSION['player']);
echo '<h2>Name</h2> ',$details['name'];
echo '<h2>Address</h2>',$details['address'];
echo '<h2>Current team</h2>',$details['team'];
echo '<h2>Hunts played</h2> ',$details['nhunts'];
echo '<h2>Badges</h2>';
foreach($details['badges'] as $badge) {
echo '<span class="badge" title="',$badge['desc'],'">',$badge['name'],'</span><br />';
}
} catch (Exception $e) {
echo 'Cannot get user details';
}
my question is why is it throwing a notice and how do i go around this problem?
fetchAll returns all results (potentially multiple rows) in a multidimensional array:
array(
0 => array(/* first row */),
1 => array(/* second row */),
...
)
That's why the array doesn't have a direct index 'name', it needs to be [0]['name'].
Or you shouldn't fetchAll, just fetch.
Related
I'm using a PDO driver to connect to a mySQL database. I have had luck querying this database when I search by ID; however, when I try to change the query from ID to first_name, I just get an error. Below is my code:
This code works
//functions.php file
function query_database($id) {
include("connection.php");
try {
$results = $db->query("SELECT first_name, last_name FROM master_tradesmen WHERE id = $id");
}catch(Exception $e) {
echo "Something went wrong with the query.";
}
$data = $results->fetch();
return $data;
}
$res = query_database(1);
print_r($res);
This returns:
Array ( [first_name] => Steve [0] => Steve [last_name] => Albertsen [1] => Albertsen )
So now, instead of searching by ID, I just want to search by first name. Here is the slightly altered code:
function query_database($name) {
include("connection.php");
try {
$results = $db->query("SELECT first_name, last_name FROM master_tradesmen WHERE first_name = $name");
}catch(Exception $e) {
echo "Something went wrong with the query.";
}
$data = $results->fetch();
return $data;
}
$res = query_database('Steve');
print_r($res);
This returns the following error:
Notice: Undefined variable: results in /home/locompre/public_html/php/functions.php on line 12
Fatal error: Uncaught Error: Call to a member function fetch() on null in /home/locompre/public_html/php/functions.php:12 Stack trace: #0 /home/locompre/public_html/php/functions.php(16): query_database('Steve') #1 {main} thrown in /home/locompre/public_html/php/functions.php on line 12
Any insight into why this might be happening?
You're open for SQL injections! The error happens because you initialize the variable result inside the try block. The variable isn't accessible outside the try-catch block if a error occurs, which is fact because strings need to be wrapped with single quotes in a SQL query!.
A better way to do it is:
function query_database($name) {
include("connection.php");
try {
$stmt = $db->prepare("SELECT first_name, last_name FROM master_tradesmen WHERE first_name = :name");
$stmt->bindValue(':name', $name);
$stmt->execute();
$data = $stmt->fetchAll();
return $data;
}catch(Exception $e) {
echo "Something went wrong with the query.\n<br>".
"Error: \n<br>" . $e->getMessage() . "\n<br>" .
"StackTrace: \n<br>" . $e->getTraceAsString();
return null;
}
}
$res = query_database('Steve');
print_r($res);
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.
I'd like to execute some queries that doesn't return result set, and then execute a real query, and fetch its result.
Here is an exemple that doesn't work :
<?php
try {
$db = new PDO('dblib:host=myhost;dbname=master','user','password');
$query = "declare #entier int = 1;";
$db->exec($query);
$query = "select #entier;";
$stmt = $db->query($query);
$rows = $stmt->fetchAll();
print_r($rows);
}
catch (PDOException $e) {
print ($e->getMessage());
}
catch (Exception $e) {
print ($e->getMessage());
}
?>
This code neither doesn't work :
try {
$db = new PDO('dblib:host=myhost;dbname=master','user','password');
$query = "declare #entier int = 1; select #entier;";
$stmt = $db->query($query);
$rows = $stmt->fetchAll();
print_r($rows);
}
catch (PDOException $e) {
print ($e->getMessage());
}
catch (Exception $e) {
print ($e->getMessage());
}
?>
But this code works :
<?php
try {
$db = new PDO('dblib:host=myhost;dbname=master','user','password');
$query = "select 1;";
$stmt = $db->query($query);
$rows = $stmt->fetchAll();
print_r($rows);
}
catch (PDOException $e) {
print ($e->getMessage());
}
catch (Exception $e) {
print ($e->getMessage());
}
?>
Thanks for your help
I know this is old, but for other people finding this from Google: you need to use PDOStatement::nextRowset to iterate over the result sets from your multiple queries.
However, it seems there are memory issues when using nextRowset with dblib in some versions (it tried to allocate 94Tb in my case...), so I ended up re-engineering to avoid multiple SQL queries altogether (instead duplicating the value of the DECLARE where it was being used).
PDO::query docs (http://php.net/manual/it/pdo.query.php) say
PDO::query() executes an SQL statement in a single function call, returning the result set (if any) returned by the statement as a PDOStatement object.
This could mean that you can execute with query() both queries with and without result
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.
Getting no results no matter how broad my query
PHP: 5.3
Sqlite3: 3.6
PDO: 5.3.3
I would think this should be a very simple process but even looking around I still don't know why I'm getting 0 results. Here is my code:
<?php
$sqlite = new PDO('sqlite:/example.db');
$result = $sqlite->query('SELECT * from foo');
if(!$result)
{
echo 'fail';
return false;
}
?>
Any ideas on what I am doing wrong? The 'foo' table will only have four columns, and this test db only has one table. Running the query in sqlite displays the results fine.
You have to execute the statement first than fetch the result.
You might add try/catch block around the execute method call. and do some error handling.
Here's an example of catching an Exception. Do not use it as a design guideline.
<?php
try
{
$sqlite = new PDO('sqlite:/example.db');
}
catch (PDOException $e)
{
echo 'Connection failed: ' . $e->getMessage();
}
$statement = $sqlite->prepare('SELECT * from foo');
try
{
$statement->execute();
}
catch(PDOException $e)
{
echo "Statement failed: " . $e->getMessage();
return false;
}
$result = $statement->fetchAll();
var_dump($result);
?>