Object pushed to array overites - php

I've got strange thing, it's probably simple but I can't find a solution for it. Here is part of the code:
$counter = 0;
$autoload_view_instace = new Logic_InvoiceCostData;
$sub_view_cost = array();
foreach($invoceCostData as $data)
{
$counter++;
$parm = $autoload_view_instace->edit_view_data($autoload_view, $data, $counter);
array_push( $sub_view_cost, $parm);
}
The loop calls the edit_view_data method which returns an object with some values. That object should be placed at the end of the array in each iteration without changing values of objects previously added. But after each iteration, all objects in the array have the same value as the newly added object.

apparently the array_push syntax is correct.. and it should work .. however you can do the same thing using.
$sub_view_cost[]=$parm ;
and make sure each time $parm get the correct value

Related

Foreach loop over array of objects Laravel

I'm receiving this array of objects and need to iterate over it, but the problem is that I need to get the value of the next item when its iterating, to compare the value of the current object with the next one, and if it's a different value, split this array in two.
So, I was doing it with next() php function:
//looking for the next register in the array
$next = next($finances);
//first array if exist different values
$aiuaEd = [];
//second array if exist different values
$aiua = [];
foreach ($finances as $finance) {
if ($finance->cnpj <> $next->cnpj) {
$aiua[] = $finance;
} else {
$aiuaEd[] = $finance;
}
}
This code works fine at some point, but then I got this error:
Trying to get property 'cnpj' of non-object in
I don't know why sometimes works well and sometimes don't, debugging this variables, I found that if my array have 2 objects inside only, when I'm looping over it, the $next->cnpj variable came as empty, and sometimes don't.
Can someone help me with this?
I solved it with a different approach, instead of using php next(), I first loop over this array saving the cnpj's into an array.
$cnpjs = [];
foreach($finances as $finance){
$cnpj[] = $finance->cnpj;
}
Then I use array_unique() to group this 2 differents CNPJ's and sort() to get the correct keys order.
//grouping cnpjs as unique, should exist only 2 keys
$cnpj = array_unique($cnpj);
//sort array keys to get in order
sort($cnpj);
Then I iterate over my $finances array again, but now I'm counting if this $cnpj array has more than 2 positions, which means that I have to split this data in two differents arrays.
foreach($finances as $finance){
if(count($cnpj) > 1){
if($finance->cnpj == $cnpj[1]){
$aiua[] = $finance;
}else{
$aiuaEd[] = $finance;
}
}else{
$aiuaEd[] = $finance;
}
}
I'm pretty sure that this is not the best approach for that problem, or at least the most optimized one, so I'm open for new approach's suggestions!
Just posting how I solved my problem in case anyone having the same one.
Notice that this approach is only usable because I know that will not exist more than 2 different's CNPJ's in the array.

Laravel make array of another array objects

I have general data array and I need to get array of specific data inside this general array so I can match it against my database.
Code
$nums = [];
foreach($request->phones as $phone) {
foreach($phone['_objectInstance']['phoneNumbers'] as $number) {
$nums = $number['value'];
}
}
$contacts = User::whereIn('phone', $nums)->get();
PS: $number['value'] is the data that I want to make array of it.
Sample data that I receive in backend
current error
Argument 1 passed to Illuminate\\Database\\Query\\Builder::cleanBindings() must be of the type array, string given, called in /home/....../vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php on line 918
exception: "TypeError"
Question
How can I make array of my numbers?
Ps: please if you know cleaner way to write this code, than my code above don't hesitate to share with me.
You're assigning $nums to be a new string on every iteration of the loop, rather than appending it to the array.
Just switch this line out:
$nums = $number['value'];
For
$nums[] = $number['value'];
Here are the docs for array_push(), which is the long way of writing the second line.
You are declaring $nums array, but inside the loop, you re-declaring it by a string again.
Fix the array assignments like that.
$nums[] = $number['value'];

php continue "foreach" after return

I am working on a WordPress plugin for a specific theme but have a general question,
I have an array and want to do something with each object and return the result.
everything is Ok but the "foreach" only works for the first object of array and I think its because of "return" but for some reasons I cannot use "echo" instead of return.
this is my code:
$cast_list = array(
"composite_cast",
"graphic_designer_cast",
"product_manager_cast",
"render_cast",
"the3d_cast",
"story_board_cast"
);
foreach ($cast_list as $value)
{
$user_field = get_field($value);
}
return $user_field;
}
I have read other similar topics but passing the variable to another function to do the "return" job for me also not works
Your doubt: the "foreach" only works for the first object of array and I think its because of "return"
No this not for return it's because of variable overwriting inside the foreach() loop every time. Actually you're not returning only the first element, here you're returning the last element because you're overwriting $user_field variable every time within foreach() loop
Try instead to push result to it using $user_field[] and then you're good to go
$cast_list = array(
"composite_cast",
"graphic_designer_cast",
"product_manager_cast",
"render_cast",
"the3d_cast",
"story_board_cast"
);
foreach ($cast_list as $value)
{
$user_field[] = get_field($value);
}
return $user_field;
All the functions work until the return keyword. You need to create a new array and append all the edited elements to it and then return it.
$user_fields = array();
foreach ($cast_list as $value)
{
array_push($user_fields, get_field($value));
}
return $user_fields;
Or you even can work on each field right in the loop and return nothing.

Difference between array_push() and $array[] =

