Change element of loop - php

I have an php array like this (var_dump)
I need change one of it's element
array (size=204)
'Address' =>
array (size=3)
'City' =>
array (size=3)
0 => string 'return $this->hasOne(City::className(), ['id' => 'cityId']);'
1 => string 'City' (length=4)
2 => boolean false
'CityDistrict' =>
array (size=3)
0 => string 'return $this->hasOne(CityDistrict::className(), ['id' => 'cityDistrictId']);' (length=76)
1 => string 'CityDistrict' (length=12)
2 => boolean false
'Contacts' =>
array (size=3)
0 => string 'return $this->hasMany(Contact::className(), ['addressId' => 'id']);'
1 => string 'Contact' (length=7)
2 => boolean true
'City' =>
array (size=3)
'Addresses' =>
array (size=3)
0 => string 'return $this->hasMany(Address::className(), ['cityId' => 'id']);'
1 => string 'Address' (length=7)
2 => boolean true
'Region' =>
array (size=3)
0 => string 'return $this->hasOne(Region::className(), ['id' => 'regionId']);' (length=64)
1 => string 'Region' (length=6)
2 => boolean false
'CityDistricts' =>
array (size=3)
0 => string 'return $this->hasMany(CityDistrict::className(), ['cityId' => 'id']);'
1 => string 'CityDistrict' (length=12)
2 => boolean true
'CityDistrict' =>
array (size=2)
Addresses =>
array (size=3)
0 => string 'return $this->hasMany(Address::className(), ['cityDistrictId' => 'id']);'
1 => string 'Address' (length=7)
2 => boolean true
'City' =>
array (size=3)
0 => string 'return $this->hasOne(City::className(), ['id' => 'cityId']);'
1 => string 'City' (length=4)
2 => boolean false
How can i change value 'CityDistrict' in this loop? or 'Addresses'? using php foreach
My code doesn't work please help understand what wrong!
private static function checkExistClass($relations)
{
foreach ($relations as $name => $relation) {
foreach ($relation as $functionName => $functionValue) {
$functionNameGet = 'get' . $functionName;
$directory = new Model;
if (method_exists($directory, $functionNameGet)) {
$relation['funky_key_' . $functionName] = $functionValue;
unset($relation[$functionName]);
}
}
}
return $relations;
}

I interprete your question that you want to rename the array index Addresses to NewAddresses:
$relations['CityDistrict']['NewAddresses'] = $relations['CityDistrict']['Addresses'];
unset($relations['CityDistrict']['Addresses']);
EDIT:
to do that in your foreach loop, change:
$relation['funky_key_' . $functionName] = $functionValue;
unset($relation[$functionName]);
to:
$relations[$name]['funky_key_'.$functionName] = $functionValue;
unset($relations[$name][$functionName]);

maybe this is what you're looking
if (isset($array['n'])) {
$array['name'] = $array['n'];
unset($array['n']);
}
you can see the complete post in Change key in associative array in PHP
see you!
PD Sorry, for my english is not the best

Your loop seems wrong. In the outer loop, $name assumes values such as 'Address', and $relation is an array such as { 'City' => ..., 'CityDistrict' => ... }.
So in the second loop $functionName assumes values such as City, CityDistrict and Contacts.
If you want to change that, you need to do something like #hellcode suggested:
if ('CityDistrict' == $functionName) {
$relations[$name]['NewDistrict'] = $relations[$name][$functionName];
unset($relations[$name][$functionName]);
continue;
}
This looks like a Laravel/Eloquent problem to me. If you can state more precisely what it is that you're trying to accomplish, possibly someone could be of more use.
Also, you seem to want to create a function given its code in a string. To do this you would need create_function (or declare the function as anonymous/lambda function):
$code = "return 42;";
$array['function'] = create_function('', $code);
print $array['function']();
Note that the use of create_function is somewhat deprecated. Also you need a PHP > 5.3+ (or 5.4+ if you go lambda and require $this).

Related

PHP. How to get the position of an element inside an unidimensional and multidimensional array? [duplicate]

