I am currently inserting data from json api url into my database, except some arrays are not completed filled out resulting in 'undefined index' errors.
Is there a good way to deal with this? Ofcourse checking each item index with an if isset statement and only setting it if it is available would work but that would be quite tedious for each entry.
foreach($items['response']['groups'] as $item) {
foreach($item['items'] as $item) {
Bar::firstOrCreate([
'lat' => $item['venue']['location']['lat'],
'long' => $item['venue']['location']['lng'],
'postalCode' => $item['venue']['location']['postalCode'],
'city' => $item['venue']['location']['city'],
'state' => $item['venue']['location']['state'],
'country' => $item['venue']['location']['country'],
'address' => $item['venue']['location']['address'],
'rating' => $item['venue']['rating'],
'website' => $item['venue']['url'],
]);
}
}
use simplest way like:
foreach($items['response']['groups'] as $item1) {
foreach($item1['items'] as $item) {
Bar::firstOrCreate([
'lat' => isset($item['venue']['location']['lat'])?$item['venue']['location']['lat'] : '',
'long' => isset($item['venue']['location']['lng'])?$item['venue']['location']['lng'] : '',
'postalCode' => isset($item['venue']['location']['postalCode'])?$item['venue']['location']['postalCode'] : '',
'city' => isset($item['venue']['location']['city'])?$item['venue']['location']['city'] : '',
'state' => isset($item['venue']['location']['state'])?$item['venue']['location']['state'] : '',
'country' => isset($item['venue']['location']['country'])?item['venue']['location']['country'] : '',
'address' => isset($item['venue']['location']['address'])?$item['venue']['location']['address'] : '',
'rating' => isset($item['venue']['rating'])?$item['venue']['rating'] : '',
'website' => isset($item['venue']['url'])?$item['venue']['url'] : '',
]);
}
}
Your problem here is that you rewrite value of $item
on each iteration.
foreach($items['response']['groups'] as $item) {
foreach($item['items'] as $item) {
// after first iteration here `$item` doesn't have `items` key
}
Use different variables in every foreach
.
You will have to check the existence of an index somewhere ! If you don't want to do it in the controller, you could have an entity like which checks every field :
<?php
class MyEntity
{
private $lat;
private $long;
private $postalcode;
...
public static function createInstanceFromArray(array $item)
{
if (isset($item['lat']) {
$this->setLat($item['lat']);
}
... and so on
// you could also do it automatic :
foreach($item as $key => $value) {
$methodName = 'set' . ucfirst($key);
if (method_exists($this, $methodName)) {
$this->{$methodName}($value);
}
}
}
public function setLat($lat)
{
$this->lat = $lat;
return $this;
}
public function getLat()
{
return $this->lat;
}
}
Then you could do the following to your original code :
foreach($items['response']['groups'] as $item) {
foreach($item['items'] as $subItem) {
$myEntity = MyNamespace\MyEntity::cretaInstanceFromArray($subItem['venue']);
}
}
Then you could set the fields of your entity with your methods :
'lat' => $myEntity->getLat();
....
this way, even if the array field does not exists, the entity returns a default value.
If you don't want to use objects, you could use array_merge with default values to ensure you will not have undefindex indexes :
$item = array_merge([
'lat' => '',
'long' => '',
'postalCode' => '',
...
], $item['venue']);
And put that treatment in a function for an exemple.
Check each array for completeness and only Bar::firstOrCreate()
if it's really complete:
foreach($items['response']['groups'] as $item) {
foreach($item['items'] as $item) {
if(
isset($item['venue']) &&
isset($item['venue']['location']) &&
isset($item['venue']['location']['lat']) &&
isset($item['venue']['location']['lng']) &&
isset($item['venue']['location']['postalCode']) &&
isset($item['venue']['location']['city']) &&
isset($item['venue']['location']['state']) &&
isset($item['venue']['location']['country']) &&
isset($item['venue']['location']['address']) &&
isset($item['venue']['location']['lng']) &&
isset($item['venue']['rating']) &&
isset($item['venue']['url'])
)
Bar::firstOrCreate([
'lat' => $item['venue']['location']['lat'],
'long' => $item['venue']['location']['lng'],
'postalCode' => $item['venue']['location']['postalCode'],
'city' => $item['venue']['location']['city'],
'state' => $item['venue']['location']['state'],
'country' => $item['venue']['location']['country'],
'address' => $item['venue']['location']['address'],
'rating' => $item['venue']['rating'],
'website' => $item['venue']['url'],
]);
}
}
you can use these simple steps
remove all the empty nested arrays.
$yourArray= array_map('array_filter', $yourArray);
$yourArray= array_filter( $yourArray);