pdo fetch within a fetch error - php

I am trying to run the following script (unsuccessfully):
$variables = $db->query("SELECT * FROM table1 WHERE Session_ID = '$sess1'");
while($row = $variables->fetch()) {
//FETCH DATA
$id= $row["ID"];
$info = $db->query("SELECT * FROM table2 WHERE ID = $id");
while($row2 = $info->fetch()) {
$name = $row2["FNAME"]." ".$row2["LNAME"]; }
$phone = $row2["PHONE"];
}
//SEND CUSTOMER EMAIL
require("../email/email.php");
}
this returns the error: Fatal error: Call to a member function fetch() on a non-object in...
While I am able to "solve" the problem, it is ugly. Essentially I have to make several calls ahead of the one I'm trying below (which in theory should work).
Any ideas?

As far as I can tell, you have to fetch all results from a resultset before you can issue a new query. If you're using MySQL, you can circumvent that by calling $db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY,true);, but I would advice against it, as it makes your code less portable, and on of the major plusses of PDO, database-abstraction, is lost.

try this instead
//prepare the query
$variables = $db->prepare("SELECT * FROM table1 WHERE Session_ID = :sess1");
$info = $db->prepare("SELECT * FROM table2 WHERE ID = :ID");
//bind the variable :sess1 to $sess1
$variables->bindParam(':sess1', $sess1, PDO::PARAM_STR);
//execute the query
$variables->execute;
//fetch the result
$result = $variables->fetch(PDO::FETCH_ASSOC);
//set $result['ID'] to a variable and bind it to the variable :ID in our second query
$id = $result['ID'];
$info->bindParam(':ID', $id, PDO::PARAM_INT);
while($row2 = $info->fetch()) {
$name = $row2["FNAME"]." ".$row2["LNAME"]; }
$phone = $row2["PHONE"];
}
//SEND CUSTOMER EMAIL
require("../email/email.php");
}

Related

SQL statement works separately, but together it won't

I am trying to fetch user
function getItemName($dbh, $userId) {
$itemId = getItemId($dbh, $userId); // the getItemId() function works
echo "item id is: " . $itemId ; // because I can see the correct result if I echo it
$sql = "SELECT name FROM items WHERE id = :item_id";
$stm = $dbh->prepare($sql);
$stm->bindParam(':item_id', $itemId, PDO::PARAM_INT);
$stm->execute();
$result = $stm->fetch();
return $result['name'];
}
And I get Trying to access array offset on value of type bool on the return $result['name']; line.
The field name exists on the items table so that's not the issue.
Also, when I try to further test it, I change the $sql statement to SELECT * FROM items and then when I do echo $stm->rowCount() it finds the correct number of rows (With the original SQL statement row count is 0)
Can't find out what's causing this
I have 3 suggestions:
Make sure to convert $itemId to integer using intval();
Just before returning the function result validate that the query returned results.
$result = $stm->fetch();
if(!$result){
return null;
}
return $result['name'];
Finally, the more obvious, make sure the itemId you are looking for exists in the DB.

mysqli_query while loop to PDO

I am trying to upgrade my way to fetch data from sql from mysqli_query to fetchall.
$res = mysqli_query($db, "SELECT * FROM forum_index WHERE forum_over='yes'");
while ($arr = mysqli_fetch_assoc($res)) {
......
}
So when I use fetchAll() I'll get an array, Am I supposed to use foreach() then or is there a smarter way of doing this?
And to collect a single value from the DB this is the right way right?
$fid = (int)$_GET['id'];
$thread = $db->query("SELECT * FROM forum_threads WHERE f_id=".$fid)->fetch_array();
echo $thread['id'];
You don't need to use fetchAll() just because you're using PDO. If the query returns a large amount of data, this could slow things down because it has to collect it all into memory. You can use the same kind of loop as in your mysqli code:
$res = $pdo->query("SELECT * FROM forum_index WHERE forum_over='yes'");
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
...
}
As to your second question, you should use a parametrized query, not substitute variables.
$stmt = $pdo->prepare("SELECT * FROM forum_threads WHERE f_id= :id");
$stmt->bindParam(':id', $_GET['id']);
$stmt->execute();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
...
}

how grab field value from a PHP query (PDO)

