PHP json_encode - php

This is my script at the moment:
//... PDO CONNECTION AND QUERY //...*
$result = $dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC);
foreach ($result as $row){
$return[]=array('employeeid'=>$row['employeeid'],
'firstname'=>$row['firstname'],
'lastname'=>$row['lastname'],
'id'=>$row['id'],
'startdate'=>$row['startdate'],
'enddate'=>$row['enddate'],
'type'=>$row['type'],
'reason'=>$row['reason']);
}
$dbh = null;
header('Content-type: application/json'); echo '' .
json_encode($return) .'';
This gives a result like:
[
{
'employeeid': '1',
'firstname': 'john',
'lastname': 'doe',
'id': '001',
...,
...
}
]
[
{
'employeeid': '1',
'firstname': 'john',
'lastname': 'doe',
'id': '002',
...,
...
}
]
But what i would like is a result like this (so each employee has one object with multiple requests):
[
{
'employeeid': '1',
'firstname': 'john',
'lastname': 'doe',
'requests': [
{
'id': '001',
...,
...
},
{
'id': '002',
...,
...
}
]
}
]
Can someone help me with this?
Thanks in advance,
Jan

You'll need to include the requests records in each employee array:
foreach ($result as $row){
$employee=array('employeeid'=>$row['employeeid'],
'firstname'=>$row['firstname'],
'lastname'=>$row['lastname'],
'id'=>$row['id'],
'startdate'=>$row['startdate'],
'enddate'=>$row['enddate'],
'type'=>$row['type'],
'reason'=>$row['reason']);
$requests = $dbh->query(sprintf("SELECT * FROM employee_requests WHERE employee_id = '%s'", $row['employeeid']))->fetchAll(PDO::FETCH_ASSOC);
$employee['requests'] = requests;
$return[] = $employee;
}

Change your foreach as follows:
foreach ($result as $row){
$employeeid = $row['employeeid'];
if (!isset($return[$employeeid]))
$return[$employeeid] = array(
'employeeid' => $row['employeeid'],
'firstname' => $row['firstname'],
'lastname' => $row['lastname'],
'requests' => array()
);
$return[$employeeid]['requests'][] = array(
'id' => $row['id'],
'startdate' => $row['startdate'],
'enddate' => $row['enddate'],
'type' => $row['type'],
'reason' => $row['reason']
);
}

Related

PHP looping recursive function

I had this looping function and what it does to fetch data then display the result in json format. In $subArray[] i try to call the looping function again so it can read if got any sub-nodes underneath. But seem the result not display as I expected to be.
function recursiveNode($ledgerID,$accountID){
global $ehorsObj;
$subArray = array();
$query_get_subchild = " SELECT accountLedgerID, accountID, accountMainID, accountName, active
FROM tblAccAccounts
WHERE accountMain = 'y'
AND accountSub = 'y'
AND accountMainID = '".$accountID."'
AND accountLedgerID = '".$ledgerID."'
ORDER BY accountName
";
$GetResult = $ehorsObj->FetchData($query_get_subchild, $ehorsObj->DEFAULT_PDO_CONNECTIONS);
while ($row3 = $GetResult->fetch()) {
$subArray[] = array('accountLedgerID' => $row3['accountLedgerID'], 'accountID' => $row3['accountID'], 'accountMainID' => $row3['accountMainID'], 'accountName' => $row3['accountName'], 'active' => $row3['active'], 'items' => recursiveNode($ledgerID, $row3['accountID']));
}
header("Content-type: application/json");
$result = json_encode($subArray);
echo $result;
}
it show the result (as image below)
and the result I expected to be like this
[
{
accountLedgerID: "LA1",
accountID: "LA95",
accountMainID: "LA5",
accountName: "SubGroup RunDeposit 1",
active: "y"
},
{
accountLedgerID: "LA1",
accountID: "LA2",
accountMainID: "LA5",
accountName: "SubGroup RunDeposit 2",
active: "y",
item: [
{
accountLedgerID: "LA1",
accountID: "LA125",
accountMainID: "LA2",
accountName: "Sub x2 Group RunDeposit 2",
active: "y",
items: [
{
accountLedgerID: "LA1",
accountID: "LA6",
accountMainID: "LA125",
accountName: "Sub x3 Group RunDeposit 2",
active: "y",
items: [ ]
}
]
}
]
}
]
function fetch_account ($dbresult, $ledgerID, $accountID) {
$result = array_filter($dbresult, function ($something) use ($ledgerID, $accountID) {
if ( $something['accountMainID'] == $accountID && $something['accountLedgerID'] == $ledgerID ) {
return true;
}
return false;
});
return array_values($result);
}
function recursiveNode($ledgerID,$accountID){
$testArray = [
[
'accountLedgerID' => 'LA1',
'accountID' => 'LA95',
'accountMainID' => 'LA5',
'accountName' => 'SubGroup RunDeposit 1',
'active' => 'y'
],
[
'accountLedgerID' => 'LA1',
'accountID' => 'LA2',
'accountMainID' => 'LA5',
'accountName' => 'SubGroup RunDeposit 2',
'active' => 'y'
],
[
'accountLedgerID' => 'LA1',
'accountID' => 'LA125',
'accountMainID' => 'LA2',
'accountName' => 'Sub x2 Group RunDeposit 2',
'active' => 'y'
],
[
'accountLedgerID' => 'LA1',
'accountID' => 'LA6',
'accountMainID' => 'LA125',
'accountName' => 'Sub x3 Group RunDeposit 2',
'active' => 'y'
]
];
$someArray = fetch_account($testArray, $ledgerID, $accountID);
$subArray = array();
$i = 0;
while (!empty($someArray[$i]) && $row3 = $someArray[$i]) {
$subArray[] = array(
'accountLedgerID' => $row3['accountLedgerID'],
'accountID' => $row3['accountID'],
'accountMainID' => $row3['accountMainID'],
'accountName' => $row3['accountName'],
'active' => $row3['active'],
'items' => recursiveNode($ledgerID, $row3['accountID'])
);
$i++;
}
return $subArray;
}
$myArray = recursiveNode('LA1', 'LA5');
$result = json_encode($myArray);
echo $result;
Breaking down the problem first, I think the recursive function isn't returning anything. I think this is indicative when your result has 'items' as null.

