what's wrong with this php code? - php

Ok, the idea here is to have code that will append SF_ to all key names in an array.
I took my array (which is part of an object), flipped it, added the SF_, and flipped it back.
Somewhere in the process I lost some fields...
here's what I started with:
object(stdClass)[12]
public 'Affiliate_Code__c' => string 'XX-TXUJC3' (length=9)
public 'AltEmail__c' => string 'benny#oxpublishing.com' (length=22)
public 'City' => string 'Mobile' (length=6)
public 'Email' => string 'benny#oxpublishing.com' (length=22)
public 'Fax__c' => string '251-300-1234' (length=12)
public 'FirstName' => string 'Benny' (length=5)
public 'LastName' => string 'Butler' (length=6)
public 'Phone' => string '251-300-3530' (length=12)
public 'PostalCode' => string '36606' (length=5)
public 'State' => string 'AL' (length=2)
public 'Street' => string '851 E I-65 Service Rd' (length=21)
public 'test1__c' => float 1
array
'SF_Affiliate_Code__c' => string 'XX-TXUJC3' (length=9)
'SF_Email' => string 'benny#oxpublishing.com' (length=22)
'SF_City' => string 'Mobile' (length=6)
'SF_Fax__c' => string '251-300-1234' (length=12)
'SF_FirstName' => string 'Benny' (length=5)
'SF_LastName' => string 'Butler' (length=6)
'SF_Phone' => string '251-300-3530' (length=12)
'SF_PostalCode' => int 36606
'SF_State' => string 'AL' (length=2)
'SF_Street' => string '851 E I-65 Service Rd' (length=21)
And here's my code:
$response = $mySforceConnection->query(($query));
foreach ($response->records as $SF) {
}
var_dump($SF);
$SF = array_flip($SF);
foreach ($SF as $key => $value){
$SF[$key] = 'SF_'.$value;
}
$SF = array_flip($SF);
echo "<pre>";
var_dump($SF);
echo "</pre>";
extract($SF);
Any idea?
I'm new to OO programming of any sort, and I'm sure this has something to do with it.
I'm so stupid I have to do:
foreach ($response->records as $SF) { }
because I don't know how to get to that array any other way.
Help!
Thanks!

When you do the flip, you end up with duplicate keys - the values become the keys, and your values are not unique (e.g. Email and AltEmail__c both have the same value).
Rather than doing a flip then flipping back, just create a new array and copy the values in with the new keys:
$SF_new = array();
foreach($SF as $key => $value ) {
$SF_new['SF_' . $key] = $value;
}
// And if you want to continue using the $SF name...
$SF = $SF_new;

array_flip will flip the values and keys, as you said. A PHP array cannot have multiple keys with the same name. Try something like this to avoid flipping:
<?php
$SF = array();
foreach($response->records as $key => $value)
{
$SF['SF_' . $key] = $value;
}
About the way you get to the array in the object, this is the proper way to do it.

$SF = get_object_vars($response);
Will transform your object into an array.

flip swaps keys and values. because you have values that share the same value, you lose them in the flip.

Related

How to sort and merge a PHP array by a specific key? [duplicate]