This question already has answers here:
php - get numeric index of associative array
(7 answers)
Closed 3 years ago.
For instance, in the following code, how to get the position -order- of a given element inside the array:
<?php
$cars=array("Volvo","BMW","Toyota","Tesla","Volkswagen");
//for Volvo, an echo statement should return 1
//for BMW, an echo statement should return 2
//for Toyota, an echo statement should return 3 ... and so on ...
?>
Update: After receiving some useful contributions regarding the implementation of search_array(), I was wondering if I can apply the same for arrays contained inside another array. vardump() for a multidimensional array shows me the following:
array (size=3)
'home' =>
array (size=6)
'label' =>
object(Magento\Framework\Phrase)[5814]
private 'text' => string 'Home' (length=4)
private 'arguments' =>
array (size=0)
...
'title' =>
object(Magento\Framework\Phrase)[5815]
private 'text' => string 'Go to Home Page' (length=15)
private 'arguments' =>
array (size=0)
...
'link' => string 'http://example.com/example.html' (length=23)
'first' => boolean true
'last' => null
'readonly' => null
'category4' =>
array (size=6)
'label' => string 'Transport' (length=9)
'link' => string 'http://example.com/example.html' (length=23)
'title' => null
'first' => null
'last' => null
'readonly' => null
'category686' =>
array (size=6)
'label' => string 'Transport' (length=15)
'link' => string '' (length=0)
'title' => null
'first' => null
'last' => boolean true
'readonly' => null
How to get in this case the position of category4 in regard to the array of size=3?
array_search() will let you find the position of an element or it returns FALSE if the element was not found. Read more about it at http://php.net/manual/en/function.array-search.php
From the documentation, this is what can be returned from this function:
Return Values
Returns the key for needle if it is found in the array, FALSE otherwise.
And here is an example:
<?php
$cars=array("Volvo","BMW","Toyota","Tesla","Volkswagen");
//for Volvo, an echo statement should return 1
//for BMW, an echo statement should return 2
//for Toyota, an echo statement should return 3 ... and so on ...
$volvoPosition = array_search("Volvo", $cars);
if ($volvoPosition !== false) {
// Volvo position was found at index/position 0 of the array.
print $volvoPosition; // This gives the value 0
} else {
// "Volvo" was never found in the array.
}
?>
As the example is very simple, meaning, is just an array of strings, then you may use array_flip, which is going to return an array that flips the keys with the values, so we can do:
$cars = ["Volvo","BMW","Toyota","Tesla","Volkswagen"];
$flipped = array_flip($cars);
//for Volvo, => int(0)
var_dump($flipped['Volvo']);
//for BMW, => int(1)
var_dump($flipped['BMW']);
Also remember that the array start with 0 and not with 1, then the index of "Volvo" is 0 and not 1.
Yes you can use array_search(), but array_search() returns the index of the element which is start from 0, so you can do like below,
this is your array
$cars=array("Volvo","BMW","Toyota","Tesla","Volkswagen");
echo (array_search("Volvo",$cars)) + 1; //you can getting 1 as 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';
}
}
}

Why my array is increamenting php laravel 5