Super new to PHP here, only using PHP to create my json data and having a hard time to understand the syntax. Here is some partial code:
All I am trying to do is to retrieve the value '2af8ddda-2be4-11e5-9453-b82a72d52c35' and put it in variable #sharepointID:
function selectWithSharepointID($table, $columns, $where){
try{
//Get Sharepoint file ID first
$stmt = $this->db->prepare("SELECT ID FROM table1 ORDER BY DownloadedTimeStamp DESC LIMIT 1");
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
//$data[] = array("ID" => $rows['ID']);
//$sharepointID = $data[0];
//$sharepointID = $rows[0];
$where = array('id'=>$sharepointID);
//$where = array('id'=>'2af8ddda-2be4-11e5-9453-b82a72d52c35'); //this works fine
...
PS: also tried to use print_r and echo but cant see anything in the console.
Thank you
You don't need to fetchAll if you only have one record. Try:
$stmt = $this->db->prepare("SELECT ID FROM table1 ORDER BY DownloadedTimeStamp DESC LIMIT 1");
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$sharepointID = $row['ID'];
If you have multiple records the fetchAll makes sense but then you iterate through that to get each row, and its values.
For a rough example where I'd use fetchAll...
$stmt = $this->db->prepare("SELECT name, userid FROM users");
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach($rows as $row){
echo 'Name: ' . $row['name'] . ' userid :' . $row['id'];
}
This expression returns array of rows:
$stmt->fetchAll(PDO::FETCH_ASSOC);
So, you can get data from row 0 in your case:
$sharepointID = $rows[0]['ID'];

Prepared statement LIKE wildcard

I've made a function that accepts a search column, search term and an id number, and am trying to construct a prepared statement and fetch results, and return in json.
Here is what I have:
function searchBooks($searchColumn, $searchTerm, $teacherid) {
$books = array();
$link = connect_db();
$sql = "SELECT * FROM book WHERE teacher_id = ? AND ? LIKE ?";
$searchTerm = "%{$searchTerm}%";
$stmt = $link->stmt_init();
$stmt->prepare($sql);
$stmt->bind_param('iss', $teacherid, $searchColumn, $searchTerm);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_array(MYSQLI_BOTH)) {
$book = new Book();
$book->id = $row['id'];
$book->title = $row['title'];
$book->author = $row['author'];
$book->ar_quiz = $row['ar_quiz'];
$book->ar_quiz_pts = $row['ar_quiz_pts'];
$book->book_level = $row['book_level'];
$book->type = $row['type'];
$book->teacher_id = $row['teacher_id'];
array_push($books, $book);
}
mysqli_stmt_close($stmt);
return json_encode($books);
}
I'm using a test page that passes values that I know should return results (using 'the' as a wildcard and 'title' for search column):
echo searchBooks('title', 'the', 1);
...but I am not getting any results at all... [] output on the test page.
Assume connect_db() retrieves a connection. Assume I'm doing all my error checking and everything in my controller level, and might add stuff like that later. Just trying to get results right now. Thanks in advance for anything you can point out.
searchcolumn cannot be a bind variable. You can't bind table/column names
$sql = sprintf("SELECT * FROM `book` WHERE teacher_id = ? AND `%s` LIKE ?", $searchColumn);
$searchTerm = "%{$searchTerm}%";
$stmt = $link->stmt_init();
$stmt->prepare($sql);
$stmt->bind_param('is', $teacherid, $searchTerm);
It would also be a good idea to whitelist $searchColumn, validating that it really is a column in your book table before executing this
EDIT
And why bother using fetch_array(MYSQLI_BOTH) when you're only using associative values from the array? Using fetch_assoc() would be better, or you could be even cleverer, and use fetch_object(), and then you wouldn't need to populate your Book object property by property
Consider:
while ($book = $result->fetch_object('Book')) {
array_push($books, $book);
}

How to insert where condition in mysql query

I will pass the query into this function query("SELECT * FROM table_name");
And the function is
public function query($sql) {
$resource = mysql_query($sql, $this->link_web);
if ($resource) {
if (is_resource($resource)) {
$i = 0;
$data = array();
while ($result = mysql_fetch_assoc($resource)) {
$data[$i] = $result;
$i++;
}
mysql_free_result($resource);
$query = new stdClass();
$query->row = isset($data[0]) ? $data[0] : array();
$query->rows = $data;
$query->num_rows = $i;
unset($data);
return $query;
} else {
return true;
}
} else {
trigger_error('Error: ' . mysql_error($this->link_web) . '<br />Error No: ' . mysql_errno($this->link_web) . '<br />' . $sql);
exit();
}
}
I want to add tenent_id = '1' in SELECT query also for INSERT query. Likewise I need to do it for UPDATE.
I want to bring the query like this
SELECT * FROM table_name WHERE tenent_id = 1 and user_id = 1
INSERT INTO table_name('tenant_id, user_id') VALUE('1','1')
UPDATE table_name SET user_id = 1 WHERE tenant_id = '1'
Can anyone give me the idea about how to insert tenant_id in select, insert and update
Thanks in advance
It's better practice to use the correct mysql functions rather than just a query function.
For example, if you want to cycle through many items in a database, you can use a while loop:
$query = mysql_query("SELECT * FROM table WHERE type='2'");
while($row = mysql_fetch_array($query)){
echo $line['id'];
}
This would echo all the IDs in the database that have the type 2.
The same principle is when you have an object, using mysql functions, you can specify how you want the data to return. Above I returned it in an array. Here I am going to return a single row as an object:
$query = mysql_query("SELECT * FROM table WHERE id='1'");
$object = mysql_fetch_object($query);
echo $object->id;
echo $object->type;
echo $object->*ANY COLUMN*;
This would return as:
1.
2.
Whatever the value for that column is.
To insert your data, you don't need to do "query()". You can simple use mysql_query($sql).
It will make life much easier further down the road.
Also, its best to run one query in a function, that way you can handle the data properly.
mysql_query("INSERT...");
mysql_query("UPDATE...");
mysql_query("SELECT...");
Hope this helps.
The simple answer is: just add the condition to your query. Call query("SELECT * FROM table_name WHERE tenant_id = 1 and user_id = 1").
If you're concerned about escaping the parameters you pass to the SQL query (which you should be!), you can either do it yourself manually, e.g.
$query = sprintf("SELECT * FROM table_name WHERE tenant_id = %d", intval($tenant_id));
query($query);
Or better use prepared statement offered by mysqli extension (mysql_query is deprecated anyway):
$stmt = $mysqli->prepare("SELECT * FROM table_name WHERE tenant_id = ?");
$stmt->bind_param("i", $tenant_id);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
// ...
}
If I still haven't answered your question, you can use a library to handle your queries, such as dibi:
$result = dibi::query('SELECT * FROM [table_name] WHERE [tenant_id] = %i', $id);
$rows = $result->fetchAll(); // all rows
The last option is what I would use, you don't need to write your own query-handling functions and get query parameter binding for free. In your case, you may utilize building the query gradually, so that the WHERE condition is not part of your basic query:
$query[] = 'SELECT * FROM table_name';
if ($tenant_id){
array_push($query, 'WHERE tenant_id=%d', $tenant_id);
}
$result = dibi::query($query);

Categories