блогът на belogradchik.biz

Фейсбок(Facebook) АПИ(API) - за ъплоад на снимки

August 5th, 2008 zetxxx

След дълга липса на писания в този блог поради липсата на свободно време реших да запечатамедин код които ми отне 3 часа от живота и както винаги се оказва проблемът е бил в — ( 2-те тиренца ) :(.

Идеята на този класс е да може някои девел. за напред ако има проблем с ъплоад на снимки в фейсбоок да го види да си го копне - да попълни липсващите параметри и наий-вече да му спести работа :).

Лиценза е гну, държа само да се спомене че е моя работа …

ето го и кода

  1. <?php
  2. /**
  3.  * @author Elin Ahmedov
  4.  * @category facebook image upload api
  5.  * @copyright GNU
  6.  * @since 06.08.2008
  7.  * @version 0.1
  8.  */
  9. require_once './client/facebook.php';
  10. class fbPhotoUpload
  11. {
  12.  private $namespace = array();
  13.  
  14.  /**
  15.   * class constructor
  16.   * @return fbPhotoUpload
  17.   */
  18.  
  19.  public function fbPhotoUpload()
  20.  {
  21.   return $this;
  22.  }
  23.  
  24.  /**
  25.   * setting external variables
  26.   *
  27.   * @param string $name
  28.   * @param string $value
  29.   */
  30.  
  31.  public function setVars( $name, $value )
  32.  {
  33.   $this->namespace[$name] = $value;
  34.  }
  35.  
  36.  /**
  37.   * collecting arguments for later signature generation
  38.   *
  39.   * @param string $sig__name
  40.   * @param string $sig__value
  41.   */
  42.  
  43.  private function collect__sig__( $sig__name, $sig__value )
  44.  {
  45.   $this->namespace['__sig__'][$sig__name] = $sig__value;
  46.  }
  47.  
  48.  /**
  49.   * signature generation
  50.   *
  51.   * @param string $text
  52.   * @return string
  53.   */
  54.  
  55.  private function set__sig__( $text )
  56.  {
  57.   $sig = '';
  58.   ksort( $this->namespace['__sig__'] );
  59.   foreach( $this->namespace['__sig__'] as $name=>$value )
  60.    $sig .= $name.'='.$value;
  61.   $this->namespace['__sig__']['sig'] = md5( $sig.$this->namespace['__secret__'] );
  62.   return preg_replace( '/__sig__/i', $this->namespace['__sig__']['sig'], $text );
  63.  }
  64.  
  65.  /**
  66.   * create top headers
  67.   *
  68.   */
  69.  
  70.  private function setReqsHeaders()
  71.  {
  72.   $this->namespace['headers'] = "POST ".$this->namespace['request_file']." HTTP/1.1\r\n";
  73.   $this->namespace['headers'] .= "Host: ".$this->namespace['domain']."\r\n";
  74.   $this->namespace['headers'] .= "User-Agent: Facebook Photo API PHP5 Client 1.0 ".phpversion()."\r\n";
  75.   $this->namespace['headers'] .= "Connection: close\r\n";
  76.   $this->namespace['headers'] .= "Content-type: multipart/form-data, boundary=".$this->namespace['boundary']."\r\n";
  77.   $this->namespace['headers'] .= "Content-Length: __cont_lenght__\r\n";
  78.   $this->namespace['headers'] .= "MIME-version: 1.0\r\n\r\n";
  79.   $this->namespace['headers'] = preg_replace( '/__cont_lenght__/i', strlen( $this->namespace['add.headers'] ), $this->namespace['headers'] ).$this->namespace['add.headers'];
  80.  }
  81.  
  82.  /**
  83.   * create additional headers
  84.   *
  85.   * @param string $content
  86.   */
  87.  
  88.  private function setAdditonalHeaders( $content )
  89.  {
  90.   preg_match( '/(?P<fname>[^\/]*?(?P<fext>[^\.]*))$/i', $this->namespace['file_name'], $matches );
  91.   $this->namespace['add.headers'] = '–'.$this->namespace['boundary']."\r\n";
  92.   $this->namespace['add.headers'] .= "Content-Disposition: form-data; name=\"method\"\r\n\r\n";
  93.   $this->namespace['add.headers'] .= "facebook.photos.upload\r\n";
  94.   $this->namespace['add.headers'] .= '–'.$this->namespace['boundary']."\r\n";
  95.   $this->collect__sig__( 'method', 'facebook.photos.upload' );
  96.   $this->namespace['add.headers'] .= "Content-Disposition: form-data; name=\"v\"\r\n\r\n";
  97.   $this->namespace['add.headers'] .= "1.0\r\n";
  98.   $this->namespace['add.headers'] .= '–'.$this->namespace['boundary']."\r\n";
  99.   $this->collect__sig__( 'v', '1.0' );
  100.   $this->namespace['add.headers'] .= "Content-Disposition: form-data; name=\"api_key\"\r\n\r\n";
  101.   $this->namespace['add.headers'] .= $this->namespace['__api_key__']."\r\n";
  102.   $this->namespace['add.headers'] .= '–'.$this->namespace['boundary']."\r\n";
  103.   $this->collect__sig__( 'api_key', $this->namespace['__api_key__'] );
  104.   $this->namespace['add.headers'] .= "Content-Disposition: form-data; name=\"session_key\"\r\n\r\n";
  105.   $this->namespace['add.headers'] .= $this->namespace['__session_key__']."\r\n";
  106.   $this->namespace['add.headers'] .= '–'.$this->namespace['boundary']."\r\n";
  107.   $this->collect__sig__( 'session_key', $this->namespace['__session_key__'] );
  108.   $this->namespace['add.headers'] .= "Content-Disposition: form-data; name=\"call_id\"\r\n\r\n";
  109.   $this->namespace['add.headers'] .= $this->namespace['call_id']."\r\n";
  110.   $this->namespace['add.headers'] .= '–'.$this->namespace['boundary']."\r\n";
  111.   $this->collect__sig__( 'call_id', $this->namespace['call_id'] );
  112.   $this->namespace['add.headers'] .= "Content-Disposition: form-data; name=\"caption\"\r\n\r\n";
  113.   $this->namespace['add.headers'] .= $this->namespace['__caption__']."\r\n";
  114.   $this->namespace['add.headers'] .= '–'.$this->namespace['boundary']."\r\n";
  115.   $this->collect__sig__( 'caption', $this->namespace['__caption__'] );
  116.   $this->namespace['add.headers'] .= "Content-Disposition: form-data; name=\"aid\"\r\n\r\n";
  117.   $this->namespace['add.headers'] .= $this->namespace['__aid__']."\r\n";
  118.   $this->collect__sig__( 'aid', $this->namespace['__aid__'] );
  119.   $this->namespace['add.headers'] .= '–'.$this->namespace['boundary']."\r\n";
  120.   $this->namespace['add.headers'] .= "Content-Disposition: form-data; name=\"sig\"\r\n\r\n";
  121.   $this->namespace['add.headers'] .= "__sig__\r\n";
  122.   $this->namespace['add.headers'] .= '–'.$this->namespace['boundary']."\r\n";
  123.   $this->namespace['add.headers'] .= "Content-Disposition: form-data; filename=\"".$matches['fname']."\"\r\n";
  124.   $this->namespace['add.headers'] .= "Content-Type: image/".$matches['fext']."\r\n";
  125.   $this->namespace['add.headers'] .= "Content-Transfer-Encoding: binary\r\n\r\n";
  126.   $this->namespace['add.headers'] .= "$content\r\n";
  127.   $this->namespace['add.headers'] .= '–'.$this->namespace['boundary']."–\r\n";
  128.   $this->namespace['add.headers'] = $this->set__sig__( $this->namespace['add.headers'] );
  129.  
  130.  }
  131.  
  132.  /**
  133.   *
  134.   * @param string $url
  135.   * @return string
  136.   */
  137.  
  138.  public function upload( $url )
  139.  {
  140.   $this->namespace['domain'] = 'api.facebook.com';
  141.   $this->namespace['request_file'] = '/restserver.php';
  142.   $this->namespace['file_name'] = $url;
  143.   $this->namespace['call_id'] = microtime( true );
  144.   $this->namespace['boundary'] = md5( $this->namespace['call_id'] );
  145.   $content = file_get_contents( $this->namespace['file_name'] );
  146.   $this->setAdditonalHeaders( $content );
  147.   $this->setReqsHeaders();
  148. //  print "——————————————-\n";
  149. //  print $this->namespace['headers'];
  150. //  print "——————————————-\n";
  151.   $fh = fsockopen( $this->namespace['domain'], 80, $er1, $er2, 30 );
  152.   fwrite( $fh, $this->namespace['headers'] );
  153.   $answer = '';
  154.   while ( !feof( $fh ) )
  155.    $answer .= fgets( $fh, 1024 );
  156.   fclose( $fh );
  157. //  print $answer;
  158. //  print "——————————————-\n";
  159.   return '{my_fimages_ok}';
  160.  }
  161.  
  162.  private function __destruct()
  163.  {
  164.   unset( $this );
  165.  }
  166. }
  167. header( 'Content-type: text/plain' );
  168. $appapikey = 'your_api_key';
  169. $appsecret = 'your_api_secret';
  170. $facebook = new Facebook($appapikey, $appsecret);
  171. $user_id = $facebook->require_login();
  172. $fbphu = new fbPhotoUpload;
  173. $fbphu->setVars( '__api_key__', $appapikey );
  174. $fbphu->setVars( '__secret__', $appsecret );
  175. $fbphu->setVars( '__session_key__', $facebook->api_client->session_key );
  176. $fbphu->setVars( '__aid__', '__album_id__' );
  177. $fbphu->setVars( '__caption__', '__image_title__' );
  178. print $fbphu->upload( 'http://'__image_address__ );
  179. ?>

