Php pdo foreach - php

Here I have php pdo function to get json from database
try {
$conn = new PDO("mysql:host=localhost;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$result = $conn->prepare("SELECT id_tabele,naziv FROM track_aktivnosti WHERE prvi=:prvi AND id_akt=:id_akt AND tabela=:tabela");
$result->execute(array(':prvi' => $_POST['prvi'], ':id_akt' => $_POST['id_akt'], ':tabela' => $_POST['tabela']));
$result = $result->fetchAll();
foreach($result as $r) {
$temp = array();
$temp[] = array('id' => (int) $r['id_tabele'], 'ime_prezime' => (string) $r['naziv']);
}
$table = $temp;
$jsonTable = json_encode($table);
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
echo $jsonTable;
but I get just one result, one element in json etc.
[{"id":1,"ime_prezime":"Pera Peric"}]
other element I can't get. WHY?
I must get json like this:
[{"id":1,"ime_prezime":"Pera Peric"},[{"id":2,"ime_prezime":"Laza Lazic"}] ]
but I get only 1.st element and other not ...

You are overwriting the array inside the foreach on each iteration. This essentially means that the array is emptied on each iteration. The array will only contain the values from the last iteration. Move the $temp = array(); declaration outside the loop to fix this:
$temp = array(); // intialize the array
foreach($result as $r) {
$temp[] = array(
'id' => (int) $r['id_tabele'],
'ime_prezime' => (string) $r['naziv']
);
}
The above fix will make your code work, but I recommend using the approach using SQL aliases as shown in #YourCommonSense's answer below.

You are doing a whole lot of useless operations. It's no wonder why you got lost.
$conn = new PDO("mysql:host=localhost;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
$sql = "SELECT id_tabele id, naziv ime_prezime FROM track_aktivnosti
WHERE prvi=? AND id_akt=? AND tabela=?";
$stmt = $conn->prepare($sql);
$stmt->execute(array($_POST['prvi'], $_POST['id_akt'], $_POST['tabela']));
echo json_encode($result->fetchAll());

declare
$temp = array();
out side the loop since you have this inside the loop and on each iteration its declared as new array and previous entries are wiped.
i.e.
$temp = array();
foreach($result as $r) {
$temp[] = array('id' => (int) $r['id_tabele'], 'ime_prezime' => (string) $r['naziv']);
}

Related

Construct http_build_query with PDO and Select

I am trying to create an http_build_query array but it is inserting some diferent characters, this is my Code:
function Conectar(){
try{
$opcoes = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES UTF8');
$con = new PDO("mysql:host=localhost; dbname=*****;", "*****", "*****", $opcoes);
$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $con;
} catch (Exception $e){
echo 'Erro: '.$e->getMessage();
return null;
}
}
$pdo = Conectar();
$sql = "
SELECT dominio
FROM dominios_extraidos
WHERE verificado='0' LIMIT 3
";
$stm = $pdo->prepare($sql);
$stm->execute();
while ($rows = $stm->fetch()) {
$query = http_build_query(array(
'domains' => array(
''.$rows['dominio'].'',
)
));
print_r($query);
}
Creating this output:
domains%5B0%5D=0002021web.com.br%0Adomains%5B0%5D=007import.com.br%0Adomains%5B0%5D=00pet.com.br%0A
But this is my desire output:
domains%5B0%5D=0002021web.com.br&domains%5B1%5D=007import.com.br&domains%5B2%5D=00pet.com.br
My desire output could be generated manually using this code:
$query = http_build_query(array(
'domains' => array(
'0002021web.com.br',
'007import.com.br',
'00pet.com.br',
)
));
print_r($query);
Thank you for your time :)
You want to build up your array properly first, so that it looks like your manual array, then use http_build_query:
$domains = ['domains' => []];
while ($rows = $stm->fetch()) {
$domains['domains'][] = trim($rows['dominio']);
}
$query = http_build_query($domains);
print_r($query);
Create an array of domains in the loop and then after the loop is complete pass it as a param to the http_build_query().
while ($rows = $stm->fetch()) {
$doms[] = trim($rows['dominio']);
}
$query = http_build_query( ['domains' => $doms] );
print_r($query);
This will produce
domains%5B0%5D=0002021web.com.br%0A&domains%5B1%5D=007import.com.br%0A&domains%5B2%5D=00pet.com.br%0A
which equates to
domains[0]=0002021web.com.br
&domains[1]=007import.com.br
&domains[2]=00pet.com.br
0A decoded is \n or Line Feed;
perhaps try sanitizing first with
$query= trim($query, "\x00..\x20\x7F");
this code remove ASCII character from 00 to 20 hex and 7f hex

Foreach loop only showing last item in array in api

I am making a CRUD API for my android app, all this API needs to do is check the database for information regarding an indeterminate incoming user ID's and return the query results to the app(the R in CRUD). I have gotten the API to query and output both single item arrays and the last Item in the array.
my code:
$jsonobj = '{"code":"ascaasease","code":"ascaesease","code":"onetoelevn"}';
//mock json
$obj = json_decode($jsonobj);
foreach($obj as $key => $value) {
$sql = "SELECT code, header, body FROM `messages` WHERE code= '$value'";
$result = mysqli_query($conn, $sql);
if (mysqli_num_rows($result) > 0) {
while($row = mysqli_fetch_assoc($result)) {
$response['code'] = $row["code"];
$response['header'] = $row["header"];
$response['body'] = $row["body"];
$array_push[] = $response;
}
}
mysqli_close($conn);
}
$return = array("resoponse"=>array("check"=>"check"),"array"=>$array_push);
echo json_encode($return);
in this configuration, it will just output the final item in the array ("code","onetoelevn"). If the formating is dropped, and you tell the script to just echo the response it still only displays the last item in the array.
if you could tell me how to run an SQL query on each item in the array I would be very thankful.
First of all, your mock JSON is broken. It contains repeated properties.
If you must use a loop (which you don't have to) you can prepare the statement before the loop and execute within. Then use get_result() and fetch_all() to get the data.
mysqli
//mysqli connection
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$conn = new mysqli('localhost', 'user', 'password', 'db_name');
$conn->set_charset('utf8mb4'); // always set the charset
$jsonobj = '[ "ascaasease", "onetoelevn"]';
//mock json
$obj = json_decode($jsonobj);
$stmt = $conn->prepare('SELECT code, header, body FROM messages WHERE code=?');
$stmt->bind_param('s', $value);
$array_push = [];
foreach ($obj as $key => $value) {
$stmt->execute();
$data = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
$array_push = array_merge($array_push, $data);
}
$return = array("resoponse" => array("check" => "check"), "array" => $array_push);
echo json_encode($return);
If you don't have to use a loop, then you can use WHERE IN()
$jsonobj = '[ "ascaasease", "onetoelevn"]';
//mock json
$obj = json_decode($jsonobj);
$wherein = str_repeat(',?', count($obj) - 1);
$stmt = $conn->prepare("SELECT code, header, body FROM messages WHERE code IN(? $wherein )");
$stmt->bind_param(str_repeat('s', count($obj)), ...$obj);
$stmt->execute();
$array_push = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
$return = array("resoponse" => array("check" => "check"), "array" => $array_push);
echo json_encode($return);
PDO
Of course, all of this would be simpler if you were using PDO. If it is not too late, can you consider switching over to PDO instead of using mysqli?
Option 1:
// PDO connection
$pdo = new PDO("mysql:host=localhost;dbname=db_name;charset=utf8mb4", 'user', 'password', [
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_EMULATE_PREPARES => false
]);
$jsonobj = '[ "ascaasease", "onetoelevn"]';
//mock json
$obj = json_decode($jsonobj);
$stmt = $pdo->prepare('SELECT code, header, body FROM messages WHERE code=?');
$array_push = [];
foreach ($obj as $key => $value) {
$stmt->execute([$value]);
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
$array_push = array_merge($array_push, $data);
}
$return = array("resoponse" => array("check" => "check"), "array" => $array_push);
echo json_encode($return);
Option 2:
$jsonobj = '[ "ascaasease", "onetoelevn"]';
//mock json
$obj = json_decode($jsonobj);
$wherein = str_repeat(',?', count($obj) - 1);
$stmt = $pdo->prepare("SELECT code, header, body FROM messages WHERE code IN(? $wherein )");
$stmt->execute($obj);
$array_push = $stmt->fetchAll(PDO::FETCH_ASSOC);
$return = array("resoponse" => array("check" => "check"), "array" => $array_push);
echo json_encode($return);

Add query results to arrary PDO

I am trying to add query results to an array. My while statement works but I am not getting anything in my array. Here is my code:
$res=$pdo->query("select * from questions where category_id='$category' ORDER BY RAND()");
$rows = $res->rowCount();
if ($rows < 1){
echo "There is no question in the database";
exit();}
$questionsArray = array();
while ($item = $res->fetch(PDO::FETCH_ASSOC)){
$questionsArray[] = $item;
echo "There should be some info here<br>";
}
You might want to consider something like this, with thru PDO prepared statements.
Also, a while loop with a fetch is bad and slow and was good 15 years ago with MySQL.
Here is the proper way to do it.
define("SQLHOST", "127.0.0.1");
define("SQLUSER", "user");
define("SQLPASS", "password");
define("SQLSGBD", "database");
try {
$con = new PDO('mysql:host=' . SQLHOST . ';dbname=' . SQLSGBD . ';charset=UTF8', SQLUSER, SQLPASS);
$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
var_dump('Connection failed: ' . $e->getMessage());
}
$categories = ['A', 'B', 'C'];
$questionsArray = array();
$stmt = $con->prepare("select * from questions where category_id=? ORDER BY RAND()");
foreach ($categories as $key => $cat) {
$stmt->bindParam(1, $cat, PDO::PARAM_STR);
$stmt->execute();
$obj = $stmt->fetchall(PDO::FETCH_ASSOC);
if (count($obj) !== 0) {
foreach ($obj as $key2 => $item) {
$questionsArray[] = [$cat => $item];
}
}
}

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.

returning multiple rows from mysql in php

I'm trying to write a PHP-script that will fetch multiple rows from MySQL and return them as a JSONObject, the code works if I try to only fetch 1 row but if I try to get more than one at a time the return string is empty.
$i = mysql_query("select * from database where id = '$v1'", $con);
$temp = 2;
while($row = mysql_fetch_assoc($i)) {
$r[$temp] = $row;
//$temp = $temp +1;
}
If I write the code like this it returns what I expect it to, but if I remove the // from the second row in the while loop it will return nothing. Can anyone explain why this is and what I should do to solve it?
You are using an obsolete mysql_* library.
You are SQL injection prone.
Your code is silly and makes no sense.
If you really wan to stick to it, why simply not do:
while($row = mysql_fetch_assoc($i)) {
$r[] = $row;
}
echo json_encode($r);
And finally, an example using PDO:
$database = 'your_database';
$user = 'your_db_user';
$pass = 'your_db_pass';
$pdo = new \PDO('mysql:host=localhost;dbname='. $database, $user, $pass);
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
try
{
$stmt = $pdo->prepare("SELECT * FROM your_table WHERE id = :id");
$stmt->bindValue(':id', $id);
$stmt->execute();
$results = $stmt->fetchAll(\PDO::FETCH_ASSOC);
}
catch(\PDOException $e)
{
$results = ['error' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine());
}
echo json_encode($results);
You don't need the $temp variable. You can add an element to an array with:
$r[] = $row;

Categories