Einfachstes PHP-Beispiel zum Abrufen von user_timeline mit der Twitter API Version 1.1

292

Aufgrund des Ausscheidens von Twitter API 1.0 zum 11. Juni 2013 funktioniert das folgende Skript nicht mehr.

// Create curl resource 
$ch = curl_init(); 
// Set url 
curl_setopt($ch, CURLOPT_URL, "http://twitter.com/statuses/user_timeline/myscreenname.json?count=10"); 
// Return the transfer as a string 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
// $output contains the output string 
$output = curl_exec($ch); 
// Close curl resource to free up system resources 
curl_close($ch);

if ($output) 
{
    $tweets = json_decode($output,true);

    foreach ($tweets as $tweet)
    {
        print_r($tweet);
    }
}

Wie kann ich die user_timeline (aktuelle Status) mit dem geringstmöglichen Code abrufen?

Ich habe Folgendes gefunden: https://dev.twitter.com/docs/api/1.1/get/statuses/user_timeline, aber ich erhalte die folgende Fehlermeldung:

"{"errors":[{"message":"Could not authenticate you","code":32}]}"

Es gibt viele Klassen da draußen, aber nachdem ich einige ausprobiert habe, scheint keine von ihnen aufgrund dieser Updates bei Twitter zu funktionieren, und einige von ihnen sind ziemlich fortgeschrittene Klassen mit vielen Funktionen, die ich nicht wirklich brauche.

Was ist der einfachste / kürzeste Weg, um die neuesten Benutzerstatus mit PHP zu erhalten?

Mitweltbürger
quelle
97
Ich würde für die Antwort auf diese Frage TÖTEN. Ihre Dokumentation ist schrecklich schlecht.
RCNeil
Ich bin neu in der Twitter-API und habe ein bisschen Probleme damit. Ich habe veralteten Code verwendet.
Anthony
Werfen
Aamir Afridi
@ Mark Danke Mark !! Das war einfach!! Das hat bei mir anfangs nicht funktioniert. Ich leite WAMP. Ich musste eine Änderung an meiner php.ini in meinem Apache-Verzeichnis gemäß diesem Thread vornehmen
Adlin Ling
1
Ich habe gerade eine Lösung ohne CURL oder andere zusätzliche Bibliotheken aufgeschrieben
Rauli Rajande

Antworten:

820

Wichtiger Hinweis: Ab Mitte 2018 wurde der Prozess zum Abrufen von Twitter-API-Token viel bürokratischer. Ich habe über eine Arbeitswoche gebraucht , um eine Reihe von API-Token bereitzustellen. Dies ist ein Open-Source-Projekt für euch Jungs und Mädchen mit über 1,2 Millionen Installationen auf Packagist und 1,6.000 Sternen auf Github, das theoretisch eine höhere Priorität haben sollte .

Wenn Sie mit der Arbeit mit der Twitter-API für Ihre Arbeit beauftragt sind, müssen Sie diese möglicherweise extrem lange Wartezeit berücksichtigen. Berücksichtigen Sie auch andere Social-Media-Möglichkeiten wie Facebook oder Instagram und bieten Sie diese Optionen an, da das Abrufen der Token sofort erfolgt.


Sie möchten also die Twitter v1.1-API verwenden?

Hinweis: Die Dateien für diese befinden sich auf GitHub .

Version 1.0 wird bald veraltet sein und nicht autorisierte Anfragen werden nicht zugelassen. Hier ist ein Beitrag, der Ihnen dabei hilft, zusammen mit einer PHP-Klasse, die Ihnen das Leben erleichtert.

1. Erstellen Sie ein Entwicklerkonto: Richten Sie ein Entwicklerkonto bei Twitter ein

Sie müssen die offizielle Twitter-Entwicklerseite besuchen und sich für ein Entwicklerkonto registrieren. Dies ist ein kostenloser und notwendiger Schritt, um Anforderungen für die v1.1-API zu stellen.

2. Erstellen Sie eine Anwendung: Erstellen Sie eine Anwendung auf der Twitter-Entwicklerseite

Was? Sie dachten, Sie könnten nicht authentifizierte Anfragen stellen? Nicht mit der v1.1-API von Twitter. Sie müssen http://dev.twitter.com/apps besuchen und auf die Schaltfläche "Anwendung erstellen" klicken.

Geben Sie hier die Bildbeschreibung ein

Geben Sie auf dieser Seite die gewünschten Details ein. Für mich war das egal, weil ich nur eine Menge Blockanfragen stellen wollte, um Spam-Follower loszuwerden. Der Punkt ist, dass Sie sich einen Satz eindeutiger Schlüssel besorgen, die Sie für Ihre Anwendung verwenden können.

Beim Erstellen einer Anwendung müssen Sie sich (und Twitter) einen Schlüsselbund geben. Diese sind:

  • Der Verbraucherschlüssel
  • Das Verbrauchergeheimnis
  • Das Zugriffstoken
  • Das Zugriffstoken-Geheimnis

Es gibt ein wenig Informationen hier auf das, was diese Tokens für.

3. Zugriffstoken erstellen : Sie benötigen diese, um erfolgreiche Anforderungen zu stellen

OAuth fordert einige Token an. Sie müssen sie also für Sie generieren lassen.

Geben Sie hier die Bildbeschreibung ein

Klicken Sie unten auf "Mein Zugriffstoken erstellen". Sobald Sie wieder nach unten scrollen, haben Sie einige neu generierte Schlüssel. Sie müssen die vier zuvor beschrifteten Schlüssel von dieser Seite für Ihre API-Aufrufe abrufen, notieren Sie sie sich also irgendwo.

4. Ändern Sie die Zugriffsebene : Sie möchten nicht schreibgeschützt, oder?

Wenn Sie diese API angemessen nutzen möchten, müssen Sie Ihre Einstellungen in Lesen und Schreiben ändern, wenn Sie etwas anderes als das Standard-Datenabrufen mit GET- Anforderungen durchführen.

Geben Sie hier die Bildbeschreibung ein

Wählen Sie die Registerkarte "Einstellungen" oben auf der Seite.

Geben Sie hier die Bildbeschreibung ein

