2012-10-27 20 views
1

我想知道我能做些什麼來不對API進行多次調用?例如,如果我嘗試使用yelp的api,那麼它們在超出前會有一個限制的通話(一旦超過該數字,它們就會停止向您提供信息)。PHP處理API不超過它的限制?

我該怎麼辦?現在,我有這樣的(從他們的API PHP的例子)中,我需要得到從他們的網站信息的每一頁:

// For example, request business with id 'the-waterboy-sacramento' 
//$unsigned_url = "http://api.yelp.com/v2/business/the-waterboy-sacramento"; 


// For examaple, search for 'tacos' in 'sf' 
//$unsigned_url = "http://api.yelp.com/v2/search?term=tacos&location=sf"; 

// My own code 
$unsigned_url = "http://api.yelp.com/v2/search?term=".$term.""; 
// $term is coming from searching 

// Set your keys here 
$consumer_key = "some_id"; 
$consumer_secret = "some_id"; 
$token = "some_id"; 
$token_secret = "some_id"; 

// Token object built using the OAuth library 
$token = new OAuthToken($token, $token_secret); 

// Consumer object built using the OAuth library 
$consumer = new OAuthConsumer($consumer_key, $consumer_secret); 

// Yelp uses HMAC SHA1 encoding 
$signature_method = new OAuthSignatureMethod_HMAC_SHA1(); 

// Build OAuth Request using the OAuth PHP library. Uses the consumer and token object created above. 
$oauthrequest = OAuthRequest::from_consumer_and_token($consumer, $token, 'GET', $unsigned_url); 

// Sign the request 
$oauthrequest->sign_request($signature_method, $consumer, $token); 

// Get the signed URL 
$signed_url = $oauthrequest->to_url(); 

// Send Yelp API Call 
$ch = curl_init($signed_url); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
curl_setopt($ch, CURLOPT_HEADER, 0); 
$data = curl_exec($ch); // Yelp response 
curl_close($ch); 

,這似乎過分的每一頁做時,我想打電話給某商業。

回答

3

我不使用它,但作爲一般答案,考慮緩存數據庫中的數據以減少API調用。它還可以提高網站的性能,尤其是當需要多次加載同一個API數據的頁面時。

這裏是一個基於文件的一般使用實施

/** 
* Cache friendly function call stub. 
* 
* @param callback $Callback 
* @param array $Arguments 
* @param integer $Expiration 
* @return mixed 
*/ 
function CallFunctionAndCacheResult($Callback, array $Arguments, $Expiration = 3600){ 
    // Validate $Callback 
    if(!is_callable($Callback)){ 
     trigger_error('$Callback must be a callback.', E_USER_WARNING); 
     return false; 
    } 
    // Validate $Arguments (we need some to hash) 
    if(empty($Arguments)){ 
     trigger_error('$Arguments cannot be empty.', E_USER_WARNING); 
     return false; 
    } 
    // Empty $Expiration means live calls 
    if(empty($Expiration)){ 
     return call_user_func_array($Callback, $Arguments); 
    } 
    // Validate $Expiration (we need some to hash) 
    if(!is_numeric($Expiration) or (($Expiration = intval($Expiration)) < 1)){ 
     trigger_error('$Expiration has to be a positive integer.', E_USER_WARNING); 
     return false; 
    } 
    // Hash the Arguments (Unique Call ID) 
    $Hash = md5(serialize($Arguments)); 
    // Check if Cache file exists 
    if(is_file($Cache = dirname(__FILE__)."/{$Hash}.serial")){ 
     // Test if file expired 
     if(($MTime = filemtime($Cache)) >= (time() - $Expiration)){ 
      // Attempt to load data, assume it's corrupted 
      if(($Data = unserialize(file_get_contents($Cache))) !== false){ 
       return $Data; 
      } 
     } 
    } 
    // Now regenerate the data if you got here 
    $Data = call_user_func_array($Callback, $Arguments); 
    // Store it, with LOCK_EX enabled to prevent collisions 
    file_put_contents($Cache, serialize($Data), LOCK_EX); 
    // Return the data 
    return $Data; 
} 

// Test case (store current time for 10 seconds, keep refreshing) 
var_dump($Data = CallFunctionAndCacheResult(function(){ 
    // Return some data to be cached 
    return array_merge(func_get_args(), array(
     'cached' => gmstrftime('%A, %d %B %Y %H:%M:%S'), 
    )); 
}, array(
    'Username', 
    'Password', 
    // ... 
), 10)); 

希望這是有道理的。只需測試一下,算出來並使用數據庫引擎即可獲得相同的結果。

+1

你有沒有我可以查看的參考資料?謝謝 – hellomello

+0

@andrewliu不是真的,這對我來說很自然......而且我是個不好的老師:)你必須進入API調用的中間並緩存到數據庫。然後,在將來的調用中,檢查參數散列是否匹配並從數據庫返回結果,而不是進行實時調用......但還要設置過期時間,以便最終刷新數據。你需要使用一個數據庫和一個函數來處理這個調用,以允許輕鬆緩存。查看mysqli對象並從那裏開始。但也許你會在這裏找到關於SO的提示。 – CodeAngry

+0

@andrewliu增加了一些代碼。一探究竟! – CodeAngry

1

緩存是你的朋友在這裏。如果您認爲自己一遍又一遍地執行不需要的API查詢,則應該將信息緩存到cookie中,如果它的內容很小/非重要或者數據庫不對。

贊,如果用戶希望刷新頁面並在其中運行查詢以獲取其名稱,我不想用盡限制。你可以得到他的名字一次,存儲到一個cookie,然後從那裏使用它,而不是每次查詢。像其他答案一樣,更快,更高效。

+0

感謝您的提示:)! – hellomello