Using cURL Handle as Array Key
Asked Answered
B

3

5

I'm using curl_multi functions to request multiple URLs and process them as they complete. As one connection completes all I really have is the cURL handle (and associated data) from curl_multi_info_read().

The URLs come from a job queue, and once processed I need to remove the job from the queue. I don't want to rely on the URL to identify the job (there shouldn't be duplicate URLs, but what if there is).

The solution I've worked up so far is to use the cURL handle as an array key pointing to the jobid. Form what I can tell, when treated as a string the handle is something like:

"Resource id #1"

That seams reasonably unique to me. The basic code is:

$ch = curl_init($job->getUrl());
$handles[$ch] = $job;
//then later
$done = curl_multi_info_read($master);
$handles[$done['handle']]->delete();
curl_multi_remove_handle($master, $done['handle']);

Is the cURL handle safe to use in this way?

Or is there a better way to map the cURL handles to the job that created them?

Bauble answered 11/2, 2010 at 15:53 Comment(0)
A
2

It will probably work thanks to some implicit type cast, but it doesn't feel right to me at all. I think it's begging for trouble somewhere down the line, with future versions that treat resources differently, different platforms...

I personally wouldn't do it, but use numeric indexes.

Adkins answered 11/2, 2010 at 15:57 Comment(2)
But with numeric indexes I'd still have to somehow map the original job to the cURL handle. You think array_search($ch, $jobs) would work?Bauble
@Tim I don't know, you'd have to try... True, you'd have to map the original job somehow with a numeric index, but IMO it's worth the effort. array[$ch] smells really evil!Adkins
G
9

Store private data inside the cURL easy handle, e.g. some job ID:

curl_setopt($ch, CURLOPT_PRIVATE, $job->getId());
// then later
$id = curl_getinfo($done['handle'], CURLINFO_PRIVATE);

This "private data" feature is not (yet) documented in the PHP manual. It was introduced already in PHP 5.2.4. It allows you to store and retrieve a string of your choice inside the cURL handle. Use it for a key that uniquely identifies the job.

Edit: Feature is now documented in the PHP manual (search for CURLOPT_PRIVATE within the page).

Gonsalez answered 11/10, 2014 at 15:38 Comment(1)
I don't know why it is'nt the accepted answer. It's a working solution (I've tested it), and the other answers only tell what's wrong...Holm
A
2

It will probably work thanks to some implicit type cast, but it doesn't feel right to me at all. I think it's begging for trouble somewhere down the line, with future versions that treat resources differently, different platforms...

I personally wouldn't do it, but use numeric indexes.

Adkins answered 11/2, 2010 at 15:57 Comment(2)
But with numeric indexes I'd still have to somehow map the original job to the cURL handle. You think array_search($ch, $jobs) would work?Bauble
@Tim I don't know, you'd have to try... True, you'd have to map the original job somehow with a numeric index, but IMO it's worth the effort. array[$ch] smells really evil!Adkins
P
2

I have to agree with Pekka... it will probably work but it smells bad. id use straight up integers as Pekka suggests or wrap the handles in a simple class and then use spl_object_hash or have the constructor generate a uniqid when its set up.

Palatable answered 11/2, 2010 at 16:5 Comment(3)
Not sure wrapping the handles in a class helps, because all I get back from curl_multi_info_read() is the [unwrapped] handle.Bauble
Yeah i guess youd have to make a wrapper for the curl_multi functionality as well.Palatable
That doesn't really make sense. I'm at this same problem, so creating a wrapper will still leave us with the problem that the only thing we have is the handle. The idea is we want O(1) lookup using a hash map of some sort. But, what's the best way to get a key value based on the resource. And of course... Yo dawg, I got a wrapper for your wrapper so you can wrap while you're wrapping.Despite

© 2022 - 2024 — McMap. All rights reserved.