In the PHP manual, (array_push) says..
If you use array_push() to add one element to the array it's better to
use $array[] = because in that way there is no overhead of calling a
function.
For example :
$arr = array();
array_push($arr, "stackoverflow");
print_r($arr);
vs
$arr[] = "stackoverflow";
print_r($arr);
I don't understand why there is a big difference.
When you call a function in PHP (such as array_push()), there are overheads to the call, as PHP has to look up the function reference, find its position in memory and execute whatever code it defines.
Using $arr[] = 'some value'; does not require a function call, and implements the addition straight into the data structure. Thus, when adding a lot of data it is a lot quicker and resource-efficient to use $arr[].
You can add more than 1 element in one shot to array using array_push,
e.g. array_push($array_name, $element1, $element2,...)
Where $element1, $element2,... are elements to be added to array.
But if you want to add only one element at one time, then other method (i.e. using $array_name[]) should be preferred.
The difference is in the line below to "because in that way there is no overhead of calling a function."
array_push() will raise a warning if the first argument is not
an array. This differs from the $var[] behaviour where a new array is
created.
You should always use $array[] if possible because as the box states there is no overhead for the function call. Thus it is a bit faster than the function call.
array_push — Push one or more elements onto the end of array
Take note of the words "one or more elements onto the end"
to do that using $arr[] you would have to get the max size of the array
explain:
1.the first one declare the variable in array.
2.the second array_push method is used to push the string in the array variable.
3.finally it will print the result.
4.the second method is directly store the string in the array.
5.the data is printed in the array values in using print_r method.
this two are same
both are the same, but array_push makes a loop in it's parameter which is an array and perform $array[]=$element
Thought I'd add to the discussion since I believe there exists a crucial difference between the two when working with indexed arrays that people should be aware of.
Say you are dynamically creating a multi-dimensional associative array by looping through some data sets.
$foo = []
foreach ($fooData as $fooKey => $fooValue) {
foreach ($fooValue ?? [] as $barKey => $barValue) {
// Approach 1: results in Error 500
array_push($foo[$fooKey], $barKey); // Error 500: Argument #1 ($array) must be of type array
// NOTE: ($foo[$fooKey] ?? []) argument won't work since only variables can be passed by reference
// Approach 2: fix problem by instantiating array beforehand if it didn't exist
$foo[$fooKey] ??= [];
array_push($foo[$fooKey], $barKey);
// Approach 3: One liner approach
$foo[$fooKey][] = $barKey; // Instantiates array if it doesn't exist
}
}
Without having $foo[$fooKey] instantiated as an array beforehand, we won't be able to do array_push without getting the Error 500. The shorthand $foo[$fooKey][] does the heavy work for us, checking if the provided element is an array, and if it isn't, it creates it and pushes the item in for us.
I know this is an old answer but it might be helpful for others to know that another difference between the two is that if you have to add more than 2/3 values per loop to an array it's faster to use:
for($i = 0; $i < 10; $i++){
array_push($arr, $i, $i*2, $i*3, $i*4, ...)
}
instead of:
for($i = 0; $i < 10; $i++){
$arr[] = $i;
$arr[] = $i*2;
$arr[] = $i*3;
$arr[] = $i*4;
...
}
edit- Forgot to close the bracket for the for conditional
No one said, but array_push only pushes a element to the END OF THE ARRAY, where $array[index] can insert a value at any given index. Big difference.

Assigning object property inside a foreach loop; data does not persist outside foreach loop. Why not? INT and STRING assignment does work

Been knocking my head off the desk on this one all day.
// Iterate over project array to populate release data
for ($i = 0; $i < count($data); $i++) {
$data[$i]->setProjectReleaseSchedule( $proj_scheds[$i] );
//Get each projects Est and Act hours
$options = new stdClass;
$options->default = true;
$options->project_id = $data[$i]->getProjectId();
$options->department_id = $person_dm->getPersonDepartmentId();
//works; AKA: property get assigned an int thatr incriments evern loop
//$data[$i]->data->proj_hours = $this->counter++;
//$weekly_report_dm->getProjectHours returns an object w/ populated properties
$data[$i]->data->proj_hours = $weekly_report_dm->getProjectHours($options);
//As a test, this dumps what is expected...
echo'<pre>';
print_r( $data[$i]->data->proj_hours );
echo'</pre>';
}
echo'<pre>';
//After the loop completes and I try to dump the data the property $data->data->proj_hours is assigned an object..
//but the object properties are all null :(.
print_r( $data );
echo'</pre>';
exit;
So as you can see Im looping over an array of objects; for each object I got another method for data, it returns with expected data. The "print_r( $data[$i]->data->proj_hours );". However, once the loop finishes and I try to dump the data the object is assigned to the parent, but the properties of said object are null/blank.
So the question: Why can I assign INTs, STRINGS, etc to an objects property and they persist outside the foreach loop. But an objects properties when assigned to a parent object inside a foreach loop, the values do not persist?
It seems that weekly_report_dm->getProjectHours($options) returns reference to same private (?) property , which changes each call. You can try to clone the result with clone :
$data[$i]->data->proj_hours = clone $weekly_report_dm->getProjectHours($options);
Changing getProjectHours to not return reference would be the right solution
On top, outside for loop add:
$filler = array();
Inside for loop add this:
$filler[] = $data[$i]->data->proj_hours;
Then try to dump data afterwards.
print_r($filler);
Hope that will bring you some results.

Categories