1

The title may be sound confusing so here is the code to explain clearly.

I wrote the following code in a PHP script

    $options=array(
        CURLOPT_URL => 'http://site2sms.com/userregistration_next.asp',
        CURLOPT_REFERER => 'http://site2sms.com/UserRegistration_Next.asp',
        CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31',
        CURLOPT_POST => TRUE,
        CURLOPT_POSTFIELDS => http_build_query($post_fields)
    );

But, when the dump the array using var_dump function here is what I got

array (size=5)
  10002 => string 'http://site2sms.com/userregistration_next.asp' (length=45)
  10016 => string 'http://site2sms.com/UserRegistration_Next.asp' (length=45)
  10018 => string 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31' (length=108)
  47 => int 1
  10015 => string 'action=UserCreate&txtFullName=fdsf&genderCombo=Male&birth_day=2&birth_month=12&birth_year=2013&txtEmail=fdsf%40dssad&ProfessCombo=1&StateCombo=Delhi&txtMobileNum=4234&cityCombo=223&Submit=Register' (length=196)

Clearly, the value of constant CURLOPT_URL is replaced by 10002 in its dump. So, I replaced the original array by this

    $options=array(
        'CURLOPT_URL' => 'http://site2sms.com/userregistration_next.asp',
        'CURLOPT_REFERER' => 'http://site2sms.com/UserRegistration_Next.asp',
        'CURLOPT_USERAGENT' => 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31',
        'CURLOPT_POST' => TRUE,
        'CURLOPT_POSTFIELDS' => http_build_query($post_fields)
    );

to get this dump value

array (size=5)
  'CURLOPT_URL' => string 'http://site2sms.com/userregistration_next.asp' (length=45)
  'CURLOPT_REFERER' => string 'http://site2sms.com/UserRegistration_Next.asp' (length=45)


  'CURLOPT_USERAGENT' => string 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31' (length=108)
  'CURLOPT_POST' => boolean true
  'CURLOPT_POSTFIELDS' => string 'action=UserCreate&txtFullName=fdsf&genderCombo=Male&birth_day=2&birth_month=12&birth_year=2013&txtEmail=fdsf%40dssad&ProfessCombo=1&StateCombo=Delhi&txtMobileNum=4234&cityCombo=485&Submit=Register' (length=196)

Now, I am getting an error Warning: curl_setopt_array(): Array keys must be CURLOPT constants or equivalent integer values. So, How can I tweak the array so that dumping array shows constant name not value and when used with curl_setopt_array it should work nicely. I am looking for some function that can be used a step earlier than curl_setopt_array function so that it can make necessary changes to array. If it is not possible through PHP built in functions please suggest me how to create this function manually.

3
  • Note: I have raised this question out of curiosity. I am learning PHP these days Commented Dec 18, 2013 at 23:57
  • 2
    You could keep your string keys, but utilize constant() for passing its keys to _setopt. Commented Dec 18, 2013 at 23:59
  • @mario How can I implement this in my array? Is there some built in functions for it or I should for each loop for it. Commented Dec 19, 2013 at 0:02

3 Answers 3

2

There's even a compact way for that:

curl_setopt_array($ch,
    array_combine(
        array_map("constant", array_keys($options)),
        array_values($options)
    )
);

To explain this a little:

  • constant() converts a stringy constant name to its value

  • array_keys() just extracts the keys from your $options array

  • array_map() applys constant to each key, returning its value, but keeps the order of the now integer-key list

  • array_values() returns the indexed list of your $options values

  • finally array_combine() remerges the both-still-in-order numeric keys with their values

Since you mostly need this for commanding curl, I'd also like to present a little alternative here. Not for the overall question, but the concrete task at hand.

I'm personally using a small hybrid/fluent wrapper curl.php for such things. It's possibly often shorter than the array options approach:

$result =
    curl()
       ->URL('http://site2sms.com/userregistration_next.asp')
       ->REFERER('http://site2sms.com/UserRegistration_Next.asp')
       ->USERAGENT('Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/')
       ->POST(true)
       ->POSTFIELDS(http_build_query($post_fields))
       ->exec();

Which reduces all the curl_ function and CURL_ constant prefixes.
(But it still had ->setopt_array() available, btw.)

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

9 Comments

This is an accident waiting to happen! If used inside a class, it will prefer a method named "constant" to the global function.
@EugenRieck I'm not sure I've ever seen array_map call up a method without passing [$this,'method'].
Just try it out, inside a class, where a method has the same name as a global function. Verified on PHP 5.3.10-1ubuntu3.9 with Suhosin-Patch right now. (I was bitten by this in the past ...)
@EugenRieck Seriously, you have to show me. Can't reproduce it with either 5.3.10-1ubuntu3.8+suhosin, 5.4.8, 5.5.5, 5.2.2, 5.1.0, 5.0.5 or 4.4.7.
Don't know how this will format: <?php define('FOO_CONST','BAR-NAME'); class foo { function constant($name) {return "foo-name";} function test() {return constant('FOO_CONST');} } echo foo::test(); ?> outputs 'foo-name'
|
1

Here's an example dump function for this. Pass it the array and a prefix of the constants it'll use for the map.

<?php

function const_keyed_array_dump($arr, $const_prefix) {
        static $map = array();

        // Primative caching
        if (!$map) {
                foreach (get_defined_constants() as $name=>$val) {
                        if (strpos($name, $const_prefix) === 0) {
                                $map[$val] = $name;
                        }
                }
        }

        $output = array();

        foreach ($arr as $key=>$val) {
                $output[$map[$key]] = $val;
        }

        return $output;
}

var_dump(
        const_keyed_array_dump(
                array(
                        CURLOPT_DNS_USE_GLOBAL_CACHE => 'foo',
                        CURLFTPSSL_TRY => 'bar',
                ),
                'CURL'
        )
);

Comments

-1

CURLOPT_URL (without quotes) is just another name for the integer 10002 - the moment you use it, it is translated. This is a one-way process!

If you want to use the string representation, you need either interims table:

$dumpableoptions=array(
    'CURLOPT_URL' => 'http://site2sms.com/userregistration_next.asp',
    ...
);

$translations=array(
    'CURLOPT_URL' => CURLOPT_URL,
    ...
);

and later

$options=array();
foreach ($dumpableoptions as $key=>$value)
  $options[$translations[$key]]=$value;

or you have to make use of the horror of horrors: eval(). I am not willing to provide code for that.

EDIT

After reading @mario's comment, I found out, that after developing in PHP since version 2 I still have lots to learn! I simply didn't know the constant() function. This changes a lot:

  • forget the interims table, it is inside the cURL extension
  • change the later code to

.

$options=array();
foreach ($dumpableoptions as $key=>$value)
  $options[constant($key)]=$value;

2 Comments

@mario again got another advanced way for that.
@VarunAgw And as I commented there, it has a big disadvantage!

Your Answer

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