Confusion how to handle array return - php

function get_galleryxml_row($table_data)
{
$xml_output = array();
if ($table_data)
{
foreach($table_data as $key => $row)
{
$xml_output[] .= $this->exporter->get_property_gallery_data($key['id']);
}
return implode(" ", $xml_output);
}
}
get_property_gallery_data Returns area of images and urls which does contain data and I have checked but some reason i am getting the follow error.
Array to string conversion and it states this line as the error
$xml_output[] .= $this->exporter->get_property_gallery_data($key['id']);

No need of . -
$xml_output[] = $this->exporter->get_property_gallery_data($row['id']); // It should be only $key or $row['id']
It will store the value with new index. . is used to concatenate strings.

Try this...
$xml_output[] .= $this->exporter->get_property_gallery_data($key['id']);
to
$xml_output[] = $this->exporter->get_property_gallery_data($row['id']);

Related

How to get the keys of each level of a multidimensional array in PHP [duplicate]

This question already has answers here:
PHP - Convert multidimensional array to 2D array with dot notation keys
(5 answers)
Closed 8 months ago.
I'm trying to grab all the keys of a multidimensional array and format them a certain way. Here's a partial array:
$ini_config['aaa']['email']['main'] = 'me#name.com';
$ini_config['bbb']['email']['ccc'] = 'you#name.com';
$ini_config['bbb']['phone']['local'] = '800-555-1212';
$ini_config['bbb']['phone']['skype'] = '744-222-1234';
$ini_config['ccc']['phone']['main'] = 'domain.com';
$ini_config['ccc']['domain']['https'] = 'https://www. domain.com';
$ini_config['ccc']['fax'] = '744-222-1237';
and here's the format I need them in:
aaa_email_main
bbb_email_ccc
bbb_phone_local
bbb_phone_skype
ccc_phone_main
ccc_domain_https
ccc_fax
This script is the closest I've been able to come to what I need:
<?php
rloop($ini_config);
function rloop($array) {
global $full_key;
foreach($array as $key => $value) {
if(is_array($value) ) {
$full_key .= $key .'_';
$array[$key] = rloop($array[$key]);
}
else {
$array[$key] = (string) $value;
$filename = $full_key . $key;
echo 'filename: '. $filename . PHP_EOL;
$full_key = '';
}
}
}
N.B. The number of levels can be from 1 to 4, and all keys are strings.
Thanks
$ini_config['aaa']['email']['main'] = 'me#name.com';
$ini_config['bbb']['email']['ccc'] = 'you#name.com';
$ini_config['bbb']['phone']['local'] = '800-555-1212';
$ini_config['bbb']['phone']['skype'] = '744-222-1234';
$ini_config['ccc']['phone']['main'] = 'domain.com';
$ini_config['ccc']['domain']['https'] = 'https://www. domain.com';
$ini_config['ccc']['fax'] = '744-222-1237';
function keyPaths(array $array, array $carry = [], string $separator = ''): array {
foreach ($array as $key => $value) {
if (is_array($value)) {
$carry = keyPaths($value, $carry, $separator . $key . '_');
} else {
$carry[] = $separator . $key;
}
}
return $carry;
}
$result = keyPaths($ini_config);
Thanks to #lucas.j here's what I'm using now:
function get_all_keys($array, $collector='') {
$separator = '_';
foreach ($array as $key => $value) {
if (is_array($value)) {
get_all_keys($value, $collector.$key.$separator);
}
else {
$filename = $collector.$key;
$content = $value;
// echo 'filename: '. $filename . PHP_EOL; //:debug
// echo 'content: ' . $content . PHP_EOL; //:debug
file_put_contents($filename, $content);
}
}
}
After adding strategically placed echo statements, I was able to see what the $separator variable was doing. So I renamed it to $collector, since it's collecting the keys to form the "all-keys" string. I also renamed the function to be a little more descriptive, and added the hard-coded underscore to a new variable called $separator.
And since I don't need a new variable created, I dropped $carry and am performing what I need done directly in the else section.
Thanks, Lucas!

Unserialize function doesn't return array values

