2012-03-27 11 views
14

Ich versuche, ein paar Einblicke von den Seiten Ich bin Administrator auf Facebook zu bekommen.
Was mein Code tut, bekommt es die IDs der Seiten, mit denen ich arbeiten möchte, über mySQL. Ich habe diesen Teil jedoch nicht aufgenommen.Erhöhung der Leistung und Benutzerfreundlichkeit von Facebook FQL

Danach bekomme ich die page_id, name und fan_count von jeder dieser Facebook-IDs und sind in fancounts[] gespeichert.

Ich habe zwei Probleme damit.

  1. Es hat eine sehr geringe Leistung
  2. ich nicht einen Weg finden, die Daten so echo:

Meine Fragen sind, wie der Code der Leistung zu erhöhen geändert werden kann und zeigen die Daten wie oben? Ich lese über fql.multiquery. Kann es hier verwendet werden?

Bitte geben Sie mir Codebeispiele. Danke

+0

Statt Speicherung '$ fancounts' und '$ messages' als Arrays, was passiert, wenn man nur die Daten ausgibt? Wird es nicht angezeigt? – hohner

+0

@Jamie Ja, es werden zuerst ALLE Namen, Fans, IDs angezeigt und es werden weiterhin ALLE Nachrichten angezeigt. Ich hatte es schon einmal so. – EnexoOnoma

+0

Auch können Sie [facebook Batch-Anfrage] (http://developers.facebook.com/docs/reference/api/batch/) –

Antwort

5

Wenn Sie n Seiten haben, Ihre Skript macht n+1 Abfragen. Dies ist der Hauptnachteil Ihres Skripts. Dies ist der Grund für eine geringe Leistung.

Sie können eine Stapelanforderung verwenden, um die Abfragen zu kombinieren. Sie können das folgende Skript verwenden, um zu erreichen, was Sie wollen. Ich habe diese n+1 Abfragen zu nur einer Stapelabfrage kombiniert. So wird es schneller als dein Skript sein.

Ich habe auch den echo Teil korrigiert. Jetzt zeigt das Skript die Ausgabe an, die Sie in Ihrer Frage angegeben haben.

// 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

Im Moment machen Sie zwei separate Anrufe in der Facebook-Datenbank, die alles verlangsamt. Facebook bietet seine Multiquery an, damit Sie alles mit möglichst wenigen DB-Anrufen erledigen können. So sind die Anrufe, die Sie denken sollten, verwenden, sind:

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

Und weil sie ermöglicht es Ihnen, eine vorherige Abfrage zu verweisen, können Sie schließen es gerade nach einem #:

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

Die PHP Sie verwenden müssen so etwas wie dieses:

$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); 

wenn die zweite Abfrage wird durch nicht gehen, versuchen sie die FB DB testet mit gerade diese Abfrage und sehen, ob es funktioniert. Wenn die Abfrage nichts selbst zurückgibt, besteht das Problem möglicherweise in den Berechtigungen (d. H. Zugriff auf eine sensible Tabelle - aber ich denke nicht, dass dies der Fall ist). Ein weiteres Problem, das ich häufig erlebt habe ist, wie FQL sich mit Leerzeichen Reisen, also versuchen, alle möglichen Leerzeichen aus Ihrem Array Weglassen:

$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, das ist lesbar ... Dieses von Facebook's documentation auf FQL genommen wurde, Sie müssen es jedoch möglicherweise an Ihre Webanwendung anpassen, wenn Sie eine Drittanbieterbibliothek verwenden. Alle Ihre Daten werden in $fql_url gespeichert. Alles, was Sie tun müssen, ist Schleife durch es und Echo die Informationen, die Sie wollen. Wenn Sie eine Zusammenfassung von allem sehen wollen, denken Sie daran, print_r() oder var_dump() zu verwenden, nur um sich zu orientieren.

EDIT

Der Grund, dass Sie ein leeres Array für die zweite Abfrage sind empfangen ist, weil Sie für die stream Tabelle keine Berechtigung zu haben scheinen.Wenn Sie Facebook überprüfen documentation, erwähnen sie die Kriterien erforderlich, um diese Tabelle zuzugreifen:

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

Um zu überprüfen, welche Berechtigungen Sie haben, können Sie diese Abfrage ausführen:

$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

Haben Sie dies versucht, weil ich die gleiche Antwort posten würde, außer dass die zweite Abfrage immer das leere Array "[]" zurückgab. –

+0

@Jamie Ich habe die Variable korrigiert (entfernt die '_multiquery') und versucht,' print_r ($ fql_result) '. Das habe ich bekommen * {"error": {"message": "(# 601) Parserfehler: unerwartet '{' an Position 0.", "Type": "OAuthException", "code": 601}} * – EnexoOnoma

+0

@P.Galbraith Haben Sie es mit dem SDK oder wie oben versucht? Weil ich einen Fehler bekomme – EnexoOnoma

2

Sie können alles versuchen, aber Ihr Code wird nicht schnell laufen, weil Sie die goldene Regel der Hochgeschwindigkeits-Web-App brechen. Was Sie tatsächlich schreiben jetzt gerade:

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

Und was Sie wirklich tun sollten: -

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

Ja, Sie sollten mehrere Anfrage sofort zu verringern, um Gesamtreaktionszeit gemacht. Der Browser beschleunigt das Laden der Seite nur auf diese Weise.

Ich habe ähnliches Problem während der Arbeit an RSS Feed Fetcher konfrontiert (Es hat eine riesige Datenbank von RSS-Links).

dieses Problem zu lösen, kann ich Ihnen zwei Dinge vorschlägt

  1. Verwendung Multi-curl Befehl mehr Befehle auf einmal zu holen. Es wird Ihr Skript wirklich beschleunigen, da mehrere Anfragen gleichzeitig die Gesamtzeit verringern.

  2. Aber obige Lösung wird in gewissem Maße funktionieren. Wenn Sie viele Daten abfragen, müssen Sie anderswo suchen, da PHP nicht Multi-Threading unterstützt. Sie können java oder node.js als Alternative verwenden und redis server (unterschätzt es nicht) als Pipeline zwischen php-Skript und java oder node.js verwenden, indem Sie dessen pub/sub-Funktionalität verwenden. Laut mir ist es die beste Alternative und ich habe es benutzt, um über Hunderttausende von Aufnahmen zu sammeln und es versagt nie.

Und andere Sache, in der ich nicht wirklich Geschwindigkeit Ihrer Internetverbindung kann helfen;)

Hope this löst Ihr Problem :)

Deepak

Verwandte Themen