Error on update elasticsearch php "document_missing_exception"

I'm using Elasticsearch with PHP and after the required data mapping. I inserted the data via insert function as seen below:
public function insertNode ($event_id) {
global $conn1;
$client = $this->elasticclient;
$params = null;
$stmt = "SELECT
events.event_id,
events.event_title,
events.event_details,
DATE_FORMAT(events.added_date,'%d-%m-%Y') AS added_date
FROM events
WHERE events.event_id = $event_id";
$query = $conn1->prepare($stmt);
$query->execute();
$rows = $query->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
$params = [
'index' => 'eventree',
'type' => 'events',
'id' => $row['event_id'],
'body' => [
'EVENT_TITLE' => $row['event_title'],
'EVENT_DETAILS' => $row['event_details'],
'START_TIME' => $row['start_time'],
'ADDED_DATE' => $row['added_date'],
'STATUS' => $row['status']
]
];
}
$responses = $client->index($params);
return true;
}
below you can see how I update data:
public function updateNode($event_id) {
global $conn1;
$client = $this->elasticclient;
$params = null;
$stmt = "SELECT
events.event_id,
events.event_title,
events.event_details,
events.status,
DATE_FORMAT(events.added_date,'%d-%m-%Y') AS added_date
FROM events
WHERE events.event_id = $event_id";
$query = $conn1->prepare($stmt);
$query->execute();
$rows = $query->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
$params = [
'index' => 'eventree',
'type' => 'events',
'id' => $row['event_id'],
'body' => [
'doc' => [
'EVENT_TITLE' => $row['event_title'],
'EVENT_DETAILS' => $row['event_details'],
'START_TIME' => $row['start_time'],
'ADDED_DATE' => $row['added_date'],
'STATUS' => $row['status']
]]];
}
$responses = $client->update($params);
return true;
}
The problem is that the update process won't accept ids larger than 9, although there are records with ids greter than number 9. This is the error I get after running the update proccess:
{
"error": "{\"error\":{\"root_cause\":[{\"type\":\"document_missing_exception\",\"reason\":\"[events][10]: document missing\",\"index_uuid\":\"6l5vWeLLSb6CvcCsqTws9g\",\"shard\":\"1\",\"index\":\"eventree\"}],\"type\":\"document_missing_exception\",\"reason\":\"[events][10]: document missing\",\"index_uuid\":\"6l5vWeLLSb6CvcCsqTws9g\",\"shard\":\"1\",\"index\":\"eventree\"},\"status\":404}"
}
Your php code is wrong, you loop $rows and override $params variable all the time!
the correct code
public function insertNode($event_id) {
global $conn1;
$client = $this->elasticclient;
$params = null;
$stmt = "SELECT
events.event_id,
events.event_title,
events.event_details,
DATE_FORMAT(events.added_date,'%d-%m-%Y') AS added_date
FROM events
WHERE events.event_id = $event_id";
$query = $conn1->prepare($stmt);
$query->execute();
$rows = $query->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
$params = [
'index' => 'eventree',
'type' => 'events',
'id' => $row['event_id'],
'body' => [
'EVENT_TITLE' => $row['event_title'],
'EVENT_DETAILS' => $row['event_details'],
'START_TIME' => $row['start_time'],
'ADDED_DATE' => $row['added_date'],
'STATUS' => $row['status']
]];
$responses = $client->index($params);
}
return true;
}
public function updateNode($event_id) {
global $conn1;
$client = $this->elasticclient;
$params = null;
$stmt = "SELECT
events.event_id,
events.event_title,
events.event_details,
events.status,
DATE_FORMAT(events.added_date,'%d-%m-%Y') AS added_date
FROM events
WHERE events.event_id = $event_id";
$query = $conn1->prepare($stmt);
$query->execute();
$rows = $query->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
$params = [
'index' => 'eventree',
'type' => 'events',
'id' => $row['event_id'],
'body' => [
'doc' => [
'EVENT_TITLE' => $row['event_title'],
'EVENT_DETAILS' => $row['event_details'],
'START_TIME' => $row['start_time'],
'ADDED_DATE' => $row['added_date'],
'STATUS' => $row['status']
]]];
$responses = $client->update($params);
}
return true;
}

