1

I'm using an external class (Zebra_cURL) to execute multiple HTTP GET requests. It worked in the following way:

$items = array(
    0=>array('url' => 'url0'),
    1=>array('url' => 'url1'),
    2=>array('url' => 'url2'),
    3=>array('url' => 'url3'),
);
$curl = new Zebra_cURL();
$curl->get(array_column($urls,'url'),'scan_item',$moreimfo);

function scan_item($result,$moreimfo){
    $items[$key]['size'] = strlen($result->body);
}

So my callback should fill up my $items array with more info for each url (in my case - size of the page). So there is a missing $key variable.

This class supports extra parameters in the callbacks ($moreimfo in my case). BUT as I understand the data passing to each callback will be always the same.

$result object containing the original url info ($result->info['url']). So I COULD use it to find needed array element. However this looks too inefficient in case the size of an array will be big enough.

I think that I should find how to pass an array member key information for EACH callback execution. Is it possible without modifying the original class?

5
  • "without modifying the original class" - i don't think so. But since it's "only" a hashtable lookup how big must the array become for this to become unbearable? Commented Oct 6, 2015 at 10:43
  • @VolkerK I don't know actually. I just think that strcmp on an array should be much slower than picking the right element by its known key. So maybe I should skip my dislike and use strcmp but I just feel jittery seeing the inefficiency of the code. Commented Oct 6, 2015 at 10:48
  • 1
    Why strcmp? If you use an array with a string as a key, the string get's hashed when accessing the array element and the access is blazingly fast. Commented Oct 6, 2015 at 10:51
  • 1
    Oh, I'm blind today.... thought the url was the key of the array. Nevermind ;-) But would it be possible to use the url as the key in $items instead of 0,1,2,3? Commented Oct 6, 2015 at 10:51
  • @VolkerK Hm... Didn't think about it! Thank you for an idea! Commented Oct 6, 2015 at 10:52

2 Answers 2

2

If you use the url as key in the $items array the solution could be something like

<?php
$items = [
  'url0'=>array('url' => 'url0'),
  'url1'=>array('url' => 'url1'),
  'url2'=>array('url' => 'url2'),
  'url3'=>array('url' => 'url3'),
];
$curl = new Zebra_cURL();
$curl->get(
    array_keys($items),
    function($result) use (&$items) {
        $key = $result->info['url'];
        $items[$key]['size'] = strlen($result->body);
    }
);

using an anymous function that "Imports" the $items array via reference.

Sign up to request clarification or add additional context in comments.

2 Comments

Never heard about function use syntax. Interesting!
Never hear of function use neither! here's how I do it: github.com/stefangabos/Zebra_cURL/issues/15
1

While it doesn't solve the original problem of passing a reference to the according array element to the callback, the following should be very fast (as noted in the comments, PHP Arrays are implemented using a hashtable).

$items = array(
    0=>array('url' => 'url0'),
    1=>array('url' => 'url1'),
    2=>array('url' => 'url2'),
    3=>array('url' => 'url3'),
);

$lookup=array();
foreach($lookup as $k=>$v) {
    $lookup[$v['url']]=$k;
}

$curl = new Zebra_cURL();
$curl->get(array_column($urls,'url'),'scan_item',$moreimfo);

function scan_item($result,$moreimfo){
    global $lookup,$items;
    $items[$lookup[$result->info['url']]]['size'] = strlen($result->body);
}

Probably you may consider using an OOP-approach, with the callback as a method, then the global-izing of the arrays shouldn't be necessary if you use $this->anyMember

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.