Add property foreach object with php - php

I have two arrays object:
$seo_items = collect($resource->items)->values();
$api_items = collect($api_items)->values();
And, I want to iterate these elements and add the property size, which belongs to the $api_items array to the $seo_items array.
foreach($seo_items as &$seo_item)
{
foreach($api_items as $item)
{
if($item->article_id == $seo_item->article->article_erp_id)
{
$seo_item->article->size == $item->size;
$items_result[] = $seo_item;
}
}
}
The problem is that I can not assign this value, because php report this error:
Undefined property: stdClass::$size
How can I do this ?

Seems it is result of typing.
You have used == ( comparison operator), which is comparing with property which doesn't exist,instead of assigning the value.
$seo_item->article->size == $item->size;
changing it to
$seo_item->article->size = $item->size;
Should resolve your problem.

Related

MySQL weird behavior with null integer

So I'm trying to implement php-etl to my application and MySQL doesnt let me insert null to nullable integer but it does if I manually change it, like this:
### This works ###
foreach($data as $row){
if($row["some_integer"] == Null){
$row["some_integer"] = Null;
}
if($row["some_other_integer"] == Null){
$row["some_other_integer"] = Null;
}
MyModel::create($row);
}
### This throws General error: 1366 Incorrect integer value ###
foreach($data as $row){
MyModel::create($row);
}
Tried both manually and with marquine/php-etl package. The input is csv file, null is empty space between ;; separators. Anybody knows what is going on here? Working on laravel 7.
Ok so the package loads the values as empty strings and by setting it Null it becomes real null... Is there a way to quicky convert these values to null?
MySQL won't treat an empty string as null, simply because an empty string and null are two different things. So the message you get from MySQL isn't weird, it's correct.
Nullify all empty strings in an array
If you just want to nullify all empty strings in an array, you can create a simple function for it:
function nullifyEmptyStrings(array $array)
{
return array_map(function ($item) {
return $item !== '' ? $item : null;
}, $array);
}
Then call it where ever/when ever you need it:
$row = nullifyEmptyStrings($row);
or use it directly in the argument for the create function:
MyModel::create(nullifyEmptyStrings($row));
Here's a demo
Nullify specific empty strings in an array
If you want to be able to define which array items to nullify, you can use this function:
function nullifyEmptyArrayValues(array $array, array $keys)
{
foreach ($keys as $key) {
if (array_key_exists($key, $array) && $array[$key] === '') {
$array[$key] = null;
}
}
return $array;
}
And in your code, you first pass the array containing the data and then another array with the keys to nullify, if the values are empty:
$row = nullifyEmptyArrayValues($row, ['some-key', 'another-key']);
Here's a demo

Checking if an array key exists

I have a multidimensional array produced by json_decode(). The json is dynamically generated, that means some keys will be present randomly.
I would like to avoid Undefined index: notice, so i encapsulated the calls to the array in a function like this:
function exists($value) {
if (isset($value)) {
return $value;
}
}
I then call data:
$something = exists($json_array['foo']['bar']['baz']);
But i still get the Undefined index: baz notice. Any suggestions?
It seems you are new to PHP, so I'll give a bit lengthier answer than normal.
$something = exists($json_array['foo']['bar']['baz']);
This is equivalent to what you wrote:
$baz = $json_array['foo']['bar']['baz'];
$something = exists($baz);
As you may have noticed, this means that $json_array['foo']['bar']['baz'] is evaluated before it's passed to exists(). This is where the undefined index is coming from.
The correct idiom would be more like this:
$something = NULL;
if (isset($json_array['foo']['bar']['baz'])) {
$something = $json_array['foo']['bar']['baz'];
}
The following is also identical to the above lines:
$something = isset($json_array['foo']['bar']['baz'])
? $json_array['foo']['bar']['baz']
: NULL;
You would have to chain the exists calls one by one, because you are trying to dereference the array before you send it to the exists function.
See this question for more info: Check if a "run-time" multidimensional array key exists
$json_array['foo']['bar']['baz'] fails when you pass it as an argument, before it's passed to isset(). That is your problem.

Undefined Index in php array

Looking to get a count of particular key=>values in an multi dimensional array. What I have works i.e. the result is correct, but I can't seem to get rid of the Undefined Index notice.
$total_arr = array();
foreach($data['user'] as $ar) {
$total_arr[$ar['city']]++;
}
print_r($total_arr);
Any ideas? I have tried isset within the foreach loop, but no joy...
$total_arr = array();
foreach($data['user'] as $ar) {
if(array_key_exists($ar['city'],$total_arr) {
$total_arr[$ar['city']]++;
} else {
$total_arr[$ar['city']] = 1; // Or 0 if you would like to start from 0
}
}
print_r($total_arr);
PHP will throw that notice if your index hasn't been initialized before being manipulated. Either use the # symbol to suppress the notice or use isset() in conjunction with a block that will initialize the index value for you.

Items in Arrays, are they references?

look at the code below:
$index = GetIndexForId($itemid);
$item = null;
if( $index == -1 )
{
$item = array();
$this->items[] = $item;
$index = count($this->items)-1;
}
else
$item = $this->items[$index];
$item['id'] = $itemid;
$item['qty'] = $qty;
$item['options'] = $options;
$this->items[$index] = $item; // This line is my question
The last line, is it necessary? I really dont know how php handles array assignment.
P.S. GetIndexForId just searches for if the current ID already exists in the array, and the other "undeclared" variables are parameters.
From the documentation:
Array assignment always involves value copying. Use the reference operator to copy an array by reference.
So yes, given your code, the last line is necessary, but $this->items[] = $item; is superfluous.
If you want to update your Object, yes you need this last line
Any value type like boolean, int... will not be passed by reference. But if your array is filled with objects, it WILL be passed by reference. In your exemple, you need the last line. But as I said, if $item were an object you wouldn't need the last line. It is possible to pass a value type by reference with the reference operator.
Learn how to use the reference operator
HERE

what is the fastest method to check if given array has array or non-array or both values?

We gave a given array which can be in 4 states.
array has values that are:
only arrays
only non-arrays
both array and non array
array has no values
Considering than an array-key can only be a numerical or string value (and not an array), I suppose you want to know about array-values ?
If so, you'll have to loop over your array, testing, for each element, if it's an array or not, keeping track of what's been found -- see the is_array function, about that.
Then, when you've tested all elements, you'll have to test if you found arrays, and/or non-array.
Something like this, I suppose, might do the trick :
$has_array = false;
$has_non_array = false;
foreach ($your_array as $element) {
if (is_array($element)) {
$has_array = true;
} else {
$has_non_array = true;
}
}
if ($has_array && $has_non_array) {
// both
} else {
if ($has_array) {
// only arrays
} else {
// only non-array
}
}
(Not tested, but the idea should be there)
This portion of code should work for the three first points you asked for.
To test for "array has no value", The fastest way is to use the empty() language construct before the loop -- and only do the loop if the array is not empty, to avoid any error.
You could also count the number of elements in the array, using the count() function, and test if it's equal to 0, BTW.
Some precalculation:
function isArray($reducedValue, $currentValue) {
// boolean value is converted to 0 or 1
return $reducedValue + is_array($currentValue);
}
$number_of_arrays = array_reduce($array, 'isArray', 0);
Then the different states can be evaluated as follows:
only arrays
count($array) == $number_of_arrays
only non-arrays
$number_of_arrays == 0
both array and non array keys
count($array) != $number_of_arrays
array has no keys
empty($array);
So you just need to write a function that returns the appropriate state.
Reference: in_array, array_reduce, empty

Categories