Geben Sie Ihrer Anwendung Lese- / Schreibzugriff und klicken Sie unten auf "Aktualisieren".

Sie können mehr über die Anwendungen Berechtigungsmodell lesen , dass Twitter hier verwendet.


5. Schreiben Sie Code, um auf die API zuzugreifen : Ich habe das meiste für Sie erledigt

Ich habe den obigen Code mit einigen Modifikationen und Änderungen zu einer PHP-Klasse kombiniert, damit es wirklich einfach ist, die gewünschten Anforderungen zu stellen.

Dies verwendet OAuth und die Twitter v1.1-API sowie die von mir erstellte Klasse, die Sie unten finden.

require_once('TwitterAPIExchange.php');

/** Set access tokens here - see: https://dev.twitter.com/apps/ **/
$settings = array(
    'oauth_access_token' => "YOUR_OAUTH_ACCESS_TOKEN",
    'oauth_access_token_secret' => "YOUR_OAUTH_ACCESS_TOKEN_SECRET",
    'consumer_key' => "YOUR_CONSUMER_KEY",
    'consumer_secret' => "YOUR_CONSUMER_SECRET"
);

Stellen Sie sicher, dass Sie die Schlüssel, die Sie von Ihrer Anwendung oben erhalten haben, in die entsprechenden Felder einfügen.

Als nächstes müssen Sie eine URL auswählen, an die Sie eine Anfrage stellen möchten. Die API-Dokumentation von Twitter hilft Ihnen bei der Auswahl der URL und des Anforderungstyps (POST oder GET).

/** URL for REST request, see: https://dev.twitter.com/docs/api/1.1/ **/
$url = 'https://api.twitter.com/1.1/blocks/create.json';
$requestMethod = 'POST';

In der Dokumentation gibt jede URL an, was Sie an sie übergeben können. Wenn wir die URL "Blöcke" wie oben verwenden, kann ich die folgenden POST-Parameter übergeben:

/** POST fields required by the URL above. See relevant docs as above **/
$postfields = array(
    'screen_name' => 'usernameToBlock', 
    'skip_status' => '1'
);

Nachdem Sie festgelegt haben, was Sie mit der API tun möchten, ist es Zeit, die eigentliche Anfrage zu stellen.

/** Perform the request and echo the response **/
$twitter = new TwitterAPIExchange($settings);
echo $twitter->buildOauth($url, $requestMethod)
             ->setPostfields($postfields)
             ->performRequest();

Und für eine POST- Anfrage ist es das!

Bei einer GET- Anfrage ist das etwas anders. Hier ist ein Beispiel:

/** Note: Set the GET field BEFORE calling buildOauth(); **/
$url = 'https://api.twitter.com/1.1/followers/ids.json';
$getfield = '?username=J7mbo';
$requestMethod = 'GET';
$twitter = new TwitterAPIExchange($settings);
echo $twitter->setGetfield($getfield)
             ->buildOauth($url, $requestMethod)
             ->performRequest();     

Letztes Codebeispiel : Für eine einfache GET-Anfrage nach einer Liste meiner Follower.

$url = 'https://api.twitter.com/1.1/followers/list.json';
$getfield = '?username=J7mbo&skip_status=1';
$requestMethod = 'GET';
$twitter = new TwitterAPIExchange($settings);
echo $twitter->setGetfield($getfield)
             ->buildOauth($url, $requestMethod)
             ->performRequest();  

Ich habe diese Dateien auf GitHub mit Kredit an @ lackovic10 und @rivers gestellt! Ich hoffe, jemand findet es nützlich; Ich weiß, dass ich es getan habe (ich habe es zum Blockieren von Massen in einer Schleife verwendet).

Für diejenigen unter Windows, die Probleme mit SSL-Zertifikaten haben, lesen Sie diesen Beitrag . Diese Bibliothek verwendet cURL unter der Haube, daher müssen Sie sicherstellen, dass Ihre cURL-Zertifikate wahrscheinlich eingerichtet sind. Google ist auch dein Freund.

Jimbo
quelle
4
@kaffolder Der Link auf dieser Seite: profilepicture.co.uk/caching-api-responses-php schlägt eine einfache Möglichkeit vor. Sie schreiben Ihre Twitter - Daten in einer Datei oder Datenbank (MySQL oder MongoDB) auf erste Anforderung, dann jede nachfolgende Anforderung überprüfen Sie aktuelle Zeit vor der Frist für die Datei wollen (man könnte benennen Sie die Datei als Frist), und Wenn die Datei vorhanden ist und der Dateiname innerhalb des gewünschten Zeitlimits liegt, ziehen Sie die Daten ab, anstatt die API-Anforderung auszuführen. Wenn eine Datei vorhanden ist, das Zeitlimit jedoch überschritten wurde, löschen Sie die Datei und führen Sie die API-Anforderung aus.
Jimbo
7
Ich kann nicht herausfinden, wie ich mit den zurückgegebenen JSON-Daten umgehen soll. Ich möchte es nicht einfach wie in echo $ twitter -> setGetfield ($ getfield) -> buildOauth ($ url, $ requestMethod) -> performRequest () auf dem Bildschirm wiedergeben. Entschuldigung, ich kann nicht herausfinden, wie man Zeilenumbrüche macht! Ich möchte so etwas wie $ jsonData = json_decode ($ twitter) machen. aber es funktioniert nicht - ich habe das Gefühl, ich vermisse etwas Grundlegendes, aber der Penny fällt nicht ...
Ashley
67
Vielen Dank, die Dokumentation von Twitter ist ein unorganisiertes Durcheinander, das hat sehr geholfen.
Joren
7
Es gibt einige Voraussetzungen, damit diese Klasse unter Windows funktioniert. Sie müssen eine funktionierende Version von cURL in Ihre php.iniDatei geladen haben und die CA-Zertifikate in Ihre php.iniDatei mit laden curl.cainfo = path\to\cacert.pem. Die CA-Zertifikate erhalten Sie hier .
Jake Z
4
@Jimbo Ich habe nur bemerkt, dass einige der Standard-cURL-Erweiterungen in Windows fehlerhaft sind und ersetzt werden müssen (daher der Link zu den "festen" Versionen) und dass Ihre Klasse ohne Laden der CA-Zertifikate ein false zurückgibt, da curl_error () meldet das Problem mit dem SSL-Zertifikat. Überprüfen Sie, ob das CA-Zertifikat in Ordnung ist. Dies kann vermieden werden, indem CURLOPT_SSL_VERIFYPEER deaktiviert wird. Ich dachte jedoch, ich würde die grundlegenden Anweisungen zur tatsächlichen Verwendung der CA-Zertifikate hinzufügen. Dies ist nur enthalten, um einigen Personen möglicherweise ein paar Minuten Suche zu ersparen.
Jake Z
137

