How to batch a pdo loop - php

I am completely stumped how to do this. I want to perform a function per batch of 100 mysql results.
$stmt=$db->prepare("SELECT count(user) AS cnt, user FROM table");
$stmt->execute();
$row = $stmt->fetchAll();
foreach ($row AS $row) {
$user .= $row['user'];
}
function($user);
The trouble is I can't figure out how to stop the loop each 100, perform the function, then continue again until there are no more results.

$stmt=$db->query("SELECT user FROM table");
$i = 1;
foreach ($stmt as $row) {
$user .= $row['user'];
if ($i++ == 100) {
function($user);
$i = 1;
}
}
function($user);

Related

Get batch by batch about 70K of data

I need to get about 70.000 lines from database and I want to get batch by batch but like I did I get only some lines :
$sql = "SELECT COUNT(*) as num FROM ".self::TABLE_NAME;
$stmt = Db::get()->prepare($sql);
$stmt->execute();
$results = $stmt->fetch();
$batches = $results['num'] / 1000;
$limit = 0;
for ($i = 0; $i <= $batches; $i++) {
$offset = $i * 1000;
$sql = "SELECT * FROM ".self::TABLE_NAME." LIMIT $limit,$offset";
$stmt = Db::get()->prepare($sql);
$stmt->execute();
$results = $stmt->fetchAll();
foreach ($results as $result) {
echo $result['supplierName'].PHP_EOL;
}
$limit+=1000;
}
Have you an idea ? Thx in advance.

How do I display content with PDO based on num_rows?

Apparently, the num_rows property does not work in PDO as it would with mysqli.
Normally, with mysqli, my code would look like this:
<?php
$conn = new mysqli('127.0.0.1','root','mypassword','mydbname');
if($conn->connect_errno){
die("Sorry, could not connect.");
}
$id = 1;
$qry = "SELECT * FROM customers WHERE id = ?";
$getCustomers = $conn->prepare($qry);
$getCustomers->bind_param("i",$id);
$getCustomers->execute();
$result = $getCustomers->get_result();
$count = $result->num_rows;
if($count == 0){
echo "Sorry, there are no results";
}else{
while($row = $result->fetch_object()){
echo $row->id;
echo $row->fname;
echo $row->lname;
echo $row->entry_date;
}
}
?>
How do I create the equivalent with PDO? Here is what I have tried so far:
<?php
try{
$conn = new PDO('mysql:host=127.0.0.1;dbname=mydbname','root','mypassword');
}catch(PDOException $e){
echo $e;
}
$id = 1;
$qry = $conn->prepare("SELECT * FROM customers WHERE id = :id");
$qry->execute([':id'=>$id]);
$rows = $qry->fetchAll(PDO::FETCH_OBJ);
$count = count($rows);
if($count == 0){
echo "Sorry, there are no results for your criteria";
}else{
for($i = 0; $i < $count; $i++){
echo $rows->fname;
}
}
?>
Yeah isn't PDO great ;p no need to count rows when you have already got them.
To loop over your result as you have an array.
Change:
for ($i = 0; $i < $count; $i++){
echo $rows->fname;
}
To:
for ($i = 0; $i < $count; $i++){
echo $rows[$i]->fname;
}
Or better just use a foreach.
foreach ($rows as $row) {
echo $row->fname;
}
The statement
fetchAll(PDO::FETCH_OBJ) returns an array containing all of the result set rows as described here. To get the size of the array use sizeof($count). That should give you the size of the array.
To answer your question specifically. You can use rowCount() to retrieve the number of rows in a result:
$qry = $conn->prepare("SELECT * FROM customers WHERE id = :id");
$qry->execute([':id'=>$id]);
$count = $qry->rowCount();
$rows = $qry->fetchAll(PDO::FETCH_ASSOC); //my personal preference
for($i=0; $i < $count; $i++) {
echo $rows[$i]['fname'];
}
To more closely replicate your mysqli code:
while($row = $qry->fetch(PDO::FETCH_OBJ) {
echo $row->fname;
}
Of course, you should always check $conn->errorCode() after each database execution to ensure something go sideways on you.
UPDATE:
As Lawrence points out, rowCount() does not work with MS SQL Server. An alternative in that case is to use fetchAll() and count().

Get the number of rows affected by multiple delete

How can I get a count of the number of affected rows when I'm deleting multiple rows in PDO? This is the technique I'm using to delete multiple rows:
$selected = $_POST['checkbox'];
$N = count($selected);
for ($i = 0; $i < $N; $i++) {
$result = $dbh->prepare('DELETE FROM users WHERE id= :id');
$result->bindParam(':id', $selected[$i], PDO::PARAM_INT);
$result->execute();
}
I tried this, but it always returned 1:
$deleted = $result->rowCount();
if ($deleted) {
echo $deleted.' was deleted.';
}
You're running a loop, so each call is deleting 1; you need to add a counter.
So add:
$deleted += $result->rowCount();
inside the loop
and then outside:
if ($deleted) {
echo $deleted.' was deleted.';
}
If the id field is unique, then that statement could affect at most 1 row. However you are preparing a new statement and executing it in a loop. You should try adding up how many you delete.
$deleted = 0;
for ($i = 0; $i < $N; $i++) {
$result = $dbh->prepare('DELETE FROM users WHERE id= :id');
$result->bindParam(':id', $selected[$i], PDO::PARAM_INT);
$result->execute();
$deleted = $deleted + $result->rowCount();
}
echo $deleted.' was deleted.';
Here's a way to do it in 1 delete instead of running multiple deletes.
This way rowCount() will show the actual results deleted.
$selected = $_POST['checkbox'];
$placeholder = array();
$values = array();
foreach ($selected as $id) {
$placeholder[] = ":".$id;
$values[":".$id] = $id;
}
$sql = "Delete FROM users WHERE id IN (".implode(', ',$placeholder).") ";
$result = $dbh->prepare($sql);
$result->execute($values);
$deleted = $result->rowCount();
if ($deleted>0) {
echo $deleted.' was deleted.';
}

PHP PDO only fetch 1 row

I want to fetch all the rows of a table but it only echos 1 row. (The latest)
Tried much but nothing worked for me. Tried answers on stackoverflow but it is not working.
Here is the code that i use to fetch the rows:
$stmt = $pdo->prepare("SELECT * FROM admin");
$stmt->execute();
$result = $stmt->fetchAll();
foreach ($result as $row) {
$gebruikersnaam = $row['gebruikersnaam'];
$wachtwoord = $row['wachtwoord'];
}
Hope that anyone can help me with this.
I want to fetch all the rows of a table but it only echos 1 row. (The latest)
foreach ($result as $row) {
$gebruikersnaam = $row['gebruikersnaam'];
$wachtwoord = $row['wachtwoord'];
}
I can bet 5 dollars on the assumption that you are using those variables outside the loop :) That's why you only see the last row's data. Either remove fetchAll() and fetch() them one by one or manipulate your variables within the loop so you get new values for every row.
Try this and you will know what i mean
foreach ($result as $row) {
print_r($row);
}
$stmt = $pdo->prepare("SELECT * FROM admin");
$stmt->execute();
$result = $stmt->fetchAll();
$count = $stmt->rowCount();
for ($i=0; $i < $count; $i++) {
$gebruikersnaam = $result[$i]['gebruikersnaam'];
$wachtwoord = $result[$i]['wachtwoord'];
echo 'Gebruikersnaam is : '.$gebruikersnaam.'<br/>';
echo 'Wachtwoord is : '.$wachtwoord.'<br/>';
}
Or if you want to use foreach:
$stmt = $pdo->prepare("SELECT * FROM admin");
$stmt->execute();
$result = $stmt->fetchAll();
foreach ($result as $row) {
$gebruikersnaam .= $row['gebruikersnaam'];
$wachtwoord .= $row['wachtwoord'];
}
echo 'Gebruikersnamen zijn : '.$gebruikersnaam.'<br/>';
echo 'Wachtwoorden zijn : '.$wachtwoord.'<br/>';
you have to style it al little bit because it'll stick them all together.

