Najprostszy przykład PHP do pobierania user_timeline z Twitter API w wersji 1.1


292

Z powodu wycofania Twitter API API 1.0 z 11 czerwca 2013 r. Poniższy skrypt już nie działa.

// 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);
    }
}

Jak mogę uzyskać linię czasu użytkownika (ostatnie statusy) z możliwie najmniejszym kodem?

Znalazłem to: https://dev.twitter.com/docs/api/1.1/get/statuses/user_timeline, ale pojawia się następujący błąd:

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

Istnieje wiele klas, ale po wypróbowaniu kilku z nich żadna z nich nie działa z powodu tych aktualizacji na Twitterze, a niektóre z nich są dość zaawansowanymi klasami z dużą ilością funkcji, których tak naprawdę nie potrzebuję.

Jaki jest najprostszy / najkrótszy sposób uzyskania najnowszych statusów użytkowników za pomocą PHP?


97
Zabiłbym za odpowiedź na to pytanie. Ich dokumentacja jest strasznie zła.
RCNeil

Jestem nowy w interfejsie API Twittera i mam z tym trochę trudności. Zauważyłem, że używam przestarzałego kodu.
Anthony


@ Mark Mark Mark !! To było łatwe!! Początkowo to nie działało. Używam WAMP. Musiałem dokonać zmian w pliku php.ini w katalogu Apache zgodnie z tym wątkiem: stackoverflow.com/questions/5444249/…
Adlin Ling

1
Właśnie spisałem rozwiązanie bez CURL lub innych dodatkowych bibliotek: stackoverflow.com/questions/17049821/…
Rauli Rajande

Odpowiedzi:


820

Ważna uwaga: od połowy 2018 r. Proces uzyskiwania twitterowych tokenów API stał się znacznie bardziej biurokratyczny. Dostarczenie zestawu tokenów API zajęło mi ponad tydzień roboczy. Dotyczy to projektu open source dla was, chłopaki i dziewczynki, z ponad 1,2 milionem instalacji na Packagist i 1,6 tysiącami gwiazd na Github, co teoretycznie powinno mieć wyższy priorytet .

Jeśli masz za zadanie pracować z twitterowym interfejsem API w swojej pracy, musisz wziąć pod uwagę ten potencjalnie wyjątkowo długi czas oczekiwania. Weź również pod uwagę inne możliwości mediów społecznościowych, takie jak Facebook czy Instagram, i podaj te opcje, ponieważ proces odzyskiwania ich tokenów jest natychmiastowy.


Więc chcesz użyć interfejsu API Twitter v1.1?

Uwaga: pliki dla nich znajdują się na GitHub .

Wersja 1.0 zostanie wkrótce uznana za przestarzałą i nie będą akceptowane nieautoryzowane żądania. Oto post, który pomoże Ci to zrobić, wraz z klasą PHP, która ułatwi ci życie.

1. Utwórz konto programisty: skonfiguruj konto dewelopera na Twitterze

Musisz odwiedzić oficjalną stronę programisty Twittera i zarejestrować konto programisty. To jest darmowy i niezbędny krok do zgłaszania żądań interfejsu API wersji 1.1.

2. Utwórz aplikację: Utwórz aplikację na stronie programisty Twitter

Co? Myślałeś, że możesz wysyłać nieuwierzytelnione wnioski? Nie z interfejsem API wersji 1.1 Twittera. Musisz odwiedzić http://dev.twitter.com/apps i kliknąć przycisk „Utwórz aplikację”.

Wpisz opis zdjęcia tutaj

Na tej stronie wpisz dowolne szczegóły. Dla mnie to nie miało znaczenia, ponieważ chciałem po prostu załadować wiele bloków, aby pozbyć się obserwujących spam. Chodzi o to, że zdobędziesz siebie zestaw unikalnych kluczy do użycia w swojej aplikacji.

Tak więc celem stworzenia aplikacji jest przekazanie sobie (i Twitterowi) zestawu kluczy. To są:

  • Klucz klienta
  • Tajemnica konsumencka
  • Token dostępu
  • Sekret tokena dostępu

Jest tu trochę informacji o tym, do czego służą te tokeny.

3. Utwórz tokeny dostępu : Będziesz ich potrzebować, aby pomyślnie wysyłać żądania

OAuth prosi o kilka tokenów. Musisz więc je wygenerować.

Wpisz opis zdjęcia tutaj