Gehen Sie zu dev.twitter.com und erstellen Sie eine Anwendung . Dadurch erhalten Sie die erforderlichen Anmeldeinformationen. Hier ist eine Implementierung, die ich kürzlich mit PHP und cURL geschrieben habe .

<?php
    function buildBaseString($baseURI, $method, $params) {
        $r = array();
        ksort($params);
        foreach($params as $key=>$value){
            $r[] = "$key=" . rawurlencode($value);
        }
        return $method."&" . rawurlencode($baseURI) . '&' . rawurlencode(implode('&', $r));
    }

    function buildAuthorizationHeader($oauth) {
        $r = 'Authorization: OAuth ';
        $values = array();
        foreach($oauth as $key=>$value)
            $values[] = "$key=\"" . rawurlencode($value) . "\"";
        $r .= implode(', ', $values);
        return $r;
    }

    $url = "https://api.twitter.com/1.1/statuses/user_timeline.json";

    $oauth_access_token = "YOURVALUE";
    $oauth_access_token_secret = "YOURVALUE";
    $consumer_key = "YOURVALUE";
    $consumer_secret = "YOURVALUE";

    $oauth = array( 'oauth_consumer_key' => $consumer_key,
                    'oauth_nonce' => time(),
                    'oauth_signature_method' => 'HMAC-SHA1',
                    'oauth_token' => $oauth_access_token,
                    'oauth_timestamp' => time(),
                    'oauth_version' => '1.0');

    $base_info = buildBaseString($url, 'GET', $oauth);
    $composite_key = rawurlencode($consumer_secret) . '&' . rawurlencode($oauth_access_token_secret);
    $oauth_signature = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
    $oauth['oauth_signature'] = $oauth_signature;

    // Make requests
    $header = array(buildAuthorizationHeader($oauth), 'Expect:');
    $options = array( CURLOPT_HTTPHEADER => $header,
                      //CURLOPT_POSTFIELDS => $postfields,
                      CURLOPT_HEADER => false,
                      CURLOPT_URL => $url,
                      CURLOPT_RETURNTRANSFER => true,
                      CURLOPT_SSL_VERIFYPEER => false);

    $feed = curl_init();
    curl_setopt_array($feed, $options);
    $json = curl_exec($feed);
    curl_close($feed);

    $twitter_data = json_decode($json);

//print it out
print_r ($twitter_data);

?>

Dies kann über die Befehlszeile ausgeführt werden:

$ php <name of PHP script>.php
Flüsse
quelle
2
Vielen Dank für das Code-Snippet, arbeiten Sie einwandfrei. Das einzige Problem ist, dass ich anscheinend nicht herausfinden kann, wie die Rückgabe nach der Anzahl festgelegt wird. Es gibt nur 20 zurück und ich möchte den vollen Betrag, der 200 gemäß Twitter-Limit beträgt.
Flatlyn
23
Wie würden Sie das screen_nameund countmit diesem Ansatz einstellen ? Ich habe versucht, es der $urlVariablen hinzuzufügen, aber ich habe den Fehler "Sie konnten nicht authentifiziert werden" erhalten.
Javier Villanueva
1
Dieser Code funktioniert super! Ich versuche es zu ändern, um die API search / tweets.json zu verwenden, aber ich erhalte immer die Antwort "Sie konnten sich nicht authentifizieren" - irgendwelche Ideen?
Chris
1
Dieser Beitrag war sehr hilfreich. Mein Code scheint jedoch nicht zurückzukehren curl_init(). Ich habe mir einige Beispiele angesehen und sie sehen sehr einfach und unkompliziert aus und genau wie dieser Code hier ... Muss ich etwas Besonderes installieren?
Jessicaraygun
1
Es hat bei mir am 26. Oktober 2016 funktioniert. Die Ausgabe war etwas komplexer als ich erwartet hatte.
JohnC
61

Der von Rivers eingefügte Code ist großartig. Vielen Dank! Ich bin neu hier und kann keinen Kommentar abgeben. Ich möchte nur die Frage von javiervd beantworten (Wie würden Sie den Bildschirmnamen festlegen und mit diesem Ansatz zählen?), Da ich viel Zeit verloren habe, um ihn herauszufinden aus.

Sie müssen die Parameter sowohl zur URL als auch zum Signaturerstellungsprozess hinzufügen . Das Erstellen einer Signatur ist der Artikel, der mir geholfen hat. Hier ist mein Code:

$oauth = array(
           'screen_name' => 'DwightHoward',
           'count' => 2,
           'oauth_consumer_key' => $consumer_key,
           'oauth_nonce' => time(),
           'oauth_signature_method' => 'HMAC-SHA1',
           'oauth_token' => $oauth_access_token,
           'oauth_timestamp' => time(),
           'oauth_version' => '1.0'
         );

$options = array(
             CURLOPT_HTTPHEADER => $header,
             //CURLOPT_POSTFIELDS => $postfields,
             CURLOPT_HEADER => false,
             CURLOPT_URL => $url . '?screen_name=DwightHoward&count=2',
             CURLOPT_RETURNTRANSFER => true, CURLOPT_SSL_VERIFYPEER => false
           );