This question already has answers here:
Creating one array from another array in php [closed]
(2 answers)
Closed 6 years ago.
I have the following PHP array
array (size=14)
0 =>
object(stdClass)[39]
public 'department' => string 'BOOKS' (length=32)
public 'dep_url' => string 'cheap-books' (length=32)
public 'category' => string 'Sci-fi' (length=23)
public 'cat_url' => string 'sci-fi' (length=23)
1 =>
object(stdClass)[40]
public 'department' => string 'JEWELRY' (length=32)
public 'dep_url' => string 'cheap-jewels' (length=32)
public 'category' => string 'Rings' (length=23)
public 'cat_url' => string 'rings' (length=23)
2 =>
object(stdClass)[41]
public 'department' => string 'JEWELRY' (length=32)
public 'dep_url' => string 'cheap-jewels' (length=32)
public 'category' => string 'Earings' (length=23)
public 'cat_url' => string 'cheap-earings' (length=23)
As you can see its an array of departments with their categories, how can i merge the array to get something like the following:
array (size=14)
0 =>
object(stdClass)[39]
public 'department' => string 'BOOKS' (length=32)
public 'dep_url' => string 'cheap-books' (length=32)
innerarray[0] =
public 'category' => string 'Sci-fi' (length=23)
public 'cat_url' => string 'sci-fi' (length=23)
1 =>
object(stdClass)[40]
public 'department' => string 'JEWELRY' (length=32)
public 'dep_url' => string 'cheap-jewels' (length=32)
innerarray[0] =
public 'category' => string 'Rings' (length=23)
public 'cat_url' => string 'rings' (length=23)
innerarray[1] =
public 'category' => string 'Earings' (length=23)
public 'cat_url' => string 'cheap-earings' (length=23)
I want to merge the array by department with the least amount of loops.
I hope i am clear with my question, thanks for any help you can give!
It would be best if you had a department ID (a primary key) to use to identify duplicates, but in lieu of that you should use the department name and URL together to match them.
Something like this should work:
$output = [];
foreach ($array as $entry) {
// no department ID, so create one for indexing the array instead...
$key = md5($entry->department . $entry->dep_url);
// create a new department entry
if (!array_key_exists($key, $output)) {
$class = new stdClass;
$class->department = $entry->department;
$class->dep_url = $entry->dep_url;
$class->categories = [];
$output[$key] = $class;
}
// add the current entry's category data to the indexed department
$category = new stdClass;
$category->category = $entry->category;
$category->cat_url = $entry->cat_url;
$output[$key]->categories[] = $category;
}
This will give you an array of department objects which contains, each of which contains an array of category objects. It'll be indexed by a hash which you create manually in lieu of a department ID/primary key to use instead.
To remove those keys simply do:
$output = array_values($output);

How to loop over an array and conditionally update a nested value

I have two arrays like:
array (size=4)
0 => string '5' (length=1)
1 => string '4' (length=1)
2 => string '2' (length=1)
3 => string '2' (length=1)
3 => string '8' (length=1)
and one array more that I load from an XML file:
object(SimpleXMLElement)[1]
public 'book' =>
array (size=101)
0 =>
object(SimpleXMLElement)[2]
public 'id' => string '1' (length=1)
public 'title' => string 'p' (length=1)
1 =>
object(SimpleXMLElement)[3]
public 'id' => string '2' (length=1)
public 'title' => string 'pp' (length=2)
2 =>
object(SimpleXMLElement)[4]
public 'id' => string '3' (length=1)
public 'title' => string 'pen' (length=3)
3 =>
object(SimpleXMLElement)[5]
public 'id' => string '4' (length=1)
public 'title' => string 'lapton' (length=6)
......
......
101 =>
object(SimpleXMLElement)[103]
public 'id' => string '101' (length=1)
public 'title' => string 'title' (length=5)
I want to compare each value of key id of second array with key of first array for each value. When it's the same, I want to update value of key title of second array.
Assuming your first array is $idArray and your second is $xmlArray, you could use something like this.
$result = array_map(function($xmlElement) use ($idArray) {
if (in_array($xmlElement->id, $idArray)) {
$xmlElement->title = 'updated value';
}
return $xmlElement;
}, $xmlArray);
Assumptions
the first array is called $array1
the second array is called $fromXML
the second array is not actually an array, it's a SimpleXMLElement with the following structure (psuedocode / JSONish syntax)
{
'book' => {
0 => SimpleXMLElement {
'id' => 1,
'title' => 'p'
}
}
}
I assume you can access the second array of elements with $fromXML['book']
I assume you can access an attribute of the first element with $fromXML['book'][0]['id']
I assume that you can set the text of the title of the first element with $fromXML['book'][0]['title'][0] = 'new title'
based on How can I set text value of SimpleXmlElement without using its parent? and PHP SimpleXML, how to set attributes? and PHP foreach change original array values
Solution
foreach($fromXML['book'] as $key => $element) {
if(array_key_exists($element['id'], $array1)) {
$fromXML['book'][$key]['title'][0] = $array1[$element->id];
}
}
Caveat and troubleshooting
I didn't test this, just going off of the documentation. If I've misinterpreted the structure of your SimpleXMLElement array, try experimenting with var_dump($fromXML['some']['key']) until you find the right way to access the array/element
Note: Apparently, array_key_exists() performs better than in_array() on large arrays
Try this for now
foreach($array1 as $arr1 => $val1){
foreach($array2 as $arr2 =>$val2){
if($arr1==$arr2){
$val2['title']='update value';
}
}
}

Php Array sorting assoc key after intersect key

