【问题标题】:Passing an argument to callback function working on an array将参数传递给处理数组的回调函数
【发布时间】:2023-03-17 23:09:01
【问题描述】:

我正在使用一个外部类 (Zebra_cURL) 来执行多个 HTTP GET 请求。它的工作方式如下:

$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);
}

所以我的回调应该用每个 url 的更多信息填充我的 $items 数组(在我的情况下 - 页面大小)。所以缺少一个$key 变量。

这个类支持回调中的额外参数(在我的例子中是$moreimfo)。但据我了解,传递给每个回调的数据将始终相同。

$result 包含原始 url 信息的对象 ($result->info['url'])。所以我可以用它来找到需要的数组元素。但是,如果数组的大小足够大,这看起来效率太低了。

我认为我应该找到如何为每个回调执行传递数组成员键信息。不修改原来的类可以吗?

【问题讨论】:

  • “不修改原来的类”——我不这么认为。但由于它“只是”一个哈希表查找,数组必须变得多大才能让这个变得难以忍受?
  • @VolkerK 实际上我不知道。我只是认为数组上的strcmp 应该比通过 known 键选择正确的元素要慢得多。所以也许我应该跳过我的不喜欢并使用strcmp,但看到代码效率低下我只是感到紧张。
  • 为什么是strcmp?如果您使用带有字符串作为键的数组,则在访问数组元素时会对字符串进行哈希处理,并且访问速度非常快。
  • 哦,我今天瞎了.... 以为 url 是数组的键。没关系 ;-) 但是可以使用 url 作为 $items 中的键而不是 0,1,2,3 吗?
  • @VolkerK 嗯...没想到!谢谢你的想法!

标签: php arrays curl callback


【解决方案1】:

如果您使用 url 作为 $items 数组中的键,则解决方案可能类似于

<?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);
    }
);

使用 anymous function 通过引用“导入”$items 数组。

【讨论】:

【解决方案2】:

虽然它没有解决将相应数组元素的引用传递给回调的原始问题,但以下应该非常快(如 cmets 中所述,PHP 数组是使用实现的哈希表)。

$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);
}

您可能会考虑使用 OOP 方法,将回调作为一种方法,那么如果您使用 $this-&gt;anyMember,则数组的 global-izing 应该是不必要的

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-20
    • 2011-03-28
    • 2011-10-05
    • 1970-01-01
    相关资源
    最近更新 更多