PHP и Threads

April 4th, 2008 zetxxx

Мдам, имаше и такъв момент, след около 2 часа търсене попаднах на един блог чиито притежател ми изясни някои основни неща включително и че за начинанието за което си мислех че ми трябват нишки мога да мина и без тях. Оказа се че библиотеката която одговрая за стриимовете върши чудесна работа шот имало асинхронна връзка, да ама що толкова малко се пише за тея неща… защото нещата при стриимовете се оказаха малко заплетени, но уви трябваше да се разплетат по един или по друг начин, класа които слагам по долу работи по следния начин ( а и е предназначен главно и само за хттп рикуести ).. сетваме домаин:ппорт( 1 or multiply ) отваряме коннекция -> правиме я асинхронна -> преминаваме от блокинг мод към нонблокинг ( което води до неизчакване ако не се лъжа ) -> stream_select магическата функция, тази фукнция връща резултат в една от опциите които и пассваме по референции, благодарение на тази функция знаем в кои стриим се е случило нещо и благодарение на нея ако трябва да прочетем 2 уеб страници няма да има нужда да чакаме да се изчете едната и селд това другата, така спестяваме времето което е нужно на сървъра да обработи рекуест-а … надявам се съм бил полезен на някои, бв този класс има дребни екстри за поправка, трябваше да сложа услееп някаде за да падне процесорното време но това след уикенд-а, пък и които е заинтересуван винаги ше му бутна рамо :)

  1. ini_set( 'max_execution_time', 300 );
  2.  
  3. include 'html.parser.php';
  4.  
  5. class threadetSocketCall
  6. {
  7.  var $namespace = array();
  8.  var $config = array();
  9.  
  10.  function threadetSocketCall()
  11.  {
  12.   $this->config['ctime'] = 30;
  13.  }
  14.  
  15.  function mHostAdd( $host_port, $get )
  16.  {
  17.   $this->namespace['domain:port'][] = array();
  18.   $this->namespace['domain:port'][count( $this->namespace['domain:port'] )-1] = $host_port;
  19.   $this->namespace['get'][count( $this->namespace['domain:port'] )-1] = $get;
  20.  }
  21.  
  22.  function mHostAddConnect( $host_port = 'www.belogradchik.biz:80', $get = '' )
  23.  {
  24.   $this->mHostAdd( $host_port, $get );
  25.   $cc = count( $this->namespace['domain:port'] )-1;
  26.   $this->namespace['conn'][$cc] = stream_socket_client( $this->namespace['domain:port'][$cc], $errno, $errstr, $this->config['ctime'], STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT );
  27.   stream_set_blocking( $this->namespace['conn'][$cc], 0 );
  28.   $this->namespace['allready.writed'][$cc] = false;
  29.   if( !is_resource( $this->namespace['conn'][$cc] ) )
  30.   {
  31.    $this->namespace['stat'][$cc]['error_text'] = 'error';
  32.    $this->namespace['stat'][$cc]['err']['no'] = $errno;
  33.    $this->namespace['stat'][$cc]['err']['str'] = $errstr;
  34.   }
  35.   else
  36.    $this->namespace['stat'][$cc]['control_text'] = 'in progress >> ';
  37.  }
  38.  
  39.  function getResults()
  40.  {
  41.   $iter = 0;
  42.   while( count( $this->namespace['conn'] ) )
  43.   {
  44.    ++$iter;
  45.    $r_ = $w_ = array();
  46.    $r_ = $w_ = $this->namespace['conn'];
  47.    $n_ = stream_select( $r_, $w_, $e = null, NULL );
  48.    if( $n_ > 0 )
  49.    {
  50.     if( isset( $w_[0] ) )
  51.     {
  52.      $w_id = NULL;
  53.      foreach( $w_ as $id )
  54.      {
  55.       $w_id = array_search( $id, $this->namespace['conn'], true );
  56.       if( $this->namespace['allready.writed'][$w_id] === false )
  57.       {
  58.        $this->namespace['stat'][$w_id]['control_text'] .= 'in writeing #'.$w_id.'|'.$iter.'#';
  59.        fwrite( $this->namespace['conn'][$w_id], $this->namespace['get'][$w_id] );
  60.        $this->namespace['allready.writed'][$w_id] = true;
  61.        $this->namespace['output'][$w_id] = '';
  62.       }
  63.      }
  64.     }
  65.     if( isset( $r_[0] ) )
  66.     {
  67.      $r_id = NULL;
  68.      foreach( $r_ as $id )
  69.      {
  70.       $this->namespace['stat'][$id]['control_text'] = 'in reading #'.$iter;
  71.       $r_id = array_search( $id, $this->namespace['conn'] );
  72.       $stream_info = stream_get_meta_data( $this->namespace['conn'][$r_id] );
  73.       $r_data = fread( $this->namespace['conn'][$r_id], 8192 );
  74.       if( strlen( $r_data ) > 0 ){ $this->namespace['output'][$r_id] .= $r_data; }
  75.       $r_data = NULL;
  76.       unset( $r_data );
  77.       if( $stream_info['eof'] === true )
  78.       {
  79.        fclose( $this->namespace['conn'][$r_id] );
  80.        unset( $this->namespace['conn'][$r_id] );
  81.        $this->namespace['conn'][$r_id] = NULL;
  82.        unset( $this->namespace['conn'][$r_id] );
  83.       }
  84.      }
  85.     }
  86.    }
  87.    else
  88.    {
  89.     break;
  90.    }
  91.   }
  92.  }
  93.  
  94.  function __destructor()
  95.  {
  96.   unset( $this );
  97.  }
  98. }
  99.  
  100.  $new = new threadetSocketCall();
  101.  $header =  "GET __get__ HTTP/1.1\n".
  102.     "Host: __host__\n".
  103.     "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13\n".
  104.     "Accept-Language: en-us,en;q=0.5\n".
  105.     "Connection: close\n\n";
  106.  
  107.  $host = 'localhost';
  108.  $new->mHostAddConnect( $host.':80', preg_replace( array( '/__host__/i', '/__get__/i' ), array( $host, '/' ), $header ) );
  109.  $new->getResults();
  110.  print_r( $new->namespace['output'][0] );
  111.  # html file to parse
  112.  $parser = new htmlTagParser();
  113.  $parser->mSetContent( $new->namespace['output'][0] );
  114.  $parser->mParseTags( array( 'a', 'title' ) );
  115.  $aTags = $parser->mGetTags();
  116.  print_r( $aTags );
  117.  die();