Hello i want to unserialize an array in order to display the array values.
The way that the array is inserted to my db field is like this.
persons: "a:1:{i:0;s:55:"[{"value":"john: writer"},{"value":"john: producer"}]";}"
and the function i have done but i am not getting any results is this
$adDetails = $stmt->fetchAll(PDO::FETCH_OBJ);
foreach ($adDetails as $feed) {
$feed->logo_pic = SITE_URL . $feed->logo_pic;
$feed->image_path = SITE_URL . $feed->image_path;
$feed->media_pic = SITE_URL . 'mediaPic/' . $feed->media_pic;
$personsArr = unserialize(array($feed->persons));
$personsText = " ";
if(!empty($personsArr)){
list($firstItem) = $personsArr;
foreach ($firstItem as $key => $value) {
foreach ($value as $valueInner) {
$personsText .= $valueInner.", ";
}
}
}
$feed->personsNew = $personsText;
}
$response['success'] = true;
$response['adDetails'] = $adDetails;
echo json_encode($response);
I am getting nothing on personsText although persons is persons: "a:1:{i:0;s:55:"[{"value":"john: writer"},{"value":"john: producer"}]";}"
Any help?
The value in the array is a JSON string, so you need to decode it.
The argument to unserialize() should just be $feed->persons, it shouldn't be in an array.
Instead of the loop, you can use array_column() to get all the value elements, and implode() to combine them with comma delimiters.
$adDetails = $stmt->fetchAll(PDO::FETCH_OBJ);
foreach ($adDetails as $feed) {
$feed->logo_pic = SITE_URL . $feed->logo_pic;
$feed->image_path = SITE_URL . $feed->image_path;
$feed->media_pic = SITE_URL . 'mediaPic/' . $feed->media_pic;
$personsArr = unserialize($feed->persons);
$personsText = " ";
if(!empty($personsArr)){
$firstItem = json_decode($personsArr[0], true);
$personsText = implode(', ', array_column($firstItem, 'value'));
}
$feed->personsNew = $personsText;
}
$response['success'] = true;
$response['adDetails'] = $adDetails;
echo json_encode($response);

NotORM: How to fetch data?

I´m having trouble using selects, I tried reading the documentation but it's not too clear, and the forums that talk about it are few and inactive.
I want to do a simple select, so I tried:
$applications = $NOTORM->user_types()
->select('id, group_title')
->where('id', 1);
return $applications;
That however gives me back a NotORM object where I don't see the resulting rows that I get when I do a normal: SELECT id, group_title FROM user_types WHERE id = 1
I tried using the fetch() but not really sure how to use it. Any insights?
Actually, recommended by the author of NotORM is to use:
<?php
array_map('iterator_to_array', iterator_to_array($result));
?>
Good luck!
I had the same problem till I realized that you have to loop over result.
Try
foreach($applications as $application) {
echo $application["id"] . ": " . $application["group_title"]
}
Alternatively as you mentioned you can use fetch() which will fetch you one row at a time.
$row=$applications->fetch();
echo $row["id"];
EDIT:
To get all the row data as plain associative array instead of NotORM Object I have come across 2 techniques:
foreach($row as $key => $value) {
$data[$key]=$value;
}
$data=iterator_to_array($row); - I haven't fount a NotOrm function that does this but I found that Notorm uses this technique internally(somewhere).
To actually get only the data array of the row, you have to access NotORM_Row->row param, but it is 'protected' by default. So to use it like this:
$row = $NOTORM->user_types()
->select('id, group_title')
->where('id', 1)
->fetch()->row; //here is the magic :)
You first need to 'hack' core NotORM_Row class in 'NotORM/Row.php',
by replacing
protected $row, $result;
to
public $row, $result;
Note: You have to call fetch() on NotORM results, because it will return the NotORM_Row object where the row data is placed.
Just add this code somewhere inside the NotORM_Result class:
function result() { return (Object)$this->result_array(); }
function result_array() {
foreach($this as $row) { $ret[] = iterator_to_array($row); }
return $ret;
}
And use it like:
$applications = $NOTORM->user_types()
->select('id, group_title')
->where('id', 1);
return $applications->result(); //To return it as an Plain Object
//or
return $applications->result_array(); //To return it as a Assoc Array
Try to define this PHP function:
function getArray($obj){
$arr = array();
foreach ($obj as $objSingle) {
$arrRow = array();
foreach ($objSingle as $key => $value) {
$arrRow[$key] = $value;
}
$arr[] = $arrRow;
}
return $arr;
}
And use it by calling:
$arr = getArray($applications);
NotOrm added a function that return raw row data than names jsonSerialize. You can get row data array by this function.
Example:
$row=$db->MyTable->where('X','93054660084')->fetch();
var_dump($row->jsonSerialize());
Output:
array (size=5)
'X' => string '93054660084' (length=9)
'Idc' => string '1132' (length=4)
'IdH' => string '1' (length=1)
'Mab' => string '0' (length=1)
'Tar' => string 'xsderf' (length=10)
For multi record data you need to use foreach and apply it to all records.
It can be done like this.
function comboBuilder2($tbl, $name, $lable, $value, $value2, $value3, $selected = NULL, $cond, $sort = NULL){
global $db;
$html = '';
$sort1 = (!empty($sort)) ? "order by sort asc" : '';
$sql = "select * from " . $tbl . " " . $cond . " " . $sort1 . "";
//echo $sql;
$sth = $db->query($sql);
$rs = $sth->fetchAll();
//print_r($rs);
if ($rs[0] > 0) {
foreach ($rs as $row) {
if ($selected == $row[$value])
$sel = 'selected = "selected" ';
else
$sel = '';
echo $row[$lable];
//$html .= '<option value="' . $row[$value] . '" data-min="' . $row[$value2] . '" data-max="' . $row[$value3] . '" ' . $sel . '>' . $row[$lable] . '</option>';
}
$html .= '';
}
return $html;
}

