I'm brand new to the PDO syntax and I'm liking the learning curve! I'm refactoring code - migrating over from archaic mysqli_* methods.
Predictably, I've run into some snags, being a novice. One of the big ones is (forgive if this is a dumb question) retrieving data from the DB and echoing it out on the page. Here is what I have so far:
$getURLid = $_GET['id'];
$idQuery = $connection->prepare("SELECT * FROM pages WHERE page_id = :getURLid");
$idQuery->execute(array(':getURLid' => $getURLid));
$idRetrieved = $idQuery->fetchAll(); // This is the part I'm unclear on.
When I echo $idRetrieved['value'] to the page, nothing shows up. I'm missing something or misunderstanding how it works. Maybe fetchAll isn't what I should be using.
If it is, is a loop necessary to retrieve all rows? I was under the impression that fetchAll would loop through them automatically based on what I've read.
Thanks for the help.
Read the doco for PDOStatement::fetchAll closely. It returns an array of row data.
The type of data representing each row depends on your fetch mode which by default is PDO::FETCH_BOTH. This would mean each row is an array with both numeric and associative keys. If you're only going to access the data associatively, I'd recommend using PDO::FETCH_ASSOC, eg
$idRetrieved = $idQuery->fetchAll(PDO::FETCH_ASSOC);
You would then either need to loop or access each row via its index, eg
foreach ($idRetrieved as $row) {
echo $row['value'];
}
// or
echo $idRetrieved[0]['value']; // assuming there's at least one row.
Related
I am new to php and mysqli and have been going through and trying to understand how a lot of these built in functions work. I have read the documentation and many tutorials/examples.
I have something like:
$conn = new mysqli(vars); <br />
$sql = "Select * from Users where name ='$name'";
$result = $conn->query($sql);
$pass = result->fetch_assoc()['Pass'];
//check password stuff
that works fine, however if I then try to use $result->fetch_assoc()['ID'] it returns null. If I swap the order of ID and Pass then the id returns and pass comes back null.
I don't understand why this is the case. What I think (which is clearly wrong) is that result should store the whole row (which it does) and then when i fetch assoc I should just be pulling data from the row. However it seems to be overwriting result when I fetch assoc. What's up with that?
My work around is to call the query multiple times for each data point i need to start a session and store variables, and I know I can use prepared statements, but I feel like there's a better way and I'm missing it.
Can someone please explain?
Every time you call fetch_assoc(), it fetches the next row. There'll presumably only be one user with a specific name, so the result of the second fetch_assoc() call will be null.
Store the value of $result->fetch_assoc() and you can do what you want with it afterwards.
$user = $result->fetch_assoc();
echo $user['ID'];
echo $user['Pass'];
In mySQL I have a table with 8 rows, id and status.
$make=mysql_query("SELECT id, status FROM data order by id");
My question is how can I avoid using the foreach or any loop to echo the data, but instead to ave something like
<?php echo $row['status with the id 5']; ?>
and in another place of the page to echo the status with id 8 ?
You can utilize the following pattern:
$contents = [];
foreach($results as $result) {
$contents[$result->id] = $result;
}
$results contains the MySQL result set. $contents will be the associative array. It would be more comfortable if you swapped that to a function or class which works for all the tables you want to access applying this pattern. Depending on which database class you use, it might be necessary to cast the key to an integer, otherwise there will be problems accessing the index if it is passed as a string.
Note that you furthermore should migrate your code to MySQLi or PDO first.
If your table is likely to become very big, you should not implement this. Instead, it would be better if you checked in the first place which entries will be needed and load those explicitly with an IN() query.
I'm using PHP and MySQLi and following a tutorial-type example and have some basic behavioral questions. A php code sample follows (hm, hope I format it correctly, 1st post here):
<?php
$db = new mysqli('hostLiteral', 'userLiteral', 'passwordLiteral', 'people');
$results = $db->query("SELECT * FROM people")
if($results->num_rows) {
while($row = $results->fetch_object()) {
$records[] = $row;
}
$results->free();
}
?>
I used a DBMS many, many years ago and perhaps it's that behavior that's keeping me from understanding this.
My perception is that when the 'SELECT * FROM people' is executed, MySQL would scan the entire database, get all the pertinent data, and end up 'pointing' at the last record in the database. So when the 'while' loop begins, I would think that's where it's starting, it would only get the last record or row and be done.
But even if it did somehow start at the top of the database at the first row, how does it know to move through the database unless 'fetch_object()' is somehow telling it to move to the next row?
I'm certain I'm missing basic SQL behavior here. But I've not found a good explanation to dispel these concepts that were placed in my head years back.
Thanks for any aid in understanding!
The query leaves the cursor pointing at the first row of your result set rather than the last. Since the general use case is to move forward through the rows, it would make little sense to leave the cursor at the last row.
In addition, fetch_object does exactly what you surmise. It gets the current row and advances the cursor to the next row. It's interesting that the documentation doesn't state that explicitly (like it does with fetch_row, but the example given makes it clear enough that that's what it does:
/* fetch associative array */
while ($obj = mysqli_fetch_object($result)) {
printf ("%s (%s)\n", $obj->Name, $obj->CountryCode);
}
I've read through PHP PDO Book and now have some basic questions:
If i understood correctly, i'll have to use begin_transaction() in order to turn off autocommit. If i am okay with autocommit, i am always good to go with a simple query()Is this correct?
Did i get it right, that there is basically no difference between query() and exec(), except of the above asked topic?
I made a query like this one:
foreach ($db->query('SELECT * from user') as $row) {
$row = json_encode($row);
echo $row;
}
Which returns a JSON Object:
{
"alias":"tk",
"0":"tk",
"password":"pw",
"1":"pw",
}
This is basically correct, however, why is each value returned twice, once with my chosen keyword and another time with an Integer key?
why is each value returned twice, once with my chosen keyword and another time with an Integer key?
The array has the values both with the column names as keys, and the column ordinals too. So you could access the values from the result set by using the number of which column you want. (of course, that does not seem to be of too much use with a select * statement...)
You can affect this behaviour with PDOStatement::setFetchMode(). The constants starting with PDO::FETCH_ are applicable here. Their documentation can be found here
I have a simple mySQL database table that I am loading into a PHP array. I would like the id column of the mySQL table (which is auto incremented, but I don't think that's relevant) to be the array key for each element of the PHP array, instead of the array being numeric.
Instead of this:
Array(
Array(id=>'1', field1=>someval, field2=>val),
Array(id=>'2', field1=>val, field2=>otherval),
Array(id=>'4', field1=>val, field2=>otherval)
)
I want this:
Array(
1=>Array(field1=>someval, field2=>val),
2=>Array(field1=>val, field2=>otherval),
4=>Array(field1=>val, field2=>otherval)
)
I don't care if id is left in the associative array for each row.
Is there a way to do this without looping through the original mySQL array and using up lots of processing time?
You can do it at the fetch time like this:
$query_ret = mysql_query(...);
$result = array();
while ($row = mysql_fetch_assoc($query_ret)) {
$result[array_shift($row)] = $row;
}
"Is there a way to do this without looping through the original mySQL array and using up lots of processing time?"
I believe the answer to this is no. The best you can do is to try to be as efficient as possible when looping through the array.
If you have PDO, you should definitely see Example #3 from the PDO documentation for fetchall: http://www.php.net/manual/en/pdostatement.fetchall.php#example-1022
Not only is this way more efficient use of your server's memory and processing power... it would also enable you to take advantage of several of PDO's other powerful APIs.