lackovic10
quelle
2
Ich kann das nicht genug abstimmen. In der API-Dokumentation von Twitter sieht man dies ins Gesicht, aber es ist nie super "offensichtlich". Beeinträchtigt dieser Ansatz die buildAuthorizationHeaderFunktion? Ich habe es separat implementiert.
Moe
Ich habe lange nicht mehr damit gearbeitet, daher erinnere ich mich nicht, wenn Sie Ihr Problem noch nicht gelöst haben, kann ich es in den nächsten Tagen untersuchen.
lackovic10
Ich habe versucht, Ihre Lösung anzupassen, um den POST für statuses / update.json ohne Glück durchzuführen. Haben Sie eine Idee, wie dies erreicht werden könnte?
Perrohunter
1
@perrohunter Ich habe keine Ahnung, dass ich mehr darüber nachdenken müsste. Wenn Sie in ein paar Tagen keinen Weg finden, senden Sie mir eine Nachricht. Ich werde versuchen, Ihnen zu helfen.
lackovic10
18

Erstellen Sie, wie in anderen Antworten angegeben, eine Twitter-App, um Token, Schlüssel und Geheimnis zu erhalten. Mit dem folgenden Code können Sie Anforderungsparameter von einer Stelle aus ändern und Tippfehler und ähnliche Fehler vermeiden ( $requestArray in returnTweet()Funktion ändern ).

function buildBaseString($baseURI, $method, $params) {
    $r = array();
    ksort($params);
    foreach($params as $key=>$value){
        $r[] = "$key=" . rawurlencode($value);
    }
    return $method."&" . rawurlencode($baseURI) . '&' . rawurlencode(implode('&', $r));
}

function buildAuthorizationHeader($oauth) {
    $r = 'Authorization: OAuth ';
    $values = array();
    foreach($oauth as $key=>$value)
        $values[] = "$key=\"" . rawurlencode($value) . "\"";
    $r .= implode(', ', $values);
    return $r;
}

function returnTweet(){
    $oauth_access_token         = "x";
    $oauth_access_token_secret  = "x";
    $consumer_key               = "x";
    $consumer_secret            = "x";

    $twitter_timeline           = "user_timeline";  //  mentions_timeline / user_timeline / home_timeline / retweets_of_me

    //  create request
        $request = array(
            'screen_name'       => 'budidino',
            'count'             => '3'
        );

    $oauth = array(
        'oauth_consumer_key'        => $consumer_key,
        'oauth_nonce'               => time(),
        'oauth_signature_method'    => 'HMAC-SHA1',
        'oauth_token'               => $oauth_access_token,
        'oauth_timestamp'           => time(),
        'oauth_version'             => '1.0'
    );

    //  merge request and oauth to one array
        $oauth = array_merge($oauth, $request);

    //  do some magic
        $base_info              = buildBaseString("https://api.twitter.com/1.1/statuses/$twitter_timeline.json", 'GET', $oauth);
        $composite_key          = rawurlencode($consumer_secret) . '&' . rawurlencode($oauth_access_token_secret);
        $oauth_signature            = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
        $oauth['oauth_signature']   = $oauth_signature;

    //  make request
        $header = array(buildAuthorizationHeader($oauth), 'Expect:');
        $options = array( CURLOPT_HTTPHEADER => $header,
                          CURLOPT_HEADER => false,
                          CURLOPT_URL => "https://api.twitter.com/1.1/statuses/$twitter_timeline.json?". http_build_query($request),
                          CURLOPT_RETURNTRANSFER => true,
                          CURLOPT_SSL_VERIFYPEER => false);

        $feed = curl_init();
        curl_setopt_array($feed, $options);
        $json = curl_exec($feed);
        curl_close($feed);

    return json_decode($json, true);
}

und dann einfach anrufen returnTweet()

Budidino
quelle
1
Super Job @budidino! Erstellt die Anwendung auf dev.twitter.com/apps und füllt Ihre x mit oauth_access_token, oauth_access_token_secret, consumer_key, consumer_secret. * beachte *, dass du auf "Mein Zugriffstoken erstellen" klicken musst und es einige Sekunden dauert, bis es generiert wird. Bitte warte darauf.
Theo
@ Budidino dnt wir müssen jede Bibliothek enthalten?
Anam
Ich habe die Schlüssel ausgefüllt, diese zu meiner functions.phpDatei in WordPress hinzugefügt , <?php echo returnTweet(); ?>eine HTML-Datei eingefügt und das Wort "Array" und sonst nichts ausgegeben.
J82
@Desi, das Ergebnis ist eine Reihe von Tweets. Sie sollten damit umgehen, wie Sie die einzelnen Tweets anzeigen. Versuchen Sie print_r (returnTweet ()), um zu sehen, was drin ist. Schauen Sie sich dieses Beispiel für die Anzeige aller Tweets an: gist.github.com/budidino/9681764#file-stackoverflow-returntweet
budidino
1
Wenn Sie nur den neuesten Tweet abrufen möchten, sollten Sie das Array $ request ändern und count auf 1 setzen. Angenommen, Sie verwenden $ tweet = returnTweet (); Wenn Sie dann den neuesten Tweet anzeigen möchten (in diesem Fall den einzigen), können Sie Folgendes schreiben: echo "letzter Tweet:". $ tweet [0] ["text"]; Überprüfen Sie unbedingt die Struktur der zurückgegebenen Twitter-Nachrichten, wenn Sie mehr als nur den Text des Tweets abrufen möchten (Beispiel $ userProfileImageURL = $ tweet [0] ["user"] ["profile_image_url"]). dev.twitter.com/docs/api/1.1/get/statuses/user_timeline
Budidino
16

Danke Kris!

Es hat bei mir funktioniert, ohne Parameter für die Abfrage zu verwenden. Wenn ich mehr als einen Parameter verwendet habe, wurde mir der Fehler angezeigt: 32 Sie konnten nicht authentifiziert werden.

Das Problem für mich war die kaufmännische Und-Kodierung. Also in Ihrem Code, wo es die folgende Zeile ist

$url .= "?".http_build_query($query);

Ich habe die folgende Zeile hinzugefügt:

$url=str_replace("&amp;","&",$url);

Und es funktionierte mit zwei oder mehr Parametern wie screen_name und count.

Der gesamte Code sieht folgendermaßen aus:

$token = 'YOUR TOKEN';
$token_secret = 'TOKEN SECRET';
$consumer_key = 'YOUR KEY';
$consumer_secret = 'KEY SECRET';

$host = 'api.twitter.com';
$method = 'GET';
$path = '/1.1/statuses/user_timeline.json'; // api call path