Kliknij „utwórz mój token dostępu” u dołu. Następnie po ponownym przewinięciu w dół będziesz mieć kilka nowo wygenerowanych kluczy. Musisz pobrać cztery wcześniej oznaczone klawisze z tej strony do wywołań API, więc zanotuj je gdzieś.

4. Zmień poziom dostępu : nie chcesz tylko do odczytu, prawda?

Jeśli chcesz w jakikolwiek sposób korzystać z tego interfejsu API, musisz zmienić ustawienia na Odczyt i zapis, jeśli robisz coś innego niż standardowe pobieranie danych przy użyciu żądań GET .

Wpisz opis zdjęcia tutaj

Wybierz kartę „Ustawienia” u góry strony.

Wpisz opis zdjęcia tutaj

Daj swojej aplikacji dostęp do odczytu / zapisu i kliknij „Aktualizuj” na dole.

Możesz przeczytać więcej na temat modelu uprawnień aplikacji , która korzysta z Twittera tutaj.


5. Napisz kod, aby uzyskać dostęp do API : Zrobiłem większość dla Ciebie

Połączyłem powyższy kod, z pewnymi modyfikacjami i zmianami, w klasę PHP, więc bardzo łatwo jest wykonać żądane żądania.

Korzysta z OAuth i interfejsu API Twittera 1.1 , a także utworzonej przeze mnie klasy, którą można znaleźć poniżej.

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

Upewnij się, że umieściłeś klucze otrzymane z aplikacji powyżej w odpowiednich miejscach.

