File upload using curl. What to do when name of input field is in form of array?

Discussion in 'PHP' started by FireFlywins, Nov 30, 2010.

  1. #1
    Hi,

    This is a test code that I made to show the problem:
    
    $useragent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12 ( .NET CLR 3.5.30729)";
    $timeout = 10 ;
    $cookie = tempnam ("/tmp", "CURLCOOKIE");
     
    $post = array('_method'=>"put",
                         'authenticity_token'=>'
    zcvcxfsdfvxcv',
                         'profile_image[a]'=>"@Girl-Next-Door-movie-f01.jpg"
    
                        );
           
            $ch = curl_init();
            curl_setopt( $ch, CURLOPT_USERAGENT, $useragent);
            curl_setopt($ch, CURLOPT_HEADER, 1);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_URL, "http://localhost/test.php");
            curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
            curl_setopt( $ch, CURLOPT_COOKIEJAR, $cookie );
            curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );
            curl_setopt( $ch, CURLOPT_ENCODING, "" );
            curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
            curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
            curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );    # required for https urls
            curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, $timeout );
            curl_setopt( $ch, CURLOPT_TIMEOUT, $timeout );
            curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
            $html = curl_exec($ch);
            curl_close($ch);
    
    PHP:
    Now this link used above: http://localhost/test.php has this code:

    
        print_r($_POST);
        print_r($_FILES);
    
    PHP:
    It simply prints whats in post and files.


    So the above code displays this on screen:
    
    Array
    (
        [_method] => put
    
    
        [authenticity_token] => zcvcxfsdfvxcv
    )
    Array
    (
        [profile_image] => Array
            (
                [name] => Array
                    (
                        [a] => Girl-Next-Door-movie-f01.jpg
    
    
                    )
    
                [type] => Array
                    (
                        [a] => image/jpeg
                    )
    
                [tmp_name] => Array
                    (
                        [a] => /tmp/phppLJPQV
    
    
                    )
    
                [error] => Array
                    (
                        [a] => 0
                    )
    
                [size] => Array
                    (
                        [a] => 55377
    
    
                    )
    
            )
    
    )
    
    Code (markup):
    but we need to modify the code so that it should display this:
    
    Array
    (
        [_method] => put
        [authenticity_token] => zcvcxfsdfvxcv
    
    
    )
    Array
    (
        [profile_image[a]] => Array
            (
                [name] => Girl-Next-Door-movie-f01.jpg
                  
                [type] => image/jpeg
    
                [tmp_name] =>  /tmp/phppLJPQV
    
                [error] =>  0
    
                [size] =>  55377
                    
            )
    
    )
    
    Code (markup):
    Meaning, it is taking this(profile_image[a]) as an array when we are defining $post because that's how curl recognizes that we want to upload only a file or an array of files on server by http post.

    So, basically the problem is the name of the input field that is defined as an array (profile_image[a]) on the web page that we are trying to mock. If this(profile_image[a]) was this (profile_image_a)(without []) on that webpage, then it would not have been a problem. So, if you understand, this is basically a syntax problem. I do not know how stop curl from reading 'profile_image[a]' as an array here 'profile_image[a]'=>"@Girl-Next-Door-movie-f01.jpg. I need curl to read 'profile_image[a]' as an string and not array. I have to use [], otherwise I will not be able to mock the webpage as the name will change. It will give error.


    I hope I explained the problem and also gave you a way to test if you have a solution. Again, if your code starts displaying this:
    
    Array
    (
        [_method] => put
        [authenticity_token] => zcvcxfsdfvxcv
    
    )
    Array
    (
        [profile_image[a]] => Array
    
            (
                [name] => Girl-Next-Door-movie-f01.jpg
                  
                [type] => image/jpeg
                    
                [tmp_name] =>  /tmp/phppLJPQV
    
                [error] =>  0
                    
                [size] =>  55377
                    
            )
    
    )
    
    Code (markup):
    , then we have a solution.

    Thanks for helping in advance.

    Regards,
    Manoj
     
    FireFlywins, Nov 30, 2010 IP
  2. ZoomRumble

    ZoomRumble Peon

    Messages:
    28
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #2
    try this

    adding (string) infront of the array key

    $useragent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12 ( .NET CLR 3.5.30729)";
    $timeout = 10 ;
    $cookie = tempnam ("/tmp", "CURLCOOKIE");
     
    $post = array('_method'=>"put",
                         'authenticity_token'       => 'zcvcxfsdfvxcv',
                         (string)'profile_image[a]' => "@Girl-Next-Door-movie-f01.jpg"
    
                        );
           
            $ch = curl_init();
            curl_setopt( $ch, CURLOPT_USERAGENT, $useragent);
            curl_setopt($ch, CURLOPT_HEADER, 1);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_URL, "http://localhost/test.php");
            curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
            curl_setopt( $ch, CURLOPT_COOKIEJAR, $cookie );
            curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );
            curl_setopt( $ch, CURLOPT_ENCODING, "" );
            curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
            curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
            curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );    # required for https urls
            curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, $timeout );
            curl_setopt( $ch, CURLOPT_TIMEOUT, $timeout );
            curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
            $html = curl_exec($ch);
            curl_close($ch);
    PHP:
     
    ZoomRumble, Nov 30, 2010 IP
  3. ThePHPMaster

    ThePHPMaster Well-Known Member

    Messages:
    737
    Likes Received:
    52
    Best Answers:
    33
    Trophy Points:
    150
    #3
    This isn't a curl "problem", but rater PHP itself. This link should help you understand how PHP parses multiple uploads in PHP:

    http://php.net/manual/en/features.file-upload.multiple.php

    To solve your problem, I would just parse the files array myself:

    
    print_r($_POST);
    print_r($_FILES);
    
    // Now we do our parsing
    parse_r($_FILES);
    print_r($_FILES);
    
    function parse_r(&$files)
    {
          // Check if empty
          if(count($files) <= 0){ return;}
    	
          // Parse array
          $fileList = array();
          foreach($files as $setIndex => $curSet)
          {
                foreach($files[$setIndex]['name'] as $index => $fileName)
                {
    	          $fileList[$setIndex][] = array('name' => $fileName, 'type' => $files[$setIndex]['type'][$index],
    	          'tmp_name' => $files[$setIndex]['tmp_name'][$index], 'error' => $files[$setIndex]['size'][$index],
    		  'error' => $files[$setIndex]['size'][$index]);
    	    }
          }
          $files = $fileList;
    }
    
    PHP:
     
    ThePHPMaster, Nov 30, 2010 IP