$query = array( // query parameters
    'screen_name' => 'twitterapi',
    'count' => '2'
);

$oauth = array(
    'oauth_consumer_key' => $consumer_key,
    'oauth_token' => $token,
    'oauth_nonce' => (string)mt_rand(), // a stronger nonce is recommended
    'oauth_timestamp' => time(),
    'oauth_signature_method' => 'HMAC-SHA1',
    'oauth_version' => '1.0'
);

$oauth = array_map("rawurlencode", $oauth); // must be encoded before sorting
$query = array_map("rawurlencode", $query);

$arr = array_merge($oauth, $query); // combine the values THEN sort

asort($arr); // secondary sort (value)
ksort($arr); // primary sort (key)

// http_build_query automatically encodes, but our parameters
// are already encoded, and must be by this point, so we undo
// the encoding step
$querystring = urldecode(http_build_query($arr, '', '&'));

$url = "https://$host$path";

// mash everything together for the text to hash
$base_string = $method."&".rawurlencode($url)."&".rawurlencode($querystring);

// same with the key
$key = rawurlencode($consumer_secret)."&".rawurlencode($token_secret);

// generate the hash
$signature = rawurlencode(base64_encode(hash_hmac('sha1', $base_string, $key, true)));

// this time we're using a normal GET query, and we're only encoding the query params
// (without the oauth params)
$url .= "?".http_build_query($query);
$url=str_replace("&amp;","&",$url); //Patch by @Frewuill

$oauth['oauth_signature'] = $signature; // don't want to abandon all that work!
ksort($oauth); // probably not necessary, but twitter's demo does it

// also not necessary, but twitter's demo does this too
function add_quotes($str) { return '"'.$str.'"'; }
$oauth = array_map("add_quotes", $oauth);

// this is the full value of the Authorization line
$auth = "OAuth " . urldecode(http_build_query($oauth, '', ', '));

// if you're doing post, you need to skip the GET building above
// and instead supply query parameters to CURLOPT_POSTFIELDS
$options = array( CURLOPT_HTTPHEADER => array("Authorization: $auth"),
                  //CURLOPT_POSTFIELDS => $postfields,
                  CURLOPT_HEADER => false,
                  CURLOPT_URL => $url,
                  CURLOPT_RETURNTRANSFER => true,
                  CURLOPT_SSL_VERIFYPEER => false);

// do our business
$feed = curl_init();
curl_setopt_array($feed, $options);
$json = curl_exec($feed);
curl_close($feed);

$twitter_data = json_decode($json);

Hoffe, es hilft jemandem mit dem gleichen Problem, das ich hatte.

Frewuill
quelle
Vielen Dank, Ihre Code-Verbesserung funktioniert gut! Eine Frage zu: "// Eine stärkere Nonce wird empfohlen". Was könnte das sein? Zeit()?
Sebastian
Vielen Dank für den Hinweis. Sebastian: Ein Nonce ist ein Einweg-Token, das kryptografisch sicher sein sollte. mt_rand () ist sowohl zu kurz (32 Bit) als auch kein kryptografisches PRNG. Theoretisch macht dies das oauth-Token schwach, aber der Einfachheit halber wollte ich in meinem ursprünglichen Beispielcode etwas verwenden, das in PHP zur Hand war und leicht verständlich war.
Kris Reeves
Fehler empfangen 32. Konnte Sie nicht authentifizieren .. Hilfe bitte ??? Ich habe Ihren obigen Code verwendet
Saadk
@frewuill, du bist großartig, Bruder, es wirkt mir wie ein Zauber, danke.
Vijay
9

Diese Frage hat mir sehr geholfen, aber nicht ganz verstanden, was passieren muss. Dieser Blog-Beitrag hat großartige Arbeit geleistet und mich durch den Blog geführt .

Hier sind die wichtigen Punkte an einem Ort:

  • Wie oben erwähnt, MÜSSEN Sie Ihre 1.1 API-Anforderungen signieren. Wenn Sie beispielsweise einen öffentlichen Status erhalten möchten, möchten Sie einen Anwendungsschlüssel anstelle eines Benutzerschlüssels. Der vollständige Link zu der gewünschten Seite lautet: https://dev.twitter.com/apps
  • Sie müssen ALLE Parameter, sowohl die Oauth-Parameter als auch die Get-Parameter (oder POST-Parameter), hashen.
  • Sie müssen die Parameter SORTIEREN, bevor Sie sie auf die URL-codierte Form reduzieren, die gehasht wird.
  • Sie müssen einige Dinge mehrmals codieren. Beispielsweise erstellen Sie eine Abfragezeichenfolge aus den URL-codierten Werten der Parameter. Anschließend codieren Sie DIESE URL und verketten sie mit dem Methodentyp und der URL.

Ich sympathisiere mit all den Kopfschmerzen, also hier ein Code, um alles zusammenzufassen:

$token = 'YOUR TOKEN';
$token_secret = 'TOKEN SECRET';
$consumer_key = 'YOUR KEY';
$consumer_secret = 'KEY SECRET';

$host = 'api.twitter.com';
$method = 'GET';
$path = '/1.1/statuses/user_timeline.json'; // api call path

$query = array( // query parameters
    'screen_name' => 'twitterapi',
    'count' => '2'
);

$oauth = array(
    'oauth_consumer_key' => $consumer_key,
    'oauth_token' => $token,
    'oauth_nonce' => (string)mt_rand(), // a stronger nonce is recommended
    'oauth_timestamp' => time(),
    'oauth_signature_method' => 'HMAC-SHA1',
    'oauth_version' => '1.0'
);

$oauth = array_map("rawurlencode", $oauth); // must be encoded before sorting
$query = array_map("rawurlencode", $query);

$arr = array_merge($oauth, $query); // combine the values THEN sort

asort($arr); // secondary sort (value)
ksort($arr); // primary sort (key)

// http_build_query automatically encodes, but our parameters
// are already encoded, and must be by this point, so we undo
// the encoding step
$querystring = urldecode(http_build_query($arr, '', '&'));

$url = "https://$host$path";

// mash everything together for the text to hash
$base_string = $method."&".rawurlencode($url)."&".rawurlencode($querystring);

// same with the key
$key = rawurlencode($consumer_secret)."&".rawurlencode($token_secret);