Następnie musisz wybrać adres URL, na który chcesz wysłać zapytanie. Twitter ma dokumentację API, która pomaga wybrać adres URL, a także typ żądania (POST lub 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';

W dokumentacji każdy adres URL określa, co możesz mu przekazać. Jeśli używamy adresu URL „bloków”, takiego jak powyższy, mogę przekazać następujące parametry POST:

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

Po skonfigurowaniu tego, co chcesz zrobić z interfejsem API, nadszedł czas, aby złożyć właściwe żądanie.

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

I w przypadku żądania POST to wszystko!

W przypadku żądania GET jest nieco inaczej. Oto przykład:

/** 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();     

Przykładowy kod końcowy : proste zapytanie GET o listę moich obserwujących.

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

Umieściłem te pliki na GitHub z podziękowaniem dla @ missingovic10 i @rivers! Mam nadzieję, że ktoś uzna to za przydatne; Wiem, że tak (użyłem go do masowego blokowania w pętli).

Również dla osób w systemie Windows, które mają problemy z certyfikatami SSL, spójrz na ten post . Ta biblioteka używa cURL pod maską, więc musisz upewnić się, że prawdopodobnie masz skonfigurowane certyfikaty cURL. Google jest także twoim przyjacielem.


4
@kaffolder Link na tej stronie: profilepicture.co.uk/caching-api-respactions-php sugeruje prosty sposób na zrobienie tego. Zapisujesz dane twittera w pliku lub bazie danych (MySQL lub MongoDB) na pierwsze żądanie, a następnie przy każdym kolejnym żądaniu sprawdzasz aktualny czas w stosunku do limitu czasu, jaki chcesz dla pliku (możesz nazwać plik jako termin), i jeśli plik istnieje, a nazwa pliku mieści się w żądanym terminie, pobierz dane zamiast wykonać żądanie interfejsu API. Jeśli plik istnieje, ale upłynął limit czasu, usuń plik, a następnie wykonaj żądanie API.
Jimbo,

7
Nie mogę wymyślić, jak obsługiwać dane JSON po ich zwróceniu. Nie chcę po prostu wyświetlać go na ekranie, jak w echu $ twitter -> setGetfield ($ getfield) -> buildOauth ($ url, $ requestMethod) -> performRequest (); PRZEPROWADZKI, nie mogę wymyślić, jak robić nowe wiersze! Chcę zrobić coś takiego jak $ jsonData = json_decode ($ twitter); ale to nie działa - mam wrażenie, że brakuje mi czegoś fundamentalnego, ale ani grosza nie spada ...
Ashley

67
Dziękujemy, dokumentacja Twittera to niezorganizowany bałagan, co bardzo pomogło.
joren

7
Jest wiele warunków, aby ta klasa działała w systemie Windows. Musisz mieć działającą wersję cURL załadowaną do php.inipliku, a także załadować certyfikaty CA do php.inipliku za pomocą curl.cainfo = path\to\cacert.pem. Możesz uzyskać certyfikaty CA tutaj .
Jake Z

4
@Jimbo Właśnie zauważyłem, że niektóre z domyślnych rozszerzeń cURL są błędne w systemie Windows i wymagają wymiany (stąd link do wersji „naprawionej”) i że bez ładowania certyfikatów CA klasa zwraca wartość false, ponieważ curl_error () zgłasza, że ​​`Problem z certyfikatem SSL, sprawdź, czy certyfikat CA jest OK`. Można tego uniknąć, wyłączając CURLOPT_SSL_VERIFYPEER, ale pomyślałem, że dołączę podstawowe instrukcje dotyczące korzystania z certyfikatów urzędu certyfikacji. Wystarczy dołączyć to, aby potencjalnie zaoszczędzić niektórym osobom kilka minut wyszukiwania.
Jake Z

137

Wejdź na dev.twitter.com i utwórz aplikację . Zapewni to niezbędne poświadczenia. Oto implementacja, którą ostatnio napisałem w PHP i cURL .

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

?>

Można to uruchomić z wiersza poleceń:

$ php <name of PHP script>.php

2
Dzięki za fragment kodu, działaj bezbłędnie. Jedynym problemem jest to, że nie potrafię wymyślić, jak ustawić zwrot liczby postów. Zwraca tylko 20 i chcę pełną kwotę, która wynosi 200 zgodnie z limitem twittera.
Flatlyn

23
Jak ustaliłbyś screen_namei countprzy takim podejściu? Próbowałem dodać ją do $urlzmiennej, ale wystąpił błąd „Nie można Cię uwierzytelnić”.
Javier Villanueva

1
Ten kod działa świetnie! Próbuję go zmodyfikować, aby używał interfejsu API search / tweets.json, ale zawsze otrzymuję odpowiedź „nie mogę Cię uwierzytelnić” - jakieś pomysły?
Chris

1
Ten post był bardzo pomocny. Wydaje się curl_init()jednak, że mój kod nie wraca . Przejrzałem kilka przykładów, które wyglądają bardzo prosto i dokładnie i dokładnie tak, jak ten kod tutaj ... Czy muszę zainstalować coś specjalnego?
jessicaraygun

1
Udało mi się to 26 października 2016 r. Wydajność była nieco bardziej złożona niż się spodziewałem.
JohnC

61

Kod wklejony przez Rivers jest świetny. Wielkie dzięki! Jestem tu nowy i nie mogę komentować, chciałbym tylko odpowiedzieć na pytanie z javiervd (Jak ustawiłbyś screen_name i policzyłeś z tym podejściem?), Ponieważ straciłem dużo czasu, aby to rozgryźć na zewnątrz.

Musisz dodać parametry zarówno do adresu URL, jak i do procesu tworzenia podpisu. Stworzenie podpisu to artykuł, który mi pomógł. Oto mój kod:

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

2
Nie mogę wystarczająco głosować. W dokumentacji API Twittera wpatruje się to w twarz, ale nigdy nie jest to „oczywiste”. Czy to podejście nie buildAuthorizationHeaderzadziała z funkcją? Zaimplementowałem to osobno.
Moe

Dawno nie pracowałem nad tym, więc nie pamiętam, jeśli nie rozwiązałeś jeszcze swojego problemu, mogę przyjrzeć się temu w kolejnych dniach.
brakovic10

Próbowałem dostosować Twoje rozwiązanie do wykonywania testu POST na status / update.json bez powodzenia, czy masz pojęcie, jak to osiągnąć?
perrohunter

1
@perrohunter nie mam pojęcia, musiałbym przyjrzeć się temu bardziej. Jeśli w ciągu kilku dni nie znajdziesz sposobu, wyślij mi wiadomość, postaram się ci pomóc.
brakovic10

18

Jak podano w innych odpowiedziach, utwórz aplikację na Twitterze, aby uzyskać token, klucz i sekret. Korzystając z poniższego kodu, możesz modyfikować parametry żądania z jednego miejsca i unikać literówek i podobnych błędów (zmień $requesttablicę w returnTweet()funkcji).

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

a potem po prostu zadzwoń returnTweet()


1
Niesamowita praca @budidino! Utworzyłeś aplikację na dev.twitter.com/apps i wypełniłeś swoje xy oauth_access_token, oauth_access_token_secret, Consumer_key, Consumer_secret. * Uwaga *, że musisz nacisnąć „Utwórz mój token dostępu”, a wygenerowanie zajmuje kilka sekund, więc poczekaj na to.
Theo

@budidino dnt musimy dołączyć dowolną bibliotekę?
anam

Wypełniłem klucze, dodałem to do mojego functions.phppliku w WordPressie, umieściłem <?php echo returnTweet(); ?>w pliku HTML i wyświetla słowo „Array” i nic więcej.
J82

@Desi, wynikiem jest tablica tweetów, powinieneś obsługiwać sposób wyświetlania każdego z nich. spróbuj print_r (returnTweet ()), aby zobaczyć, co jest w środku. Sprawdź ten przykład wyświetlania wszystkich tweetów: gist.github.com/budidino/9681764#file-stackoverflow-returntweet
budidino

1
Jeśli chcesz pobrać tylko najnowszy tweet, powinieneś zmodyfikować tablicę $ request i ustawić count na 1. Powiedzmy, że używasz $ tweet = returnTweet (); następnie, jeśli chcesz wyświetlić najnowszy tweet (w tym przypadku jedyny), możesz napisać coś takiego: echo "najnowszy tweet:". $ tweet [0] ["text"]; Pamiętaj, aby sprawdzić strukturę zwróconego Twittera, jeśli chcesz wyciągnąć więcej niż tylko tekst tweeta (na przykład $ userProfileImageURL = $ tweet [0] [„user”] [„profile_image_url”]). dev.twitter.com/docs/api/1.1/get/statuses/user_timeline
budidino

16

Dziękuję Kris!

Działa dla mnie bez użycia parametrów do zapytania, ilekroć użyłem więcej niż jednego parametru, pokazywał mi błąd: 32 Nie można Cię uwierzytelnić.

Problemem było dla mnie kodowanie ampersand. Więc w twoim kodzie, gdzie jest następujący wiersz

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

Dodałem następujący wiersz poniżej:

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

I działało przy użyciu dwóch lub więcej parametrów, takich jak screen_name i count.

Cały kod wygląda następująco:

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

Mam nadzieję, że pomaga komuś z tym samym problemem, który miałem.


wielkie dzięki, poprawa kodu działa dobrze! Jedno pytanie dotyczy: „zalecana jest silniejsza nonce”. Co to może być? czas()?
Sebastian

Dzięki za zwrócenie na to uwagi. Sebastian: nonce jest tokenem jednorazowego użytku, który powinien być zabezpieczony kryptograficznie. mt_rand () jest zarówno zbyt krótki (32 bity), a nie kryptograficzny PRNG. Teoretycznie sprawia to, że token Oauth jest słaby, ale ze względu na prostotę w moim oryginalnym przykładowym kodzie chciałem użyć czegoś, co było pod ręką w PHP i było łatwe do zrozumienia.
Kris Reeves,

otrzymuję błąd 32. Nie można Cię uwierzytelnić .. jakiejkolwiek pomocy, proszę ??? Użyłem twojego powyższego kodu
saadk

@frewuill, jesteś świetny bracie, to działa jak urok, dzięki.
Vijay

9

To pytanie bardzo mi pomogło, ale nie pomogło mi zrozumieć, co musi się wydarzyć. Ten post na blogu wykonał niesamowitą robotę, przeprowadzając mnie przez niego.

Oto ważne bity w jednym miejscu:

  • Jak wspomniano powyżej, MUSISZ podpisać swoje żądania interfejsu API 1.1. Jeśli robisz coś takiego jak uzyskiwanie statusów publicznych, potrzebujesz klucza aplikacji, a nie klucza użytkownika. Pełny link do żądanej strony to: https://dev.twitter.com/apps
  • Musisz zaszyfrować WSZYSTKIE parametry, oba oauth ORAZ uzyskać parametry (lub parametry POST) razem.
  • Musisz SORTOWAĆ parametry, zanim zredukujesz je do zakodowanej formy adresu URL.
  • Musisz zakodować niektóre rzeczy wiele razy - na przykład, tworzysz ciąg zapytania z wartości zakodowanych w parametrach parametrów, a następnie url kodujesz TO i łączysz z typem metody i adresem URL.

Współczuję wszystkim bólom głowy, więc oto kod, aby to podsumować:

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

6

Jeśli masz zainstalowaną bibliotekę OAuth PHP, nie musisz się martwić o samodzielne utworzenie zapytania.

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

Aby uzyskać więcej informacji, zajrzyj na dokumenty lub ich przykładem . Możesz użyć, pecl install oauthaby uzyskać bibliotekę.


5

Przede wszystkim chciałem podziękować jimbo i ( jego prosta biblioteka post / twitter-api-php).

Jeśli zamierzasz używać interfejsu API wyszukiwania / tweetów GET z biblioteką PHP „twitter-api-php” (TwitterAPIExchange.php):

Najpierw musisz po prostu skomentować obszar kodu „Wykonaj żądanie POST i powtórz odpowiedź”.

Wystarczy użyć kodu „Wykonaj żądanie GET i echo odpowiedzi” i powtórz odpowiedź i zmień te dwa wiersze:

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

do

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

(Zmień screen_namena q, to wszystko :)


Nadal nie mam szczęścia: /
Ricardo

2

Musisz stworzyć „aplikację” na Twitterze (i potrzebujesz konta na Twitterze, aby to zrobić).

Następnie musisz użyć OAuth, aby złożyć autoryzowane żądanie na Twitterze .

Możesz użyć zasobu GET statusy / user_timeline, aby uzyskać listę ostatnich tweetów.


4
Proszę, dla nas, głupi ludzie, wyjaśnijcie. Dajesz tyle samo wglądu, jeśli nie mniej, niż dokumentację. Czy używasz HttpRequest()funkcji PHP dla kroku 2? Istnieje biblioteka Abrahama TwitterOAuth PHP - github.com/abraham/twitteroauth - biblioteka, która również powinna to robić, ale przykład, jak ją zaimplementować, nie jest tak naprawdę dostępny.
RCNeil


2
Brak strony @MatthewRapati.
RN Kushwaha

0

Oto krótki sposób pobierania określonej liczby tweetów z osi czasu. Zasadniczo robi to samo co inne przykłady, tylko z mniejszym kodem.

Wystarczy wypełnić klucze i dostosować $countdo swoich upodobań:

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

Ten używa anonimowych funkcji i file_get_contentszamiast biblioteki cURL. Zwróć uwagę na użycie skrótu MD5. Wydaje się, że wszyscy zgadzają się z tym time()nonce, jednak większość przykładów w Internecie dotyczących OAuth używa jakiegoś zaszyfrowanego ciągu (jak ten: http://www.sitepoint.com/understanding-oauth-1/ ). To też ma dla mnie większy sens.

Dodatkowa uwaga: potrzebujesz PHP 5.3+ do anonimowych funkcji (na wypadek, gdyby Twój serwer / komputer znajdował się w jaskini z czasów zimnej wojny i nie możesz go uaktualnić).


-1

Z ich generatora podpisów możesz generować curlpolecenia postaci:

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

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

3
Dołącz wyjaśnienie tego, co robi ten kod, aby OP mógł się z niego uczyć.
Cerbrus

-2

Dzięki temu wątkowi, a zwłaszcza budidino, ponieważ jego kod był tym, co doprowadziło mnie do domu. Chciałem tylko przyczynić się do odzyskania danych JSON z żądania. Dokonaj zmian w części kodu „// żądanie utworzenia” tablicy kodu, aby wykonać różne żądania. Ostatecznie spowoduje to wyświetlenie JSON na ekranie przeglądarki

<?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;

?>

-2

Jeśli jest to przydatne dla każdego ... Na moim blogu zaimplementowałem następujący kod PHP, aby pobrać ostatnie tweety, wyodrębnić ich najbardziej odpowiednie dane, a następnie zapisać je w bazie danych MySQL. Działa, ponieważ mam go na swoim blogu.

Tabela „tweety”, w której je przechowujesz:

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

Funkcja zapisywania tweetów:

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;
}

„Działa, bo mam go na swoim blogu” jest jednym z moich ulubionych. Twój post nie odpowiada na rzeczywiste pytanie. Również używany kod php ma złą jakość. Przeczytaj trochę tutaj phptherightway.com . Zwłaszcza o DB
Maciej Paprocki

Również upubliczniłeś wszystkie swoje klucze i tokeny, więc nie zdziw się, jeśli ktoś je weźmie i zhakuje twoje konto na Twitterze!
garrettlynch
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.