Apply array_map on column of the array

I was trying to get a solution to speed up the process of PHP.
We are running into execution time issues on a specific page.
We have an array with around 10.000 rows and we need to apply several callback functions on some of the columns of that array.
What is the best way and the fastest execution possible to go over an array and only apply a callback on several columns.
<?php
$records = [
['id' => 2135, 'first_name' => 'John', 'price' => 1000, 'unit' => 5, 'discount' => 30],
['id' => 3245, 'first_name' => 'Sally', 'price' => 2000, 'unit' => 8, 'discount' => 80],
['id' => 5342, 'first_name' => 'Jane', 'price' => 4000, 'unit' => 5, 'discount' => 34],
['id' => 5623, 'first_name' => 'Peter', 'price' => 1500, 'unit' => 4, 'discount' => 25]
];
function simpleMultiply($value)
{
return $value * 2;
}
$applyToColumn = ['price','unit','discount'];
// $expectedRecords = array_map('simpleMultiply', array_column($records, 'id'));
$expectedRecords = [
['id' => 2135, 'first_name' => 'John', 'price' => 2000, 'unit' => 10, 'discount' => 60],
['id' => 3245, 'first_name' => 'Sally', 'price' => 4000, 'unit' => 16, 'discount' => 160],
['id' => 5342, 'first_name' => 'Jane', 'price' => 8000, 'unit' => 10, 'discount' => 68],
['id' => 5623, 'first_name' => 'Peter', 'price' => 3000, 'unit' => 8, 'discount' => 50]
];
?>
array_column is an expensive operation if the array is large, because it has to create an entirely new array. Calling it repeatedly for different columns will multiply that expense. I suggest you just use a simple foreach loop.
$expectedRecords = array();
foreach ($records as $r) {
foreach ($applyToColumn as $col) {
$r[$col] = simpleMultiply($r[$col]);
}
$expectedRecords[] = $r;
}
If you can modify the original $records instead of creating a new $expectedRecords, you can use a reference in the first foreach.
foreach ($records as &$r) {
foreach ($applyToColumn as $col) {
$r[$col] = simpleMultiply($r[$col]);
}
}
You can wrap the result set in an iterator (or a generator, which looks rather similar to an iterator) that modifies the current row before returning it as the iteration result, e.g.
<?php
class Foo extends IteratorIterator {
public function current() {
$rv = parent::current();
if ( $rv ) {
// ... and more checks here ....
// this example just assumes the fields/elements exist
$rv['x'] *= 17;
return $rv;
}
}
}
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'localonly', 'localonly', array(
PDO::ATTR_EMULATE_PREPARES=>false,
PDO::MYSQL_ATTR_DIRECT_QUERY=>false,
PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION
));
setup($pdo);
// the point is not to have the complete result set in memory
// see: e.g. php.net/mysqlinfo.concepts.buffering (or whatever database you use ;-) )
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
$result = new Foo( $pdo->query('SELECT x,y FROM sofoo') );
foreach( $result as $row ) {
echo join(', ', $row), PHP_EOL;
}
function setup($pdo) {
$pdo->exec('
CREATE TEMPORARY TABLE sofoo(
id int auto_increment, # I just throw this in casually....
x int,
y int,
primary key(id)
)
');
$stmt = $pdo->prepare('INSERT INTO sofoo (x,y) VALUES (?,?)');
foreach( range(1,5) as $x ) {
$stmt->execute( array($x, $x*13) );
}
}
or (without most of the boilerplate, using a generator - and invoking the anonymous function immediately)
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
$result = (function($iter) {
foreach( $iter as $row ) {
$row['x'] *= 17;
yield $row;
}
})($pdo->query('SELECT x,y FROM sofoo') );
foreach( $result as $row ) {
echo join(', ', $row), PHP_EOL;
}
You can build this "system" arbitrarily complex. Maybe passing the field names and functions to modify the elements to the generator like
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
$result = my_generator(
$pdo->query('SELECT x,y FROM sofoo'),
array('x'=>function($e) { return $e*17; })
);
foreach( $result as $row ) {
echo join(', ', $row), PHP_EOL;
}
function my_generator($iter, $modifiers) {
foreach( $iter as $row ) {
foreach( $modifiers as $field=>$func) {
$row[$field] = $func($row[$field]);
}
yield $row;
}
}
or add some chaining mechanism so that multiple functions can modify the same field. Or passing the complete row to the functions so they can change the structure as well. Or ... or ...

Implode an array in php

$array = array();
foreach( $order->get_items() as $item_id => $item ) {
$rray = array(
'name'=>$item['name'],
'qty'=>$item['qty']
);
$array[] = $rray;
}
}
I have the array like the above
How to create a string look like this:
'name qty, name qty, name qty, name qty, name qty, name qty, name qty, '
'Afghan Kush 1, Pomegranate Blue-Rasp 1, Blueberry Vanilla 1, Banana Strawberry 1, Caramel Cappuccino 1, '
Try with:
$array_text = implode(', ', array_map(function ($e) { return $e['name'] . ' ' . $e['qty']; }, $array));
$mystring = "";
foreach($array as $strain) {
$strain['array_text'] = $strain['name']." ".$strain['qty'];
$mystring .= $strain['array_text'].", ";
}
echo $mystrain;
You can use array_map() and implode().
$array = [
[
'name' => 'Blackberry Kush',
'qty' => '1'
],
[
'name' => 'Granddaddy Purple',
'qty' => '1'
],
[
'name' => '20% THC',
'qty' => '1'
],
[
'name' => 'Pomegranate Blue-Rasp',
'qty' => '1'
],
[
'name' => 'Blueberry Vanilla',
'qty' => '2'
],
[
'name' => 'Banana Strawberry',
'qty' => '3'
]
];
$formatted = array_map( function($obj) {
return "{$obj['name']} {$obj['qty']}";
}, $array );
echo implode( ', ', $formatted );
Example
$array = array();
foreach( $order->get_items() as $item_id => $item ) {
$rray = array(
'name'=>$item['name'],
'qty'=>$item['qty']
);
$array[] = $rray;
}
foreach($array as $key => $value) {
$result .= $value['name']." ". $value['qty'];
$result .= ", ";
}
var_dump($result);
Work like a champ!

