Opening for full documentation purposes.

$url = 'https://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452';
$client = new \GuzzleHttp\Client;
$response = $client->get($url, [
  'headers' => ['Accept' => application/json],
])->getBody();
$array = json_decode($response, TRUE);
$iterator = new \RecursiveIteratorIterator(
  new \RecursiveArrayIterator($array),
  \RecursiveIteratorIterator::SELF_FIRST);
// Recurse through the result array. When there is an array of items at the
// expected depth that has the expected identifier as one of the keys, pull that
// array out as a distinct item.
$identifier = 'place_id';
$identifierDepth = 1;
$items = [];
while ($iterator->valid()) {
  $iterator->next();
  $item = $iterator->current();  // TO FIX: Segfaults on last row from gmap data.
  if (is_array($item)) {
    if (array_key_exists($identifier, $item)) {
      if ( $iterator->getDepth() == $identifierDepth) {
        $items[] = $item;
      }
    }
  }
}

Comments

heddn created an issue. See original summary.

heddn’s picture

Status: Active » Postponed
heddn’s picture

Priority: Normal » Critical
Status: Postponed » Needs review
StatusFileSize
new656 bytes

Seems we can do something to fix the code while we wait for a fix upstream. Bumping priority because this fails on a supported version of PHP.

Conversation from #php

08:07 can anyone else running php 7.0.2 confirm https://bugs.php.net/bug.php?id=71495
08:11 heddn: segfault confirmed: https://3v4l.org/09Khf
08:19 heddn: I fixed your code: https://3v4l.org/GKqK6
08:29 Naktibalda: was it just moving the $iterator->next() ?
08:29 heddn: yes
08:30 heddn: your code runs ->current() after next() when iterator is no longer valid

Status: Needs review » Needs work

The last submitted patch, 3: migrate_source_json-php_7_seg_fault-2660670-3.patch, failed testing.

heddn’s picture

Failure in #4 is related to https://groups.drupal.org/node/508662 and reported in #drupal-testing. This still needs review.

heddn’s picture

Status: Needs work » Needs review
mcrittenden’s picture

Status: Needs review » Reviewed & tested by the community

This seems to fix the issue for me - we got segfaults before the patch and working migrations after, on PHP 7.

mikeryan’s picture

Status: Reviewed & tested by the community » Needs work

Doesn't moving the next() from before the current() to after the current() change what item current() returns?

heddn’s picture

I think before it was skipping the first record. Or am I reading that incorrectly? The (bug?) in php 7 is that calling next on something that has passed its end point will cause a seg fault.

dhansen’s picture

I think the issue with the placement of the next() is more of an idiosyncrasy of the RecursiveIteratorIterator class than anything else.

I'm guessing that the reason the $iterator->next(); was put before the call to $iterator->current(); was to avoid double-importing the first record in the while loop. You can see this behavior discussed at length on http://stackoverflow.com/questions/13555884/recursiveiteratoriterator-re.... You can also see the #3 patch having the same issue if you check migrate-status before your import. It'll likely have one extra record which cannot be imported because it's a duplicate ID; that's the repeated first record.

Note that this is not a bug. By design the Iterator collection was to be consumed by foreach loops, not while loops, and so the constructor being used in the foreach loops implements the rewind already to prevent duplication. You can see that in the comments on this bug report: https://bugs.php.net/bug.php?id=44063

Anyways the solution here I think is just to put a rewind before the loop and move the next() call to after the current() call (thus keeping the valid() call honest). That should keep it working fine in PHP 5 and fix it for the apparently-stricter (who knew?) PHP 7. Alternatively, we could consume the iterator with a foreach loop, but I prefer the while.

dhansen’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 10: migrate_source_json-php_7_seg_fault-2660670-10.patch, failed testing.

dhansen’s picture

Status: Needs work » Needs review

The failures in #12 are not related to the JSONReader, but rather JSONSource and JSONMultiSource (which is still labeled per the project description as "very experimental"). This still needs review.

tobby’s picture

The latest patch in #10 works for me and fixes my segfault issues.

tobby’s picture

Status: Needs review » Reviewed & tested by the community
nlisgo’s picture

I have been experiencing this issue. I applied the patch in #10 in combination with #2731697-2: JSON parser triggers segfault with PHP7 and I am now able to perform 'drush ms' without experiencing a 'Segmentation Fault'.

I am now going to see if both patches are necessary to clear the issue for me. And report back.

nlisgo’s picture

After looking into this further I realise that a json parser has been adopted directly into the 2.x branch of migrate_plus which brings into question whether there is any need for this module going forward. I will not be doing any more work on this issue until I have clarification on the future of this module.

mikeryan’s picture

Status: Reviewed & tested by the community » Closed (won't fix)

This module has been superseded by the json parser plugin in migrate_plus and is no longer supported.