views:

819

answers:

4

I would like to upload a photo to facebook for a user in the default album for an application. This is described under publishing here: http://developers.facebook.com/docs/reference/api/photo

The method has been answered here: http://stackoverflow.com/questions/2964410/how-can-i-upload-photos-to-album-using-facebook-graph-api. I am using the following:

$args = array(
  'message' => 'Photo Caption', 
  'image' => '@'.realpath("image.png")
);
$data = $facebook->api('/me/photos', 'post', $args);

However I get the exception "(#324) Requires upload file" when I attempt this. I have a valid session and I have the publish_stream and user_photos permissions. I can retrieve data using the API. The image file is definitely valid because it can be loaded with file_get_contents(realpath("image.png")).

I've tried this solution, using curl, which works perfectly: http://stackoverflow.com/questions/2718610/upload-photo-to-album/2728275#2728275

$args = array(
  'message' => 'Photo from application',
  'pic.png' => '@'.realpath('pic.png')
);
$tok = $session['access_token']
$url = 'http://graph.facebook.com/'.$album_id.'/photos?access_token='.$tok;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $args);
$data = curl_exec($ch);

Compared with Facebook's PHP SDK curl which looks like this (using the same $args and $url):

$ch = curl_init();
$opts = self::$CURL_OPTS;
$opts[CURLOPT_POSTFIELDS] = http_build_query($args, null, '&');
$opts[CURLOPT_URL] = $url;
curl_setopt_array($ch, $opts);
$data= curl_exec($ch);

Why doesn't the PHP version work? Looks like the http_build_query() function is interfering with loading the image. I don't know enough about curl to understand what's going on here.

A: 

I am also trying to upload photo but it is not working in mycase as well. Did u got any solution if yes could you please share it.

I am trying the below code //upload photo $file= '/path/filename.jpg';

$args = array( 'message' => 'Photo from application', );

$args[basename($file)] = '@' . realpath($file);

$ch = curl_init();

$url = 'http://graph.facebook.com/'.$album_id.'/photos?access_token='.$access_token;

curl_setopt($ch, CURLOPT_URL, $url);

curl_setopt($ch, CURLOPT_HEADER, false);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

curl_setopt($ch, CURLOPT_POST, true);

curl_setopt($ch, CURLOPT_POSTFIELDS, $args);

$data = curl_exec($ch);

//returns the photo id print_r(json_decode($data,true));

Akhilesh
Next time put this as a comment, rather than an answer.
peterjwest
peterjwest
A: 

Facebook have intentionally transformed the POST fields to a GET string using http_build_query() to stop fields beginning with @ being used to accidentally or maliciously to upload files. Here's the GitHub issue.

A quick fix for this is to remove the http_build_query() from src/facebook.php in the SDK:

$opts[CURLOPT_POSTFIELDS] = http_build_query($params, null, '&');

Becomes:

$opts[CURLOPT_POSTFIELDS] = $params;

However if you do this you should take action to filter user generated messages that start with @. For example you could add a space to the front of each message.

peterjwest
A: 

If you use graph api to upload the photo it will getting the error (#200) User must have accepted TOS.

However if you use old rest api, just changing the url to https://api.facebook.com/method/photos.upload?access_token=xXXXXXXXXXXX if you use above example.

Illusionicea
+1  A: 

I'm so glad I went trough the same problem You have to set the fileUpload param to true !

$facebook = new Facebook(array(
            'appId'  => $facebookapi_id,
            'secret' => $facebookapi_secret,
            'fileUpload' => true,
            'cookie' => true
          ));  
Agence Webmarketing
Thanks so much for this - saved me after a long time of searching
Lobe
If you use this, be aware that user created messages could create unintentional or malicious file uploads.
peterjwest