PHP foreach loop

I have the array example below that I am using to dynamically create an SQL query based on the options ticked in a form. The code below tests whether there is a value, if so, append it to the array:
if ($lookchild) { $val[]='lookchild'; }
if ($mentalcap) { $val[]='mentalcap'; }
if ($mentalheal) { $val[]='mentalheal'; }
if ($olderpeople) { $val[]='olderpeople'; }
if ($palcare) { $val[]='palcare'; }
I am then looping through the array and adding the rest of the SQL statement:
foreach ($val as $r){
echo $r.'=1 AND ';
}
This produces:
olderpeople=1 AND palcare=1 AND lookchild=1 AND
When the loop reaches the last entry, I don't want it to append the AND to it as the SQL statement needs to close after that point.
How I want it to complete:
olderpeople=1 AND palcare=1 AND lookchild=1
Implode
In these situations you can use implode
It 'glues' an array together.
implode ( string $glue , array
$pieces )
Example:
echo implode('=1 AND ', $val);
echo '=1';
A common trick is to use 'WHERE 1=1' then you can append ' AND foo = bar' without a syntax error.
WHERE 1=1 AND olderpeople=1 AND palcare=1 AND lookchild=1
This is what implode() is for:
$result = array();
foreach ($val as $r){
$result[] = "$r=1";
}
$result = implode($result, ' AND ');
Live Example
Just don't print the AND for the last value of the foreach loop. Here is the code to use:
foreach ($val as $r){
echo $r.'=1';
if (next($val)) {
echo ' AND ';
}
}
use the implode function
$sql = implode("=1 AND ", $array)."=1";
and you wont have to use a for loop :)
Instead on assigning palcare to $val[], assign $val[] = "palcare = 1" etc. Them
implode(" AND ", $val);
Try this :
$isFirst = true;
foreach ($val as $r){
if(!$isFirst){
echo ' AND ';
}else{
$isFirst = false;
}
echo $r.'=1';
}
I would remove the last 4 characters of the string with:
$r = '';
foreach ($val as $r){
$r.'=1 AND ';
}
$r = substr($r, 0, -4);
echo $r;
Checkout http://ca3.php.net/manual/en/function.substr.php, quick and easy
If you have to do it with a foreach (and for some reason you cant use implode, which is a good suggestion) you will need a way to keep track of where you are.
I thought to add the "AND" before anything but the first item, instead of adding it after anything but the last item, something like this:
$sqlwhere = "";
foreach ($val as $r){
if($sqlwhere ==""){
$sqlwhere = $r;
}
else {
$sqlwhere .= " AND " . $sqlwhere;
}
}
echo $sqlwhere;
I used a varable instead of just echoing it out too, which I find useful in complicated sql statements anyway.
Use implode. But if for some reason you need to loop (such as you need to do more logic than just joining the strings), use a separator approach:
$seperator = '';
$result = '';
foreach ($array as $value) {
// .. Do stuff here
$result .= $seperator . $value;
$seperator = ' AND ';
}
The benefit is both brevity and flexibility without checking conditions all the time...
Since you are using an array, you can also use count to figure out how many are in the array and if you are on the last item, don't append the 'AND'.
$result = array();
$totalcount = count($val);
$currentCount = 0;
foreach ($val as $r){
$currentCount ++;
if ($currentCount != $totalcount){$result[] = "$r=1 AND ";}else{$result[] = "$r=1";}
}

array looping strange behavior in php

I have an indexed array which I've generated from an associative array with this code
$index_arr = array();
foreach($assoc_arr as $key => $val ){
$index_arr .= $val;
}
when I print it with print_r($index_arr); it works fine. But when I try to print it with foreach I get an error "Invalid argument supplied for foreach()"
foreach($index_arr as $one){
echo "one: $one<br />";
}
I'm pretty sure this is the right syntax or am I too tired at this time of day?
You turn the array into a string by using .= operator on it. You want to use:
$index_arr[] = $val;
To append to the end.
Also in this particular case, you can just do:
$index_arr = array_values($assoc_arr);
This does exactly what your loop does.
When you did $index_arr .= $val; PHP did a String operation. You need to do $index_arr[]=$val;
Needs to be this:
$index_arr = array();
foreach($assoc_arr as $key => $val ){
$index_arr[] = $val;
}
Also
foreach($index_arr as $key=>$data){
echo "Key: ".$key." Data: ".$data."<br />";
}
$index_arr .= $val;
should be
$index_arr[] = $val;

Categories