Trouble with updating table with arrays

After being stuck trying to get a grip of how this works, i've decided to ask for some hints to how I can do this.
Let me start by saying I have next to no experience with anything like this. I've just gathered some logic by looking at the code and i'm almost done with my project, except for this issue that i've come by.
This is the original code (which i am still using another place in the code, this appears to be working just fine).
function showCart() {
global $db;
$cart = $_SESSION['cart'];
if ($cart) {
$items = explode(',',$cart);
$contents = array();
foreach ($items as $item) {
$contents[$item] = (isset($contents[$item])) ? $contents[$item] + 1 : 1;
}
$output[] = '<form action="kurv.php?action=update" method="post" id="cart">';
$output[] = '<table>';
foreach ($contents as $id=>$qty) {
$sql = 'SELECT * FROM varetabel WHERE varenr = '.$id;
$result = $db->query($sql);
$row = $result->fetch();
extract($row);
$output[] = '<tr>';
$output[] = '<td>Slet</td>';
$output[] = '<td>'.$varenavn.'</td>';
$output[] = '<td>DKK '.$pris.'</td>';
$output[] = '<td><input type="text" name="qty'.$id.'" value="'.$qty.'" size="3" maxlength="3" /></td>';
$output[] = '<td>DKK '.($pris * $qty).'</td>';
$total += $pris * $qty;
$output[] = '</tr>';
$_SESSION['items'] = $contents; // Antal forskellige varer.
$_SESSION['qty'] = $qty;
}
$output[] = '</table>';
$output[] = '<p>Pris total: <strong>DKK '.$total.'</strong></p>';
$output[] = '<div><button type="submit">Opdatér kurv</button></div>';
$output[] = '</form>';
} else {
$output[] = '<p>Kurven er tom.</p>';
}
return join('',$output);
}
global $db is connecting to the DB and such, no biggie, and then there is this function from an include:
function fetch () {
if ( $row=mysql_fetch_array($this->query,MYSQL_ASSOC) ) {
return $row;
} else if ( $this->size() > 0 ) {
mysql_data_seek($this->query,0);
return false;
} else {
return false;
}
}
Now, im trying to use the same method to take the arrays from this code and put them into my database with this code:
session_start();
global $db;
$items = $_SESSION['items'];
$cart = $_SESSION['cart'];
$qty = $_SESSION['qty'];
if(isset($_SESSION['email'])) { // IF LOGGED IN
$sql = mysql_query("SELECT * FROM antalstabel ORDER BY ordrenr DESC LIMIT 1") or die(mysql_error());
$row = mysql_fetch_assoc($sql);
$maxordrenr = $row['ordrenr'];
$nextnumber = $maxordrenr + 1;
$antal = count($items); // COUNTS DIFFERENT ITEMS IN CART.
$maxplusantal = $maxordrenr + $antal;
$varenrplaceholder = 0;
for ($i = $maxordrenr; $i <= $maxplusantal; $i++) {
$sql = mysql_query("INSERT INTO antalstabel (ordrenr, varenr) VALUES ('$nextnumber','$varenrplaceholder')") or die(mysql_error());
$nextnumber--;
$varenrplaceholder++;
}
$varenrplaceholder = 0;
if ($cart) {
$items = explode(',',$cart);
$contents = array();
foreach ($items as $item) {
$contents[$item] = (isset($contents[$item])) ? $contents[$item] + 1 : 1;
}
foreach ($contents as $id=>$qty) {
$sql = 'UPDATE antalstabel SET varenr = '.$id.' and antal = '.$qty.' WHERE ordrenr = '.$nextnumber.' and varenr = '.$varenrplaceholder.'';
$result = $db->query($sql);
$row = $result->fetch();
extract($row);
$varenrplaceholder++;
}
}
But it does not appear to be working properly, the code does run, but it does not update the tabel with the values of the arrays.
Am i completely wrong or can anyone help me with this issue, i know it is a lot to ask.
my own code creates X rows with the same ID depending on how many different items there is in the cart, I am trying to update those existing rows that i've just created with the values i presume is still in the arrays of the showCart() function.
Thank you in advance
$sql = 'SELECT * FROM varetabel WHERE varenr = '.$id;
$result = $db->query($sql);
You aren't checking the success/failure status returned by query(). Most of the MySQL functions return false if there's an error, for example a misspelled table name or an invalid expression in the WHERE clause.
I don't know what $id is, but you should inspect the $sql string to see if it works (copy & paste it into a mysql client session to test it).
And you should always check that $result is not false. See http://php.net/mysql_error
there is error at your code line
foreach ($contents as $id=>$qty) {
$sql = 'UPDATE antalstabel SET varenr = '.$id.',antal = '.$qty.' WHERE ordrenr = '.$nextnumber.' and varenr = '.$varenrplaceholder.'';
$varenrplaceholder++;
}
$select_query='SELECT * FROM varetabel WHERE varenr = '.$id;
$result = $db->query($select_query);
$row = $result->fetch();
extract($row);
You appear to be creating a lot of dummy records, then going through an updating them. I would expect you to have just needed to do the insert, but wondering if this is something to do with the fetch you do after the update.
However the main thing that I suspect stops you query working is that you count the number of $items before you have set $items to the exploded $cart.
I have done the following, using assumed names for the methods in your db class
<?php
session_start();
global $db;
$items = $_SESSION['items'];
$cart = $_SESSION['cart'];
$qty = $_SESSION['qty'];
if(isset($_SESSION['email']))
{ // IF LOGGED IN
if ($cart)
{
$sql = "SELECT MAX(ordrenr) AS ordrenr FROM antalstabel";
$result = $db->query($sql) or die($db->error());
if ($row = $result->fetch())
{
$maxordrenr = $row['ordrenr'];
$nextnumber = $maxordrenr + 1;
$items = explode(',',$cart);
$antal = count($items); // COUNTS DIFFERENT ITEMS IN CART.
$maxplusantal = $maxordrenr + $antal;
$varenrplaceholder = 0;
for ($i = $maxordrenr; $i <= $maxplusantal; $i++)
{
$sql = "INSERT INTO antalstabel (ordrenr, varenr) VALUES ('$nextnumber','$varenrplaceholder')";
$db->query($sql) or die($db->error());
$varenrplaceholder++;
}
$varenrplaceholder = 0;
$contents = array();
foreach ($items as $item)
{
$contents[$item] = (isset($contents[$item])) ? $contents[$item] + 1 : 1;
}
foreach ($contents as $id=>$qty)
{
$sql = "UPDATE antalstabel SET varenr = $id and antal = $qty WHERE ordrenr = $nextnumber and varenr = $varenrplaceholder";
$result = $db->query($sql) or die($db->error());
$row = $result->fetch();
extract($row);
$varenrplaceholder++;
}
}
}
}
?>

Categories