PHP - search in array and create new one

I want to avoid if it is possible foreach combined with if. I want to search the array, take out the matches and create new one base on result.
In this example I want to create separate arrays for each os -
$os1 = $array;
$os2 = $array...
Array looks like this:
$array = [
0 => [
'id' => 1,
'name' => 'name',
'os' => 1
],
1 => [
'id' => 2,
'name' => 'name',
'os' => 1
],
2 => [
'id' => 3,
'name' => 'name',
'os' => 2
],
3 => [
'id' => 3,
'name' => 'name',
'os' => 2
]
];
Use array_filter to reduce the input array to the expected result
$os = 1;
$data = array_filter($array, function($item) use ($os) {
return $item['os'] == $os;
});
The short one
$os1 = [];
$os2 = [];
$os3 = [];
foreach ($array as $item) {
${'os' . $item['os']}[] = array('id' => $item['id'], 'name' => $item[$name];
}
The better one
$os1 = [];
$os2 = [];
$os3 = [];
foreach ($array as $item) {
switch($item['os']) {
case 1:
$os1[] = array('id' => $item['id'], 'name' => $item[$name]);
break;
case 2:
$os2[] = array('id' => $item['id'], 'name' => $item[$name]);
break;
case 3:
$os3[] = array('id' => $item['id'], 'name' => $item[$name]);
break;
default:
throw new Exception('Unknown Os');
}
}
Also you maybe want to assign array($item['id'] => $item[$name]); instead of array('id' => $item['id'], 'name' => $item[$name]);
$os1 = [];
$os2 = [];
$os3 = [];
foreach ($array as $item) {
${'os' . $item['os']}[] = array($item['id'] => $item[$name]);
}

Categories