I have an array which contains data from the database:
$responses = FormResponses::where('form_id', '>=', $phoneFirstElement->id)->where('form_id', '<=', $phoneLastElement->id)->get();
$responsesArray = $responses->toArray();
Then my nested loop:
foreach ($phone as $key => $value2) // Populate Phone Numbers Horizontally
{
$sheet->cell($start.'9', $value2->phone);
// This will fill the responses for each number
foreach ($metrics as $key => $value)
{
$form_id = $value2->id;
$metrics_id = $value->id;
$neededObjects = array_filter(
$responsesArray,
function ($e) use ($form_id, $metrics_id) {
return $e['form_id'] == $form_id && $e['metrics_id'] == $metrics_id;
}
);
var_dump($neededObjects);
exit;
//$responses = FormResponses::where('form_id', '=', $value2->id)->where('metrics_id', '=', $value->id)->get();
//$sheet->cell($start.$count, $neededObjects[$counter]['response']);
$sheet->cell('C'.$count, $value->question);
$sheet->cell('B'.$count, $value->description);
$sheet->cell('A'.$count, $value->metrics_name);
$counter++;
$count++;
$neededObjects = array();
}
$start++;
$count = 10;
//$counter = 0;
}
My $responsesArray is the data which has lots of record, so I want to extract those data to get the specific one I need using array_filter and storing it in
$neededObjects
However when I make a var_dump I get something like
array (size=1)
0 =>
array (size=7)
'id' => int 141730
'form_id' => int 4430
'metrics_id' => int 1
'response' => string 'Yes' (length=3)
'remarks' => string '' (length=0)
'created_at' => string '2015-11-23 19:30:07' (length=19)
'updated_at' => string '2015-11-23 19:30:07' (length=19)
Then when the next records loops in
array (size=1)
1 =>
array (size=7)
'id' => int 141731
'form_id' => int 4430
'metrics_id' => int 2
'response' => string 'Yes' (length=3)
'remarks' => string '' (length=0)
'created_at' => string '2015-11-23 19:30:07' (length=19)
'updated_at' => string '2015-11-23 19:30:07' (length=19)
I don't understand why it is increamenting. The first one is 0 then next is 1 . Yes given that I am making an array_filter inside a nested loop but I didn't put any inreament vairables to it and the array filter will aways give me 1 record of data so I am expecting it atleast to be in index 0 or just a format like this:
array (size=7)
'id' => int 141731
'form_id' => int 4430
'metrics_id' => int 2
'response' => string 'Yes' (length=3)
'remarks' => string '' (length=0)
'created_at' => string '2015-11-23 19:30:07' (length=19)
'updated_at' => string '2015-11-23 19:30:07' (length=19)
Any results that are returned by array_filter maintain their old keys. If you want the keys to reset then apply array_values to the result.
If you only want one result then call current() or array_pop() on the result to get the first record.
Even if array_filter returns one record, it will still be in the original array with the same key.
array_filter returns the array elements with their keys intact depending upon your filter function. So the keys (0, 1 etc) are the keys in your original array. Use array_pop to get the only element in your array.

php json_decode return [object Object]

I have a problem with JSON data in PHP. I need to use data from this JSON in my SQL statement. When I'm trying to debug it with echo(var_dump, or print_r is not working too) command the output with is
{"records":"tekst","name":"[object Object]"}
This is a JSON structre:
{
records: 'tekst',
name: {
imie: 'imie1',
nazwisko: 'nazwisko1'
}
}
I'm trying to decode this by json_decode(), but I have an error
"Warning: json_decode() expects parameter 1 to be string, array
given".
Does anyone know what's wrong?
PHP manual about JSON and the format required: function.json-decode. basically, double quotes only and names must be quoted.
a demonstration of conversion using PHP.
So, you supply the json string that looks like, with the whitespace removed, like this:
{records:[{id:1,name:'n1'},{id:2,name:'n2'}]}
Which is an object containing an array with two entries that could be arrays or objects.
Except, it is not a valid JSON string as it contains single quotes. And PHP wants all the names in double quotes, as in "id":1.
So, possible PHP code to recreate that, assuming arrays as the inner entries is:
$json = new stdClass();
$records = array();
$entry = array('id' => 1, 'name' => 'n1');
$records[] = $entry;
$entry = array('id' => 2, 'name' => 'n2');
$records[] = $entry;
$json->records = $records;
$jsonEncoded = json_encode($json);
Which, when 'dump'ed looks like:
object(stdClass)[1]
public 'records' =>
array
0 =>
array
'id' => int 1
'name' => string 'n1' (length=2)
1 =>
array
'id' => int 2
'name' => string 'n2' (length=2)
Now, the string that structure produces is:
{"records":[{"id":1,"name":"n1"},{"id":2,"name":"n2"}]}
Which looks similar to yours but is not quite the same. Note the names in double quotes.
However, if your json string looked the same then PHP could decode it, as is shown below:
$jsonDecoded = json_decode($jsonEncoded);
var_dump($jsonDecoded, 'decoded');
Output: Note all objects...
object(stdClass)[2]
public 'records' =>
array
0 =>
object(stdClass)[3]
public 'id' => int 1
public 'name' => string 'n1' (length=2)
1 =>
object(stdClass)[4]
public 'id' => int 2
public 'name' => string 'n2' (length=2)
We may want arrays instead so use the true as the second parameter in the 'decode'
$jsonDecoded = json_decode($jsonEncoded, true);
var_dump($jsonDecoded, 'decoded with true switch');
Output: with arrays rather than objects.
array
'records' =>
array
0 =>
array
'id' => int 1
'name' => string 'n1' (length=2)
1 =>
array
'id' => int 2
'name' => string 'n2' (length=2)
string 'decoded with true switch' (length=24)

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']; }

Categories