// generate the hash
$signature = rawurlencode(base64_encode(hash_hmac('sha1', $base_string, $key, true)));

// this time we're using a normal GET query, and we're only encoding the query params
// (without the oauth params)
$url .= "?".http_build_query($query);

$oauth['oauth_signature'] = $signature; // don't want to abandon all that work!
ksort($oauth); // probably not necessary, but twitter's demo does it

// also not necessary, but twitter's demo does this too
function add_quotes($str) { return '"'.$str.'"'; }
$oauth = array_map("add_quotes", $oauth);

// this is the full value of the Authorization line
$auth = "OAuth " . urldecode(http_build_query($oauth, '', ', '));

// if you're doing post, you need to skip the GET building above
// and instead supply query parameters to CURLOPT_POSTFIELDS
$options = array( CURLOPT_HTTPHEADER => array("Authorization: $auth"),
                  //CURLOPT_POSTFIELDS => $postfields,
                  CURLOPT_HEADER => false,
                  CURLOPT_URL => $url,
                  CURLOPT_RETURNTRANSFER => true,
                  CURLOPT_SSL_VERIFYPEER => false);

// do our business
$feed = curl_init();
curl_setopt_array($feed, $options);
$json = curl_exec($feed);
curl_close($feed);

$twitter_data = json_decode($json);
Kris Reeves
quelle
6

Wenn Sie die OAuth PHP-Bibliothek installiert haben, müssen Sie sich nicht darum kümmern, die Anforderung selbst zu erstellen.

$oauth = new OAuth($consumer_key, $consumer_secret, OAUTH_SIG_METHOD_HMACSHA1, OAUTH_AUTH_TYPE_URI);
$oauth->setToken($access_token, $access_secret);

$oauth->fetch("https://api.twitter.com/1.1/statuses/user_timeline.json");
$twitter_data = json_decode($oauth->getLastResponse());

print_r($twitter_data);

Weitere Informationen finden Sie unter Die Dokumente oder deren Beispiel . Sie können verwenden pecl install oauth, um die Bibliothek zu erhalten.

jeffaudio
quelle
5

Zunächst wollte ich mich bei jimbo und ( seiner einfachen Bibliothek post / twitter-api-php) bedanken .

Wenn Sie die GET-Such- / Tweets-API mit der PHP-Bibliothek "twitter-api-php" (TwitterAPIExchange.php) verwenden möchten:

Zuerst müssen Sie nur den Codebereich "POST-Anforderung ausführen und Antwort wiederholen" kommentieren.

Verwenden Sie einfach den Code "GET-Anforderung ausführen und die Antwort wiederholen" und geben Sie die Antwort wieder und ändern Sie diese beiden Zeilen:

$url = 'https://api.twitter.com/1.1/followers/ids.json';
$getfield = '?screen_name=J7mbo';

zu

$url = 'https://api.twitter.com/1.1/search/tweets.json';
$getfield = '?q=J7mbo';