Currently I have this:
$pattern = array('industry_id','category_id','subcategory_id');
$data = array('advert_id' => string '261501' (length=6)
'advert_type_id' => string '7' (length=1)
'user_id' => string '6221' (length=4)
'industry_id' => string '17' (length=2)
'category_id' => string '769' (length=3)
'subcategory_id' => string '868' (length=3)
'model' => string 'Custom Semi Drop Deck Trailer' (length=29)
'description' => string 'Industry: Trailer );
Then:
array_intersect_key( $data , array_flip($pattern) );
Using array_interect_key & array_flip to get the values from $data based on $pattern, I will get a result like this:
array (size=3)
'category_id' => string '769' (length=3)
'subcategory_id' => string '930' (length=3)
'industry_id' => string '17' (length=2)
Unfortunately as you can see the result key sorting is not the same that I declared in $pattern. Is there a shorthand way to sort it like I declared in $pattern because after this I want to implode the array and do something like this industry_id.category_id.subcategory_id without hard coding the keys.
Since you already figured out array_intersect_key method which will not get you the desired key ordering of $pattern, try this instead:
// since original $pattern is not ASSOC (only vals)
// flip it so defined vals become keys
$pattern_flipped = array_flip($pattern);
$result = array();
foreach ($pattern_flipped as $k => $v) {
if (isset($data[$k])) {
$result[$k] = $data[$k];
}
}
var_dump($result); // test
// can use original 0 1 2 dynamic keys for concatenation
echo $result[$pattern[0]], $result[$pattern[1]], $result[$pattern[2]], '<br>';
// or use hardcoded keys
echo $result['industry_id'], $result['category_id'], $result['subcategory_id'], '<br>';
You know I'm not sure how you're getting the result you describe. I've tried your code and I get
array (size=3)
'industry_id' => string '17' (length=2)
'category_id' => string '769' (length=3)
'subcategory_id' => string '868' (length=3)
You could do this another way though using array_filter
$newData = array_filter($data, function($key) use ($pattern) {
if (in_array($key, $pattern))
return true;
}, ARRAY_FILTER_USE_KEY)

Accessing JSON object with PHP, Random Object Name

I am trying to parse out certain things within the JSON code, but the problem is that the two groups of arrays that have the information in it I need have random names, here is from the var_dump:
array (size=2)
'results' =>
array (size=1)
0 => string 'Phone.5d5b6fef-a2e0-4b08-cfe3-bc7128b776c3.Durable' (length=50)
'dictionary' =>
array (size=3)
'Person.51f28c76-2993-42d3-8d65-4ea0a66c5e16.Ephemeral' =>
array (size=8)
'id' =>
array (size=5)
...
'type' => null
'names' =>
array (size=1)
...
'age_range' => null
'locations' => null
'phones' =>
array (size=1)
...
'best_name' => string 'John Smith' (length=15)
'best_location' => null
'Location.28dc9041-a0ee-4613-a3b0-65839aa461da.Durable' =>
array (size=30)
'id' =>
array (size=5)
...
'type' => string 'ZipPlus4' (length=8)
'valid_for' => null
'legal_entities_at' => null
'city' => string 'City' (length=8)
'postal_code' => string '12345' (length=5)
'zip4' => string '4812' (length=4)
'state_code' => string 'MO' (length=2)
'country_code' => string 'US' (length=2)
'address' => string 'Main St, City, MO 12345-4812' (length=33)
'house' => null
No I am trying to get best_name from under the part that starts with Person and address under Location. But when I do:
$string = file_get_contents($url);
$json=json_decode($string,true);
var_dump($json);
echo $json['dictionary']['Person']['best_name'];
I get Undefined index: Person error, because the actual object name for Person is:
Person.51f28c76-2993-42d3-8d65-4ea0a66c5e16.Ephemeral which is different every time I do a search. Is there a way to do this without putting the random generated line in?
Hopefully this makes sense, thanks for the help in advance!
If the Person key always starts with the string "Person", than simply do a foreach and check the key which contains this string.
Like:
foreach ($json['dictionary'] as $key => $value) {
if (preg_match('/^Person/', $key)) {
echo $json['dictionary'][$key]['best_name'];
}
}
Of course this get complicated, if you have multiple keys which start with "Person".
You can do the same with "Location" or any other string you need.
How about something like this ... loop through $json['dictionary']'s index keys to find something that starts with "Person".
$foundIt = false;
foreach (array_keys($json['dictionary']) as $key) {
if (substr($key,0,6) == 'Person') {
$foundIt = $key;
break;
}
}
if ($foundIt) { echo $json['dictionary'][$foundIt]['best_name']; }

converting array to stdClass in CodeIgniter

I am returning data from two tables in CodeIgniter with the function below
public function test()
{
$this->db->select('*');
$this->db->from('WHOUSE1.DLY_BWR_DLY_PERFORMANCE');
$this->db->join('WHOUSE1.DATE_DIM', 'WHOUSE1.DATE_DIM.DATE_KEY = WHOUSE1.DLY_BWR_DLY_PERFORMANCE.BDP_DATE');
$query = $this->db->get();
return $query->result_array();
}
Using var_dump I am getting the result below
array (size=3226)
0 =>
array (size=121)
'BDP_ID' => string '945149' (length=6)
'BDP_COST_CENTRE_NUMBER' => string '1376' (length=4)
'BDP_DATE' => string '20040807' (length=8)
'BDP_DAY_CODE' => string '6' (length=1)
'BDP_TAKE' => string '4923.78' (length=7)
'BDP_PAYOUT' => string '3779.22' (length=7)
'BDP_ACTUAL_SLIPPAGE' => string '636' (length=3)
1 =>
array (size=121)
'BDP_ID' => string '945150' (length=6)
'BDP_COST_CENTRE_NUMBER' => string '1376' (length=4)
'BDP_DATE' => string '20040809' (length=8)
'BDP_DAY_CODE' => string '1' (length=1)
'BDP_TAKE' => string '2848.3' (length=6)
'BDP_PAYOUT' => string '4190.34' (length=7)
'BDP_ACTUAL_SLIPPAGE' => string '280' (length=3)
But what I will like to get is this
array (size=3226)
0 =>
object(stdClass)[27]
'BDP_ID' => string '945149' (length=6)
'BDP_COST_CENTRE_NUMBER' => string '1376' (length=4)
'BDP_DATE' => string '20040807' (length=8)
'BDP_DAY_CODE' => string '6' (length=1)
'BDP_TAKE' => string '4923.78' (length=7)
'BDP_PAYOUT' => string '3779.22' (length=7)
'BDP_ACTUAL_SLIPPAGE' => string '636' (length=3)
1 =>
object(stdClass)[29]
'BDP_ID' => string '945150' (length=6)
'BDP_COST_CENTRE_NUMBER' => string '1376' (length=4)
'BDP_DATE' => string '20040809' (length=8)
'BDP_DAY_CODE' => string '1' (length=1)
'BDP_TAKE' => string '2848.3' (length=6)
'BDP_PAYOUT' => string '4190.34' (length=7)
'BDP_ACTUAL_SLIPPAGE' => string '280' (length=3)
I can't seem to get a way of converting the array into object(stdClass) Any help will be appreciated as am new to CodeIgniter.
Array to stdClass can be done in php this way.
stdClass:: __set_state(array());
Or a nicer way.
$a = (object) array();
Use this code in Your Model ( change your table name and select, distinct fileds )
$this->db->select('DISTINCT(subcategory)');
$this->db->from('tbl_property');
$this->db->where('status','1');
$data = $this->db->get()->result();
$sub_id = array();
foreach ($data as $row)
{
array_push($sub_id,$row->subcategory);
}
$this->db->from('tbl_subcategory');
$this->db->where_in('id',$sub_id);
$data1 = $this->db->get()->result();
return $data1;
use
return $query->result();
This function returns the query result as an array of objects, or an empty array on failure. Typically you'll use this in a foreach loop, like this:
$query = $this->db->query("YOUR QUERY");
foreach ($query->result() as $row)
{
echo $row->title;
echo $row->name;
echo $row->body;
}
Edit:
If you just want to print you can use var_dump() or print_r().
var_dump($obj);
print_r($obj);
If you want an array of all properties and their values use get_object_vars().
$properties = get_object_vars($obj);
print_r($properties);
According to the same documentation for Codeigniter I detail:
result_array()
This function returns the query result as a pure array, or an empty array when no
result `is produced. Typically you'll use this in a foreach loop, like this:`
and ..
result()
This function returns the query result as an array of objects, or an empty array
on failure.
You should return your data in this way
return $query->result();

Categories