2012-03-27 15 views
14

Cerco di ottenere alcune informazioni dalle pagine che sono amministratore su Facebook.
Cosa fa il mio codice, ottiene gli ID delle pagine con cui voglio lavorare tramite mySQL. Non ho incluso quella parte però.Aumentare le prestazioni e l'usabilità di FQL di Facebook

Dopo questo, ottengo page_id, name e fan_count di ciascuno di quegli ID di Facebook e sono salvati in fancounts[].

Ho due problemi con esso.

  1. Ha una prestazione molto lenta
  2. non riesco a trovare un modo per eco i dati in questo modo:

Le mie domande sono, come può il codice essere modificato per aumentare le prestazioni e spettacolo i dati come sopra? Ho letto su fql.multiquery. Può essere usato qui?

Fornire esempi di codice. Grazie

+0

Invece di memorizzare '$ fancount' e '$ messages' come array, cosa succede quando riecheggiate i dati? Non viene visualizzato? – hohner

+0

@Jamie Sì, visualizza innanzitutto TUTTI i nomi, i fan, gli ID e continua a visualizzare TUTTI i messaggi. Ho avuto così prima. – EnexoOnoma

+0

Inoltre puoi usare [richiesta batch facebook] (http://developers.facebook.com/docs/reference/api/batch/) –

risposta

5

Se avete n pagine, la tua lo script esegue le query n+1. Questo è il principale svantaggio del tuo script. Questa è la ragione per le basse prestazioni.

È possibile utilizzare la richiesta batch per combinare le query. Puoi utilizzare lo script seguente per ottenere ciò che desideri. Ho combinato le query n+1 con una sola query batch. Quindi sarà più veloce della tua sceneggiatura.

Ho anche corretto la parte echo. Ora lo script mostrerà l'output come hai detto nella tua domanda.

// Get the IDs 
$pages = array(); 
$pagesIds = implode(',', $pages); 

// fancounts[] holds the page_id, name and fan_count of the Ids I work with 
$fancounts = array(); 
$q = "SELECT page_id, name, fan_count FROM page WHERE page_id IN ({$pagesIds})"; 
$queries[] = array('method'=>'GET', 'relative_url' => 'method/fql.query?query=' . urlencode($q)); 

$messages = array(); 
foreach($pages as $id) 
{ 
    $q = "SELECT message FROM stream WHERE source_id = '$id' LIMIT 2"; 
    $queries[] = array('method'=>'GET', 'relative_url' => 'method/fql.query?query=' . urlencode($q)); 
} 

// The batch query 
$batchResponse = $facebook->api('?batch='.json_encode($queries), 'POST'); 
$pagesFanCounts = json_decode($batchResponse[0]['body'], TRUE); 

foreach ($pagesFanCounts as $page) 
{  
    $fancounts[] = number_format($page['page_id'],0,'','')."-".$page['name']."-".$page['fan_count']; 
} 

for($i=0; $i < count($fancounts); $i++) 
{ 
    echo '</br>',$fancounts[$i],'<br>'; 
    $temp = json_decode($batchResponse[$i+1]['body'], TRUE); 
    foreach ($temp as $msg) 
    { 
     echo ($msg['message']); 
     echo "</br>"; 
    } 
} 
12

Al momento, stai facendo due chiamate separate al database di Facebook che sta rallentando tutto. Facebook offre la loro multiquery in modo che tu possa fare tutto nel minor numero possibile di chiamate DB. Così i chiamate si dovrebbe pensare di utilizzare sono:

"query1":"SELECT page_id, name, fan_count FROM page WHERE page_id IN ($pagesIds)" 

E perché consentono di fare riferimento a una query precedente, appena è possibile includere dopo un #:

"query2":"SELECT message FROM stream WHERE source_id IN (SELECT page_id FROM #pages) LIMIT 2" 

Il PHP è necessario utilizzare è qualcosa di simile:

$query = array(
    "pages"=>"SELECT page_id, name, fan_count FROM page WHERE page_id IN ($pagesIds)", 
    "messages"=>"SELECT message FROM stream WHERE source_id IN (SELECT page_id FROM #pages) LIMIT 2" 
); 

$fql_url = $facebook->api(array(
    'method' => 'fql.multiquery', 
    'queries' => $query 
)); 

print_r($fql_url); 

Se la seconda query non sta attraversando, provare a testare l'FB DB con proprio questa query e vedere se funziona. Se la query non restituisce nulla da sola, il problema potrebbe riguardare le autorizzazioni (ad esempio l'accesso a una tabella sensibile, ma non penso che sia così). Un altro problema che ho spesso incontrato è come FQL si viaggi con spazi, in modo da provare omettendo tutti i possibili spazi dalla matrice:

$query = array("pages"=>"SELECT page_id, name, fan_count FROM page WHERE page_id IN ($pagesIds)","messages"=>"SELECT message FROM stream WHERE source_id IN (SELECT page_id FROM #pages) LIMIT 2"); 

Wow, questo è leggibile ... Questa è stata presa dal Facebook's documentation su FQL, tuttavia, potrebbe essere necessario adattarlo alla propria applicazione Web se si utilizza una libreria di terze parti. Tutti i tuoi dati vengono salvati in $fql_url. Tutto quello che devi fare è passarci sopra e far risuonare le informazioni che desideri. Se vuoi vedere un riassunto di tutto ciò che contiene, pensa di usare print_r() o var_dump() solo per orientarti.

EDIT

Il motivo che si sta ricevendo un array vuoto per la seconda query è perché non sembrano avere autorizzazioni per la tabella stream.Se si seleziona Facebook di documentation, accennano i criteri necessari per accedere a questa tabella:

To read the stream table you need

  • read_stream permissions for all posts that the current session user is able to view
  • read_insights permissions to see post impressions for any posts made by a Page owned by the current session user

Per controllare quali autorizzazioni dispone, è possibile eseguire questa query:

$check_query = $facebook->api(array(
    "method"    => "fql.query", 
    "query"     => "SELECT * FROM permissions WHERE uid=me()" 
)); 

foreach($check_query[0] as $k => $v) { 
    if($v === "1") { 
        echo "<strong>$k</strong> permission is granted.<br>"; 
    } else { 
        echo "<strong>$k</strong> permission is not granted.<br>"; 
    } 
} 
+0

Hai provato questo perché stavo per pubblicare la stessa risposta, tranne che la seconda query ha sempre restituito l'array vuoto "[]". –

+0

@Jamie Ho corretto la variabile (rimosso '_multiquery') e ho provato a' print_r ($ fql_result) '. Questo è quello che ho ottenuto * {"errore": {"messaggio": "(# 601) Errore del parser: imprevisto '{' in posizione 0.", "Tipo": "OAuthException", "codice": 601}} * – EnexoOnoma

+0

@ P.Galbraith Lo hai provato usando l'SDK o come sopra? Perché ottengo un errore – EnexoOnoma

2

Puoi provare qualsiasi cosa, ma il tuo codice non sarà veloce perché stai infrangendo la regola d'oro dell'app web ad alta velocità. Quello che effettivamente facendo scrittura ora è:

request1->(wait for response-> download data) -> request2 (wait for response -> 
download data) -> and so on ...... 

E ciò che si dovrebbe davvero fare: -

request1->(wait for response-> download data) 
request2->(wait for response-> download data) 
request3->(wait for response-> download data) 
...... 
...... 

Sì, si dovrebbe fatta richiesta multipla in una sola volta, al fine di ridurre il tempo di risposta totale. Il browser velocizza il caricamento della pagina solo in questo modo.

Ho affrontato un problema simile mentre lavoravo su feed fetcher RSS (Ha un enorme database di collegamenti RSS).

per risolvere questo problema che può suggerire due cose

  1. Utilizzare il comando multi-ricciolo per andare a prendere il comando multiple in una sola volta. Velocizzerà davvero lo script in quanto più richieste contemporaneamente diminuiranno il tempo complessivo.

  2. Ma la soluzione sopra descritta funzionerà in parte. Se stai interrogando molti dati, devi guardare da qualche altra parte dato che php non supporta il multi-threading. È possibile utilizzare java o node.js come alternativa e utilizzare il server redis (non sottovalutarlo) come pipeline tra lo script php e java o node.js utilizzando la funzione pub/sub. Secondo me è la migliore alternativa e l'ho usata per recuperare oltre centinaia di migliaia di dischi e non fallisce mai.

E altra cosa in cui non posso davvero aiutare è la vostra velocità di connessione a Internet;)

Spero che questo risolve il problema :)

Deepak

Problemi correlati