(Wechseln screen_namezu q, das war's :)

Chanuka Asanka
quelle
Ich habe immer noch kein Glück: /
Ricardo
2

Sie benötigen eine, um eine "App" auf Twitter zu erstellen (und Sie benötigen dazu ein Twitter-Konto).

Anschließend müssen Sie OAuth verwenden, um eine autorisierte Anfrage an Twitter zu stellen .

Sie können die Ressource GET statuses / user_timeline verwenden , um eine Liste der letzten Tweets abzurufen .

Matthew Rapati
quelle
4
Bitte erklären Sie uns dummen Leuten. Sie geben so viel Einblick, wenn nicht weniger, als die Dokumentation. Verwenden Sie die PHP- HttpRequest()Funktion für Schritt 2? Es gibt Abrahams TwitterOAuth PHP - github.com/abraham/twitteroauth - Bibliothek, die dies ebenfalls tun soll, aber ein Beispiel für die Implementierung wird nicht wirklich bereitgestellt.
RCNeil
2
github.com/abraham/twitteroauth/blob/master/test.php scheint viele Beispiele zu haben!
Matthew Rapati
2
@MatthewRapati Seite fehlt.
RN Kushwaha
0

Hier ist eine kurze Beschreibung zum Abrufen einer bestimmten Anzahl von Tweets aus Ihrer Timeline. Es macht im Grunde das Gleiche wie die anderen Beispiele, nur mit weniger Code.

Füllen Sie einfach die Tasten aus und passen Sie $countsie Ihren Wünschen an:

$url = 'https://api.twitter.com/1.1/statuses/user_timeline.json';
$count = '10';

$oauth = array('count' => $count,
               'oauth_consumer_key' => '[CONSUMER KEY]',
               'oauth_nonce' => md5(mt_rand()),
               'oauth_signature_method' => 'HMAC-SHA1',
               'oauth_timestamp' => time(),
               'oauth_token' => '[ACCESS TOKEN]',
               'oauth_version' => '1.0');

$oauth['oauth_signature'] = base64_encode(hash_hmac('sha1', 'GET&' . rawurlencode($url) . '&' . rawurlencode(implode('&', array_map(function ($v, $k) { return $k . '=' . $v; }, $oauth, array_keys($oauth)))), '[CONSUMER SECRET]&[ACCESS TOKEN SECRET]', true));

$twitterData = json_decode(file_get_contents($url . '?count=' . $count, false, stream_context_create(array('http' => array('method' => 'GET',
                                                                                                                           'header' => 'Authorization: OAuth ' 
                                                                                                                                       . implode(', ', array_map(function ($v, $k) { return $k . '="' . rawurlencode($v) . '"'; }, $oauth, array_keys($oauth))))))));

Dieser verwendet anonyme Funktionen und file_get_contentsanstelle der cURL-Bibliothek. Beachten Sie die Verwendung eines MD5-Hash-Nonce. Jeder scheint dem time()Nonce zuzustimmen, jedoch verwenden die meisten Beispiele im Internet in Bezug auf OAuth eine Art verschlüsselten String (wie diesen: http://www.sitepoint.com/understanding-oauth-1/ ). Das macht auch für mich mehr Sinn.

Weiterer Hinweis: Sie benötigen PHP 5.3+ für die anonymen Funktionen (falls sich Ihr Server / Computer in einer Höhle des Kalten Krieges befindet und Sie ihn nicht aktualisieren können).

Kasimir
quelle
-1

Über ihren Signaturgenerator können Sie curlBefehle der folgenden Form generieren :

curl --get 'https://api.twitter.com/1.1/statuses/user_timeline.json' --data 'count=2&screen_name=twitterapi' --header 'Authorization: OAuth oauth_consumer_key="YOUR_KEY", oauth_nonce="YOUR_NONCE", oauth_signature="YOUR-SIG", oauth_signature_method="HMAC-SHA1", oauth_timestamp="TIMESTAMP", oauth_token="YOUR-TOKEN", oauth_version="1.0"' --verbose
Gerämie
quelle
-2
$connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, OAUTH_TOKEN, OAUTH_TOKEN_SECRET);

$timelines = $connection->get('statuses/user_timeline', array('screen_name' => 'NSE_NIFTY', 'count' => 100, 'include_rts' => 1));
Mohd Abdul Baquee
quelle
3
Bitte geben Sie eine Erklärung dazu an, was dieser Code bewirkt, damit das OP daraus lernen kann.
Cerbrus
-2

Dank diesem Thread und besonders Budidino, weil sein Code es für mich nach Hause gebracht hat. Ich wollte nur dazu beitragen, wie die JSON-Daten aus einer Anfrage abgerufen werden. Nehmen Sie Änderungen am Anforderungsarray "// Anforderung erstellen" des Codes vor, um verschiedene Anforderungen auszuführen. Letztendlich wird der JSON auf dem Browserbildschirm ausgegeben

<?php
    function buildBaseString($baseURI, $method, $params) {
    $r = array();
    ksort($params);
    foreach($params as $key=>$value){
        $r[] = "$key=" . rawurlencode($value);
    }
    return $method."&" . rawurlencode($baseURI) . '&' . rawurlencode(implode('&', $r));
}

function buildAuthorizationHeader($oauth) {
    $r = 'Authorization: OAuth ';
    $values = array();
    foreach($oauth as $key=>$value)
        $values[] = "$key=\"" . rawurlencode($value) . "\"";
    $r .= implode(', ', $values);
    return $r;
}

function returnTweet(){
    $oauth_access_token         = "2602299919-lP6mgkqAMVwvHM1L0Cplw8idxJzvuZoQRzyMkOx";
    $oauth_access_token_secret  = "wGWny2kz67hGdnLe3Uuy63YZs4nIGs8wQtCU7KnOT5brS";
    $consumer_key               = "zAzJRrPOj5BvOsK5QhscKogVQ";
    $consumer_secret            = "Uag0ujVJomqPbfdoR2UAWbRYhjzgoU9jeo7qfZHCxR6a6ozcu1";

    $twitter_timeline           = "user_timeline";  //  mentions_timeline / user_timeline / home_timeline / retweets_of_me

    //  create request
        $request = array(
            'screen_name'       => 'burownrice',
            'count'             => '3'
        );

    $oauth = array(
        'oauth_consumer_key'        => $consumer_key,
        'oauth_nonce'               => time(),
        'oauth_signature_method'    => 'HMAC-SHA1',
        'oauth_token'               => $oauth_access_token,
        'oauth_timestamp'           => time(),
        'oauth_version'             => '1.0'
    );

    //  merge request and oauth to one array
        $oauth = array_merge($oauth, $request);

    //  do some magic
        $base_info              = buildBaseString("https://api.twitter.com/1.1/statuses/$twitter_timeline.json", 'GET', $oauth);
        $composite_key          = rawurlencode($consumer_secret) . '&' . rawurlencode($oauth_access_token_secret);
        $oauth_signature            = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
        $oauth['oauth_signature']   = $oauth_signature;

    //  make request
        $header = array(buildAuthorizationHeader($oauth), 'Expect:');
        $options = array( CURLOPT_HTTPHEADER => $header,
                          CURLOPT_HEADER => false,
                          CURLOPT_URL => "https://api.twitter.com/1.1/statuses/$twitter_timeline.json?". http_build_query($request),
                          CURLOPT_RETURNTRANSFER => true,
                          CURLOPT_SSL_VERIFYPEER => false);

        $feed = curl_init();
        curl_setopt_array($feed, $options);
        $json = curl_exec($feed);
        curl_close($feed);

    return $json;
}

$tweet = returnTweet();
echo $tweet;

?>
Terry Bu
quelle
-2

Wenn es für jemanden nützlich ist ... In meinem Blog habe ich den folgenden PHP-Code implementiert, um die letzten Tweets abzurufen, ihre relevantesten Daten zu extrahieren und sie dann in einer MySQL-Datenbank zu speichern. Es funktioniert, weil ich es in meinem Blog habe.

Die "Tweets" -Tabelle, in der sie gespeichert sind:

CREATE TABLE IF NOT EXISTS `tweets` (
  `tweet_id` int(11) NOT NULL auto_increment,
  `id_tweet` bigint(20) NOT NULL,
  `text_tweet` char(144) NOT NULL,
  `datetime_tweet` datetime NOT NULL,
  `dayofweek_tweet` char(3) NOT NULL,
  `GMT_tweet` char(5) NOT NULL,
  `shorturl_tweet` char(23) NOT NULL,
  PRIMARY KEY  (`tweet_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=83 ;

get_tweets.php:

<?php
function buildBaseString($baseURI, $method, $params) {
    $r= array();
    ksort($params);
    foreach($params as $key=>$value){
        $r[]= "$key=".rawurlencode($value);
    }
    return $method."&".rawurlencode($baseURI).'&'.rawurlencode(implode('&', $r));
}

function buildAuthorizationHeader($oauth) {
    $r= 'Authorization: OAuth ';
    $values= array();
    foreach($oauth as $key=>$value) {
        $values[]= "$key=\"".rawurlencode($value)."\"";
    }
    $r.= implode(', ', $values);
    return $r;
}

function returnTweets($last_id) {
    $oauth_access_token         = "2687912757-vbyfJA483SEyj2HJ2K346aVMxtOIgVbsY4Edrsw";
    $oauth_access_token_secret  = "nIruzmR0bXqC3has4fTf8KAq4pgOceiuKqjklhroENU4W";
    $api_key                    = "ieDSTFH8QHHPafg7H0whQB9GaY";
    $api_secret                 = "mgm8wVS9YP93IJmTQtsmR8ZJADDNdlTca5kCizMkC7O7gFDS1j";
    $twitter_timeline           = "user_timeline";  //[mentions_timeline/user_timeline/home_timeline/retweets_of_me]
    //create request
    $request= array(
        'screen_name'       => 'runs_ES',
        'count'             => '3',
        'exclude_replies'   => 'true'
        );
    if (!is_null($last_id)) { //Add to the request if it exits a last_id
        $request['since_id']= $max_id;
    }
    $oauth = array(
        'oauth_consumer_key'        => $api_key,
        'oauth_nonce'               => time(),
        'oauth_signature_method'    => 'HMAC-SHA1',
        'oauth_token'               => $oauth_access_token,
        'oauth_timestamp'           => time(),
        'oauth_version'             => '1.0'
        );
    //merge request and oauth to one array
    $oauth= array_merge($oauth, $request);
    //do some magic
    $base_info=                 buildBaseString("https://api.twitter.com/1.1/statuses/$twitter_timeline.json", 'GET', $oauth);
    $composite_key=             rawurlencode($api_secret).'&'.rawurlencode($oauth_access_token_secret);
    $oauth_signature=           base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
    $oauth['oauth_signature']=  $oauth_signature;
    //make request
    $header= array(buildAuthorizationHeader($oauth), 'Expect:');
    $options= array(CURLOPT_HTTPHEADER => $header,
                    CURLOPT_HEADER => false,
                    CURLOPT_URL => "https://api.twitter.com/1.1/statuses/$twitter_timeline.json?". http_build_query($request),
                    CURLOPT_RETURNTRANSFER => true,
                    CURLOPT_SSL_VERIFYPEER => false);
    $feed= curl_init();
    curl_setopt_array($feed, $options);
    $json= curl_exec($feed);
    curl_close($feed);
    return $json;
}

function parse_tweettext($tweet_text) {
    $text= substr($tweet_text, 0, -23);
    $short_url= substr($tweet_text, -23, 23);
    return array ('text'=>$text, 'short_url'=> $short_url);
}

function parse_tweetdatetime($tweetdatetime) {
    //Thu Aug 21 21:57:26 +0000 2014 Sun Mon Tue Wed Thu Fri Sat
    $months= array('Jan'=>'01', 'Feb'=>'02', 'Mar'=>'03', 'Apr'=>'04', 'May'=>'05', 'Jun'=>'06', 
                    'Jul'=>'07', 'Aug'=>'08', 'Sep'=>'09', 'Oct'=>'10', 'Nov'=>'11', 'Dec'=>'12');
    $GMT= substr($tweetdatetime, -10, 5);
    $year= substr($tweetdatetime, -4, 4);
    $month_str= substr($tweetdatetime, 4, 3);
    $month= $months[$month_str];
    $day= substr($tweetdatetime, 8, 2); 
    $dayofweek= substr($tweetdatetime, 0, 3);
    $time= substr($tweetdatetime, 11, 8);
    $date= $year.'-'.$month.'-'.$day;
    $datetime= $date.' '.$time;
    return array('datetime'=>$datetime, 'dayofweek'=>$dayofweek, 'GMT'=>$GMT);
    //datetime: "YYYY-MM-DD HH:MM:SS", dayofweek: Mon, Tue..., GMT: +####
}

//First check in the database the last id tweet:
$query= "SELECT MAX(tweets.id_tweet) AS id_last FROM tweets;";
$result= exec_query($query);
$row= mysql_fetch_object($result);
if ($result!= 0 && mysql_num_rows($result)) { //if error in query or not results
    $last_id= $row->id_last;
}
else {
    $last_id= null;
}

$json= returnTweets($last_id);
$tweets= json_decode($json, TRUE);

foreach ($tweets as $tweet) {
    $tweet_id= $tweet['id'];
    if (!empty($tweet_id)) { //if array is not empty
        $tweet_parsetext= parse_tweettext($tweet['text']);
        $tweet_text= utf8_encode($tweet_parsetext['text']);
        $tweet_shorturl= $tweet_parsetext['short_url'];
        $tweet_parsedt= parse_tweetdatetime($tweet['created_at']);
        $tweet_datetime= $tweet_parsedt['datetime'];
        $tweet_dayofweek= $tweet_parsedt['dayofweek'];
        $tweet_GMT= $tweet_parsedt['GMT'];
        //Insert the tweet into the database:
        $fields = array(
            'id_tweet' => $tweet_id,
            'text_tweet' => $tweet_text,
            'datetime_tweet' => $tweet_datetime,
            'dayofweek_tweet' => $tweet_dayofweek,
            'GMT_tweet' => $tweet_GMT,
            'shorturl_tweet' => $tweet_shorturl
            );
        $new_id= mysql_insert('tweets', $fields);
    }
} //end of foreach
?>

Die Funktion zum Speichern der Tweets:

function mysql_insert($table, $inserts) {
    $keys = array_keys($inserts);
    exec_query("START TRANSACTION;");
    $query= 'INSERT INTO `'.$table.'` (`'.implode('`,`', $keys).'`) VALUES (\''.implode('\',\'', $inserts).'\')';
    exec_query($query);
    $id= mysql_insert_id();
    if (mysql_error()) {
        exec_query("ROLLBACK;");
        die("Error: $query");
    }
    else {
        exec_query("COMMIT;");
    }
    return $id;
}
läuft
quelle
"Es funktioniert, weil ich es in meinem Blog habe" ist einer meiner Favoriten. Ihr Beitrag beantwortet die eigentliche Frage nicht. Auch der von Ihnen verwendete PHP-Code hat eine schlechte Qualität. Lesen Sie hier ein bisschen phptherightway.com . Besonders über DB
Maciej Paprocki
Außerdem haben Sie alle Ihre Schlüssel und Token veröffentlicht. Seien Sie also nicht überrascht, wenn jemand sie nimmt und Ihren Twitter-Account hackt!
Garrettlynch