Heim  >  Artikel  >  Backend-Entwicklung  >  Erstellen Sie eine Twitter-OAuth-Anwendung

Erstellen Sie eine Twitter-OAuth-Anwendung

王林
王林Original
2023-08-27 20:33:04876Durchsuche

OAuth mag zunächst ein schwer zu verstehendes Konzept sein, aber da die Twitter-API jetzt ihre Verwendung erfordert, müssen Sie es verstehen, bevor Sie eine Twitter-Anwendung erstellen. Dieses Tutorial führt Sie in OAuth ein und führt Sie durch den Prozess der Erstellung einer Basisanwendung.


Einführung

In diesem Tutorial erstellen wir eine einfache Anwendung, mit der Benutzer verschiedene Effekte auf ihren Twitter-Avatar anwenden können. Um die Twitter-API verwenden zu können, müssen wir OAuth verwenden, um unsere Anwendung zu autorisieren, Anfragen im Namen des Benutzers zu stellen.

Unser Bewerbungsablauf wird wie folgt aussehen:

  1. Der Benutzer wird aufgefordert, eine Verbindung zu Twitter herzustellen.
  2. Das System zeigt dem Benutzer eine Vorschau-Avatarliste zur Auswahl an.
  3. Nach der Auswahl wird dem Benutzer ein Bestätigungsbildschirm angezeigt, auf dem der ursprüngliche Avatar und der neue Avatar zum Vergleich angezeigt werden. Benutzer können auch Tweets senden.
  4. Nachdem der Benutzer bestätigt hat, erstellt die App den geänderten Avatar, lädt ihn auf Twitter hoch und zeigt eine Erfolgsseite an.

Einstellungen

Zuerst sollten wir das Quellverzeichnis festlegen. Wir benötigen ein lib 目录来存放我们的 PHP 库(类)文件,一个 tmp 目录来保存临时文件(这需要服务器可写),一个 css 目录来存放我们的样式表,以及一个 img-Verzeichnis für alle Bilder.

Ihr Verzeichnisbaum sollte so aussehen:

  • Tutorial
    • CSS
    • Bilder
    • lib
    • tmp (beschreibbar)

Registrieren Sie Ihre Bewerbung

Um OAuth nutzen zu können, benötigen Sie einen sogenannten Verbraucherschlüssel und ein Geheimnis zur Identifizierung Ihrer Anwendung. Um diese Informationen zu erhalten, müssen Sie die folgenden Schritte ausführen, um Ihre Bewerbung bei Twitter zu registrieren.

Gehen Sie zur Registrierungsseite und melden Sie sich ggf. an. Sie sehen ein Formular wie dieses:

构建 Twitter OAuth 应用程序Erstellen Sie eine Twitter-OAuth-Anwendung构建 Twitter OAuth 应用程序

Füllen Sie das Formular mit Details zu Ihrer Bewerbung aus. In unserem Fall ist der Anwendungstyp ein Browser und wir müssen die standardmäßige Rückruf-URL festlegen. Die URL kann beliebig sein, solange sie in einem gültigen Format vorliegt. Wir werden den Rückruf im Code umschreiben, sodass es keine Rolle spielt, ob es sich um eine echte URL handelt. Der Einfachheit halber sollte der Standardzugriffstyp „Lesen und Schreiben“ sein. Nachdem Sie sich registriert und die Bedingungen akzeptiert haben, werden Ihnen Informationen zu Ihrer neuen Bewerbung angezeigt. Die wichtigen Details, die wir benötigen, sind der

Consumer Key

und das Consumer Secret, die wie folgt aussehen sollten:

构建 Twitter OAuth 应用程序 Erstellen Sie eine Twitter-OAuth-Anwendung 构建 Twitter OAuth 应用程序Laden Sie die tmhOAuth-Bibliothek herunter

Wir werden eine Bibliothek nutzen, um alle Details hinter OAuth-Anfragen zu verwalten. In diesem Tutorial verwenden wir die tmhOAuth-Bibliothek von @themattharris, die das Hochladen von Dateien unterstützt.

Laden Sie tmhOAuth von GitHub herunter
  1. Extrahieren Sie
  2. tmhOAuth.php
  3. in das lib-Verzeichnis, das wir zuvor erstellt haben
Authentifizierung

Die Authentifizierung mit OAuth ist grundsätzlich ein dreistufiger Prozess. Eine ausführlichere Erklärung finden Sie auf der Twitter-Seite zur Authentifizierung, aber hier ist eine Zusammenfassung:

App erhält Anforderungstoken: Der erste Schritt besteht darin, dass sich unsere App bei Twitter identifiziert (mithilfe ihres Verbraucherschlüssels) und ein
    Anfragetoken
  1. erhält. Wir müssen dieses Anforderungstoken zur späteren Verwendung speichern. Benutzer autorisiert App auf Twitter: Der Benutzer muss nun zu Twitter weitergeleitet werden, um unserer App Zugriff auf sein Konto zu gewähren. Der Benutzer wird dann an die von der Anwendung angegebene Rückruf-URL zurückgesendet.
  2. App tauscht Anforderungstoken gegen Zugriffstoken aus: Nachdem unser Antrag nun genehmigt wurde, kann er den Anforderungstoken aus Schritt 1 gegen ein Zugriffstoken austauschen.
  3. Nach Erhalt des Zugriffstokens kann unsere Anwendung im Namen des Benutzers frei mit der Twitter-API interagieren.
  4. Also fangen wir an, etwas Code zu schreiben. Wir werden den folgenden Code in einer neuen Datei namens
starten:

<?php
class TwitterApp {
    /**
     * This variable holds the tmhOAuth object used throughout the class
     *
     * @var tmhOAuth An object of the tmhOAuth class
     */
    public $tmhOAuth;

    /**
     * User's Twitter account data
     *
     * @var array Information on the current authenticated user
     */
    public $userdata;

    /**
     * Authentication state
     *
     * Values:
     *  - 0: not authed
     *  - 1: Request token obtained
     *  - 2: Access token obtained (authed)
     *
     * @var int The current state of authentication
     */
    protected $state;

    /**
     * Initialize a new TwitterApp object
     *
     * @param tmhOAuth $tmhOAuth A tmhOAuth object with consumer key and secret
     */
    public function  __construct(tmhOAuth $tmhOAuth) {
        
        // save the tmhOAuth object
        $this->tmhOAuth = $tmhOAuth;
    }
}

Hier erstellen wir drei Eigenschaften und einen einfachen Konstruktor. $tmhOAuth 属性将是一个 tmhOAuth 对象,它将在整个类中使用。 $userdata 属性将保存一个包含用户信息的对象,例如他们的 Twitter 用户名和状态。 $state Eigenschaft, die den aktuellen Authentifizierungsstatus verfolgt.

Der

-Konstruktor akzeptiert einfach ein tmhOAuth-Objekt und weist es der $tmhOAuth-Eigenschaft zu.


Schritt 1: Anforderungstoken erhalten

So erhalten Sie ein Anforderungstoken:

/**
 * Obtain a request token from Twitter
 *
 * @return bool False if request failed
 */
private function getRequestToken() {
    
    // send request for a request token
    $this->tmhOAuth->request("POST", $this->tmhOAuth->url("oauth/request_token", ""), array(
        // pass a variable to set the callback
        'oauth_callback'    => $this->tmhOAuth->php_self()
    ));

    if($this->tmhOAuth->response["code"] == 200) {
        
        // get and store the request token
        $response = $this->tmhOAuth->extract_params($this->tmhOAuth->response["response"]);
        $_SESSION["authtoken"] = $response["oauth_token"];
        $_SESSION["authsecret"] = $response["oauth_token_secret"];

        // state is now 1
        $_SESSION["authstate"] = 1;

        // redirect the user to Twitter to authorize
        $url = $this->tmhOAuth->url("oauth/authorize", "") . '?oauth_token=' . $response["oauth_token"];
        header("Location: ' . $url);
        exit;
    }
    return false;
}

Um den ersten Teil zu verstehen, müssen Sie die tmhOAuth::request()-Methode verstehen. Mit dieser Methode können wir eine OAuth-fähige HTTP-Anfrage stellen und können wie folgt verwendet werden:

tmhOAuth::request($method, $url[, $params[, $useauth[, $multipart]]])

  • string $method – Die zu verwendende Anforderungsmethode (GET, POST usw.)
  • string $url - URL zum Besuchen
  • array $params (optional) – Assoziatives Array von Parametern, die in die Anfrage einbezogen werden sollen
  • bool $useauth (optional, Standardwert true) – Ist eine Authentifizierung erforderlich?
  • bool $multipart (optional, Standardwert „false“) – Datei-Upload auf „true“ gesetzt

Für die $url 参数,我们使用 tmhOAuth::url()-Methode wird eine URL basierend auf der API-Methode erstellt, die wir aufgerufen haben:

tmhOAuth::url($request[, $format])

  • string $request - API-Methoden (ohne Erweiterung)
  • string $format (optional, Standard 'json") – das gewünschte Antwortformat (JSON, XML usw.)

Da Sie nun mit den Methoden vertraut sind, müssen wir eine POST-Anfrage an die API-Methode oauth/request_token stellen. Dadurch werden die OAuth-Daten in einem speziellen Format zurückgegeben, wenn wir also die tmhOAuth::url() 方法时,需要将格式设置为空白。我们还需要传递一个名为 oauth_callback 的变量,这是用户在 Twitter 授权后将返回的位置。我们将使用 tmhOAuth::php_self()-Methode verwenden, um auf die aktuelle Seite zu verweisen. Das ist der Code:

// send request for a request token
$this->tmhOAuth->request("POST", $this->tmhOAuth->url("oauth/request_token", ""), array(
    // pass a variable to set the callback
    'oauth_callback'    => $this->tmhOAuth->php_self()
));

Sobald wir die Anfrage gestellt haben, wird die Antwort im Attribut tmhOAuth::response als Array mit den folgenden Schlüsseldaten gespeichert:

  • code – HTTP-Antwortcode
  • response – tatsächlich zurückgegebene Daten
  • headers – Antwortheader

Der nächste Teil unseres Codes überprüft also den Antwortcode (200 für Erfolg) und übergibt dann die oauth_tokenoauth_token_secret 放入会话变量中,因为稍后我们将需要它们。这些是使用 tmhOAuth::extract_params() 方法从响应数据中提取的,该方法返回响应中包含的数据数组。我们还设置了 authstate Sitzungsvariable, die wir erhalten haben, um anzuzeigen, dass wir uns in der nächsten Phase der Authentifizierung befinden. Hier ist der Code:

if($this->tmhOAuth->response["code"] == 200) {

    // get and store the request token
    $response = $this->tmhOAuth->extract_params($this->tmhOAuth->response["response"]);
    $_SESSION["authtoken"] = $response["oauth_token"];
    $_SESSION["authsecret"] = $response["oauth_token_secret"];

    // state is now 1
    $_SESSION["authstate"] = 1;
}

Damit das erledigt ist, müssen wir den Benutzer nun zur oauth/authorize-URL umleiten, einschließlich des oauth_token in den GET-Parametern. Das ist der Code:

// redirect the user to Twitter to authorize
$url = $this->tmhOAuth->url("oauth/authorize", "") . '?oauth_token=' . $response["oauth_token"];
header("Location: ' . $url);
exit;

Schritt 2: Zugriffstoken erhalten

So tauschen Sie ein Anforderungstoken gegen ein Zugriffstoken ein:

/**
 * Obtain an access token from Twitter
 *
 * @return bool False if request failed
 */
private function getAccessToken() {

    // set the request token and secret we have stored
    $this->tmhOAuth->config["user_token"] = $_SESSION["authtoken"];
    $this->tmhOAuth->config["user_secret"] = $_SESSION["authsecret"];

    // send request for an access token
    $this->tmhOAuth->request("POST", $this->tmhOAuth->url("oauth/access_token", ""), array(
        // pass the oauth_verifier received from Twitter
        'oauth_verifier'    => $_GET["oauth_verifier"]
    ));

    if($this->tmhOAuth->response["code"] == 200) {

        // get the access token and store it in a cookie
        $response = $this->tmhOAuth->extract_params($this->tmhOAuth->response["response"]);
        setcookie("access_token", $response["oauth_token"], time()+3600*24*30);
        setcookie("access_token_secret", $response["oauth_token_secret"], time()+3600*24*30);

        // state is now 2
        $_SESSION["authstate"] = 2;

        // redirect user to clear leftover GET variables
        header("Location: ' . $this->tmhOAuth->php_self());
        exit;
    }
    return false;
}

Als Erstes müssen wir tmhOAuth::config 数组中的 user_tokenuser_secret auf den Anforderungstoken setzen, den wir zuvor erhalten haben.

// set the request token and secret we have stored
$this->tmhOAuth->config["user_token"] = $_SESSION["authtoken"];
$this->tmhOAuth->config["user_secret"] = $_SESSION["authsecret"];

Im nächsten Teil stellen wir die POST-Anfrage an oauth/access_token. Wir übergeben das oauth_verifier, das wir in der GET-Variablen erhalten haben, als Parameter in dieser Anfrage.

// send request for an access token
$this->tmhOAuth->request("POST", $this->tmhOAuth->url("oauth/access_token", ""), array(
    // pass the oauth_verifier received from Twitter
    'oauth_verifier'    => $_GET["oauth_verifier"]
));

Twitter antwortet mit dem Zugriffstoken und dem Geheimnis. Wir müssen diese Token für zukünftige Anfragen speichern. Der nächste Codeteil nimmt diese also, speichert jeden Inhalt in einem Cookie und setzt dann den Status auf 2.

if($this->tmhOAuth->response["code"] == 200) {

    // get the access token and store it in a cookie
    $response = $this->tmhOAuth->extract_params($this->tmhOAuth->response["response"]);
    setcookie("access_token", $response["oauth_token"], time()+3600*24*30);
    setcookie("access_token_secret", $response["oauth_token_secret"], time()+3600*24*30);

    // state is now 2
    $_SESSION["authstate"] = 2;

    // redirect user to clear leftover GET variables
    header("Location: ' . $this->tmhOAuth->php_self());
    exit;
}

Die letzte Umleitung besteht darin, die von Twitter hinterlassenen URL-Parameter zu löschen und das Cookie wirksam werden zu lassen.


Schritt 3: Zugriffstoken überprüfen

Nachdem wir das Zugriffstoken erhalten haben, sollten wir prüfen, ob es gültig ist. So geht's:

/**
 * Verify the validity of our access token
 *
 * @return bool Access token verified
 */
private function verifyAccessToken() {
    $this->tmhOAuth->config["user_token"] = $_COOKIE["access_token"];
    $this->tmhOAuth->config["user_secret"] = $_COOKIE["access_token_secret"];

    // send verification request to test access key
    $this->tmhOAuth->request("GET", $this->tmhOAuth->url("1/account/verify_credentials"));

    // store the user data returned from the API
    $this->userdata = json_decode($this->tmhOAuth->response["response"]);

    // HTTP 200 means we were successful
    return ($this->tmhOAuth->response["code"] == 200);
}

Dieser Code sollte Ihnen jetzt bekannt vorkommen. Alles, was wir hier tun, ist einzurichten user_tokenuser_secret und eine GET-Anfrage an 1/account/verify_credentials zu stellen. Wenn Twitter mit einem 200-Code antwortet, ist das Zugriffstoken gültig.

Ein weiteres zu beachtendes Detail ist, dass wir es hier mit den von dieser Twitter-Anfrage zurückgegebenen Daten füllen und es in ein PHP-Objekt konvertieren. Das ist wieder diese Zeile: $userdata 属性。数据是JSON格式的,所以我们使用json_decode()

// store the user data returned from the API
$this->userdata = json_decode($this->tmhOAuth->response["response"]);


Schritt 4: Alles zusammenbündeln

Sobald unsere OAuth-Komponenten vorhanden sind, ist es an der Zeit, alles zusammenzuführen. Wir benötigen eine öffentlich zugängliche Methode, damit unser Clientcode den Authentifizierungsprozess initiieren kann, etwa so:

/**
 * Authenticate user with Twitter
 *
 * @return bool Authentication successful
 */
public function auth() {

    // state 1 requires a GET variable to exist
    if($this->state == 1 && !isset($_GET["oauth_verifier"])) {
        $this->state = 0;
    }

    // Step 1: Get a request token
    if($this->state == 0) {
        return $this->getRequestToken();
    }
    // Step 2: Get an access token
    elseif($this->state == 1) {
        return $this->getAccessToken();
    }

    // Step 3: Verify the access token
    return $this->verifyAccessToken();
}

大多数 auth() 方法应该是不言自明的。根据状态,它执行该阶段的身份验证的适当方法。如果状态为 1,则 oauth_verifier GET 变量应该存在,因此该方法也会检查该变量。

我们现在应该创建一个公共方法来确定我们是否通过了身份验证。如果状态为 2,则 isAuthed() 方法返回 true:

/**
 * Check the current state of authentication
 *
 * @return bool True if state is 2 (authenticated)
 */
public function isAuthed() {
    return $this->state == 2;
}

我们还可以使用一种方法来删除用户的身份验证。此 endSession() 方法将状态设置为 0 并删除包含访问令牌的 cookie:

/**
 * Remove user's access token cookies
 */
public function endSession() {
    $this->state = 0;
    $_SESSION["authstate"] = 0;
    setcookie("access_token", "", 0);
    setcookie("access_token_secret", "", 0);
}

初始化

现在我们需要向 __construct() 方法添加一些内容,以确定应用程序在初始化时处于哪种身份验证状态。另外,由于我们的代码使用会话变量,因此我们应该确保会话是使用以下代码启动的:

// start a session if one does not exist
if(!session_id()) {
    session_start();
}

下一部分是我们确定状态的地方。状态从0开始;如果设置了包含访问令牌的 cookie,则状态假定为 2;如果失败,状态将设置为 authstate 会话变量(如果存在)。这是代码:

// determine the authentication status
// default to 0
$this->state = 0;
// 2 (authenticated) if the cookies are set
if(isset($_COOKIE["access_token"], $_COOKIE["access_token_secret"])) {
    $this->state = 2;
}
// otherwise use value stored in session
elseif(isset($_SESSION["authstate"])) {
    $this->state = (int)$_SESSION["authstate"];
}

如果状态为 1,则表示我们正在进行身份验证。所以我们现在可以继续这个过程:

// if we are in the process of authentication we continue
if($this->state == 1) {
    $this->auth();
}

如果状态为2,我们应该验证访问令牌。如果身份验证失败,此代码将清除 cookie 并重置状态:

// verify authentication, clearing cookies if it fails
elseif($this->state == 2 && !$this->auth()) {
    $this->endSession();
}

这是进行了这些更改的新构造函数:

/**
 * Initialize a new TwitterApp object
 *
 * @param tmhOAuth $tmhOAuth A tmhOAuth object with consumer key and secret
 */
public function  __construct(tmhOAuth $tmhOAuth) {

    // save the tmhOAuth object
    $this->tmhOAuth = $tmhOAuth;

    // start a session if one does not exist
    if(!session_id()) {
        session_start();
    }

    // determine the authentication status
    // default to 0
    $this->state = 0;
    // 2 (authenticated) if the cookies are set
    if(isset($_COOKIE["access_token"], $_COOKIE["access_token_secret"])) {
        $this->state = 2;
    }
    // otherwise use value stored in session
    elseif(isset($_SESSION["authstate"])) {
    $this->state = (int)$_SESSION["authstate"];
    }

    // if we are in the process of authentication we continue
    if($this->state == 1) {
        $this->auth();
    }
    // verify authentication, clearing cookies if it fails
    elseif($this->state == 2 && !$this->auth()) {
        $this->endSession();
    }
}

发送推文

现在所有授权代码都已完成,我们可以向我们的类添加一些常用功能。以下是通过 Twitter API 发送推文的方法:

/**
 * Send a tweet on the user's behalf
 *
 * @param string $text Text to tweet
 * @return bool Tweet successfully sent
 */
public function sendTweet($text) {

    // limit the string to 140 characters
    $text = substr($text, 0, 140);

    // POST the text to the statuses/update method
    $this->tmhOAuth->request("POST", $this->tmhOAuth->url("1/statuses/update"), array(
        'status' => $text
    ));

    return ($this->tmhOAuth->response["code"] == 200);
}

sendTweet() 方法接受一个字符串,将其限制为 140 个字符,然后在 POST 请求中将其发送到 1/statuses/update。这种模式现在应该非常熟悉了。


完整的 TwitterApp 类

<?php
class TwitterApp {
    
    /**
     * This variable holds the tmhOAuth object used throughout the class
     *
     * @var tmhOAuth An object of the tmhOAuth class
     */
    public $tmhOAuth;

    /**
     * User's Twitter account data
     *
     * @var array Information on the current authenticated user
     */
    public $userdata;

    /**
     * Authentication state
     *
     * Values:
     *  - 0: not authed
     *  - 1: Request token obtained
     *  - 2: Access token obtained (authed)
     *
     * @var int The current state of authentication
     */
    protected $state;

    /**
     * Initialize a new TwitterApp object
     *
     * @param tmhOAuth $tmhOAuth A tmhOAuth object with consumer key and secret
     */
    public function  __construct(tmhOAuth $tmhOAuth) {
        
        // save the tmhOAuth object
        $this->tmhOAuth = $tmhOAuth;

        // start a session if one does not exist
        if(!session_id()) {
            session_start();
        }
        
        // determine the authentication status
        // default to 0
        $this->state = 0;
        // 2 (authenticated) if the cookies are set
        if(isset($_COOKIE["access_token"], $_COOKIE["access_token_secret"])) {
            $this->state = 2;
        }
        // otherwise use value stored in session
        elseif(isset($_SESSION["authstate"])) {
            $this->state = (int)$_SESSION["authstate"];
        }
        
        // if we are in the process of authentication we continue
        if($this->state == 1) {
            $this->auth();
        }
        // verify authentication, clearing cookies if it fails
        elseif($this->state == 2 && !$this->auth()) {
            $this->endSession();
        }
    }

    /**
     * Authenticate user with Twitter
     *
     * @return bool Authentication successful
     */
    public function auth() {
        
        // state 1 requires a GET variable to exist
        if($this->state == 1 && !isset($_GET["oauth_verifier"])) {
            $this->state = 0;
        }

        // Step 1: Get a request token
        if($this->state == 0) {
            return $this->getRequestToken();
        }
        // Step 2: Get an access token

        elseif($this->state == 1) {
            return $this->getAccessToken();
        }

        // Step 3: Verify the access token
        return $this->verifyAccessToken();
    }

    /**
     * Obtain a request token from Twitter
     *
     * @return bool False if request failed
     */
    private function getRequestToken() {
        
        // send request for a request token
        $this->tmhOAuth->request("POST", $this->tmhOAuth->url("oauth/request_token", ""), array(
            // pass a variable to set the callback
            'oauth_callback'    => $this->tmhOAuth->php_self()
        ));

        if($this->tmhOAuth->response["code"] == 200) {
            
            // get and store the request token
            $response = $this->tmhOAuth->extract_params($this->tmhOAuth->response["response"]);
            $_SESSION["authtoken"] = $response["oauth_token"];
            $_SESSION["authsecret"] = $response["oauth_token_secret"];

            // state is now 1
            $_SESSION["authstate"] = 1;

            // redirect the user to Twitter to authorize
            $url = $this->tmhOAuth->url("oauth/authorize", "") . '?oauth_token=' . $response["oauth_token"];
            header("Location: ' . $url);
            exit;
        }
        return false;
    }

    /**
     * Obtain an access token from Twitter
     *
     * @return bool False if request failed
     */
    private function getAccessToken() {
        
        // set the request token and secret we have stored
        $this->tmhOAuth->config["user_token"] = $_SESSION["authtoken"];
        $this->tmhOAuth->config["user_secret"] = $_SESSION["authsecret"];

        // send request for an access token
        $this->tmhOAuth->request("POST", $this->tmhOAuth->url("oauth/access_token", ""), array(
            // pass the oauth_verifier received from Twitter
            'oauth_verifier'    => $_GET["oauth_verifier"]
        ));

        if($this->tmhOAuth->response["code"] == 200) {

            // get the access token and store it in a cookie
            $response = $this->tmhOAuth->extract_params($this->tmhOAuth->response["response"]);
            setcookie("access_token", $response["oauth_token"], time()+3600*24*30);
            setcookie("access_token_secret", $response["oauth_token_secret"], time()+3600*24*30);

            // state is now 2
            $_SESSION["authstate"] = 2;

            // redirect user to clear leftover GET variables
            header("Location: ' . $this->tmhOAuth->php_self());
            exit;
        }
        return false;
    }

    /**
     * Verify the validity of our access token
     *
     * @return bool Access token verified
     */
    private function verifyAccessToken() {
        $this->tmhOAuth->config["user_token"] = $_COOKIE["access_token"];
        $this->tmhOAuth->config["user_secret"] = $_COOKIE["access_token_secret"];

        // send verification request to test access key
        $this->tmhOAuth->request("GET", $this->tmhOAuth->url("1/account/verify_credentials"));

        // store the user data returned from the API
        $this->userdata = json_decode($this->tmhOAuth->response["response"]);

        // HTTP 200 means we were successful
        return ($this->tmhOAuth->response["code"] == 200);
    }

    /**
     * Check the current state of authentication
     *
     * @return bool True if state is 2 (authenticated)
     */
    public function isAuthed() {
        return $this->state == 2;
    }

    /**
     * Remove user's access token cookies
     */
    public function endSession() {
        $this->state = 0;
        $_SESSION["authstate"] = 0;
        setcookie("access_token", "", 0);
        setcookie("access_token_secret", "", 0);
    }
    
    /**
     * Send a tweet on the user's behalf
     *
     * @param string $text Text to tweet
     * @return bool Tweet successfully sent
     */
    public function sendTweet($text) {

        // limit the string to 140 characters
        $text = substr($text, 0, 140);

        // POST the text to the statuses/update method
        $this->tmhOAuth->request("POST", $this->tmhOAuth->url("1/statuses/update"), array(
            'status' => $text
        ));
        
        return ($this->tmhOAuth->response["code"] == 200);
    }
}

我们的应用

现在我们有了一个处理所有 OAuth 任务的类,我们现在可以使用特定于我们的应用程序的功能来扩展它。这包括获取、更改和设置用户头像的能力。

我们将使用 TwitterAvatars 类扩展 TwitterApp 类。在名为 lib/TwitterAvatars.php 的新文件中开始以下代码:

<?php
class TwitterAvatars extends TwitterApp {
    
    /**
     * The path to our temporary files directory
     *
     * @var string Path to store image files
     */
    public $path;
    
    /**
     * These are all the GD image filters available in this class
     *
     * @var array Associative array of image filters
     */
    protected $filters = array(
        'grayscale'     => IMG_FILTER_GRAYSCALE,
        'negative'      => IMG_FILTER_NEGATE,
        'edgedetect'    => IMG_FILTER_EDGEDETECT,
        'embossed'      => IMG_FILTER_EMBOSS,
        'blurry'        => IMG_FILTER_GAUSSIAN_BLUR,
        'sketchy'       => IMG_FILTER_MEAN_REMOVAL
    );
    
    /**
     * Initialize a new TwitterAvatars object
     *
     * @param tmhOAuth $tmhOAuth A tmhOAuth object with consumer key and secret
     * @param string $path Path to store image files (default 'tmp")
     */
    public function  __construct(tmhOAuth $tmhOAuth, $path = 'tmp") {
        
        // call the parent class' constructor
        parent::__construct($tmhOAuth);

        // save the path variable
        $this->path = $path;
    }
}

正如你所看到的,扩展类包括一个 $path 属性,用于指向临时图像文件的位置,一个 $filters 属性,保存图像过滤器数组,以及一个带有要设置的参数的扩展构造函数路径。由于我们要重写原始构造函数,因此必须使用 parent::__construct() 显式调用父级构造函数。

现在我们可以开始添加我们的方法了。


下载

显然,我们需要能够下载图像才能操作它们。这是一个通用的 download() 方法,它接受 URL 并返回该位置的数据。该方法发出基本的 cURL 请求。

/**
 * Download data from specified URL
 *
 * @param string $url URL to download
 * @return string Downloaded data
 */
protected function download($url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $ret = curl_exec($ch);
    curl_close($ch);

    return $ret;
}

查找 URL

现在我们可以下载文件了,我们需要找到所需文件的位置。我们感兴趣的是两种不同的图像,标准尺寸的缩略图和原始的全尺寸图像。因此,我们将创建一个方法来获取每个 URL。

为了获取标准尺寸的缩略图,我们将调用 users/profile_image/:screen_name API 方法,该方法通过 302 重定向响应指定用户的头像图像。这意味着 URL 将在 Location 标头中找到。这是该方法:

/**
 * Get the URL to the standard sized avatar
 *
 * @return string The URL to the image file
 */
protected function getImageURL() {

    // request user's 'bigger' profile image
    $this->tmhOAuth->request("GET", $this->tmhOAuth->url("1/users/profile_image/" . $this->userdata->screen_name), array(
        'screen_name'   => $this->userdata->screen_name,
        'size'          => 'bigger'
    ));

    if($this->tmhOAuth->response["code"] == 302) {

        // the direct URL is in the Location header
        return $this->tmhOAuth->response["headers"]["location"];
    }
    throw new Exception("Error locating image");
}

请注意,我们正在使用 tmhOAuth 发出 GET 请求,传递 screen_namesize 参数,然后返回 Location 标头的内容。

没有 API 方法可以获取完整尺寸的图像,因此对于下一个方法,我们将稍微作弊并编辑 URL。用户数据包含一个 profile_image_url 字段,该字段指向 avatar_normal.jpg 之类的内容,并且可以在 avatar.jpg 中找到不带后缀的原始图像。所以这个方法获取URL,去掉尺寸后缀并返回修改后的URL:

/**
 * Get the URL to the full sized avatar
 *
 * @return string The URL to the image file
 */
protected function getErstellen Sie eine Twitter-OAuth-AnwendungImageURL() {

    // get the regular sized avatar
    $url = $this->userdata->profile_image_url;

    // save the extension for later
    $ext = strrchr($url, '.");

    // strip the "_normal' suffix and add back the extension
    return substr($url, 0, strrpos($url, "_")) . $ext;
}

读取图像

现在我们可以找到并下载图像,我们需要一种方法来读取它们。我们将使用 GD 库来操作图像,因此此方法会将原始图像数据转换为 GD 图像资源。

/**
 * Convert raw image data to a GD resource
 *
 * @param string $data Binary image data to parse
 * @return resource A GD image resource identifier
 */
protected function readImage($data) {

    // read in the original image
    $src = imagecreatefromstring($data);

    if(!$src) {
        throw new Exception("Error reading image");
    }

    // get the dimensions
    $width = imagesx($src);
    $height = imagesy($src);

    // create a blank true color image of the same size
    $img = imagecreatetruecolor($width, $height);

    // copy the original image to this new canvas
    imagecopy($img, $src, 0, 0, 0, 0, $width, $height);

    // discard the source image
    imagedestroy($src);

    return $img;
}

描述上面发生的事情:

  1. 使用 imagecreatefromstring() 函数将图像数据转换为 GD 资源。
  2. 使用 imagesx()imagesy() 记录图像尺寸。
  3. 使用 imagecreatetruecolor() 创建具有相同尺寸的新空白真彩色图像。
  4. 使用 imagecopy() 函数将原始图像复制到新图像中。无论原始颜色模式如何,这都会产生原始图像的真彩色版本。
  5. 使用 imagedestroy() 销毁原始图像资源,并返回新图像的句柄。

保存图像

现在我们可以下载图像并创建 GD 资源,我们需要一种将图像保存到文件系统的方法。以下是使用 imagepng() 将提供的图像保存为具有指定名称的 PNG 文件的方法:

/**
 * Save a GD image resource to a PNG file
 *
 * @param resource $img GD image resource identifier
 * @param string $name Name of the image
 * @return string Path to the saved image
 */
protected function saveImage($img, $name) {
    $path = $this->path . "/' . $name . '.png';
    imagepng($img, $path);
    imagedestroy($img);
    return $path;
}

生成预览

现在我们已经拥有了为我们的应用程序提供支持的所有部分,我们可以开始将它们组合在一起。在我们的应用程序流程中,我们将为用户提供可供选择的预览选项。以下是生成这些预览的方法:

/**
 * Generate previews for each image filter
 *
 * @return array Associative array of image previews
 */
public function generatePreviews() {

    // we need valid user info to know whose avatar to handle
    if(!$this->isAuthed()) {
        throw new Exception("Requires oauth authorization");
    }
    $username = $this->userdata->screen_name;

    // cache the raw data to use
    $data = $this->download($this->getImageURL());

    // copy the original image
    $img = $this->readImage($data);
    $this->saveImage($img, $username . "_orig");

    // array to hold the list of previews
    $images = array();

    // loop through each filter to generate previews
    foreach($this->filters as $filter_name => $filter) {
        $img = $this->readImage($data);
        imagefilter($img, $filter);
        $images[$filter_name] = $this->saveImage($img, $username . "_' . $filter_name);
    }

    return $images;
}

我们要做的第一件事是检查用户是否已通过身份验证,然后获取用户名以便稍后在文件名中使用。

// we need valid user info to know whose avatar to handle
if(!$this->isAuthed()) {
    throw new Exception("Requires oauth authorization");
}
$username = $this->userdata->screen_name;

然后我们使用我们创建的 getImageURL()download() 方法下载用户的图像。该数据将在每次预览中重复使用,因此我们将其保存在 $data 变量中。

// cache the raw data to use
$data = $this->download($this->getImageURL());

接下来,我们使用 _orig 后缀保存未修改的副本。这是为了稍后进行视觉比较。

// copy the original image
$img = $this->readImage($data);
$this->saveImage($img, $username . "_orig");

该方法的最后一部分是我们循环遍历 $filters 属性中列出的图像过滤器,为每个过滤器生成一个图像。在每次迭代中,我们创建一个图像并应用 imagefilter() 函数,该函数接受我们在 $filters 数组中列出的常量之一。然后,对于我们保存的每个图像,我们将其路径添加到该方法最后返回的关联数组(使用过滤器名称作为键)。

// array to hold the list of previews
$images = array();

// loop through each filter to generate previews
foreach($this->filters as $filter_name => $filter) {
    $img = $this->readImage($data);
    imagefilter($img, $filter);
    $images[$filter_name] = $this->saveImage($img, $username . "_' . $filter_name);
}

return $images;

我们的应用程序流程的下一部分要求用户确认他们的选择,因此我们需要一种方法来查找特定的预览。下面是根据作为参数传递的选项获取图像路径的简单方法,默认为原始图像:

/**
 * Get the path to a previously generated preview
 *
 * @param string $filter The image filter to get the preview for
 * @return string The path to the preview file or null if not found
 */
public function getPreview($filter = 'orig") {
    if(!$this->isAuthed()) {
        throw new Exception("Requires oauth authorization");
    }
    $path = $this->path . "/' . $this->userdata->screen_name . "_' . $filter . '.png';
    if(file_exists($path)) {
        return $path;
    }
    return null;
}

更改头像

我们的应用程序流程的最后阶段是实际更改用户的头像。首先,我们需要一种方法来获取全尺寸图像并对其应用特定的滤镜。这是:

/**
 * Process the user's full avatar using one of the filters
 *
 * @param string $filter The filter to apply to the image
 * @return string Path to the output file
 */
protected function processImage($filter = "grayscale") {

    // make sure the filter exists
    $filter = strtolower($filter);
    if(!array_key_exists($filter, $this->filters)) {
        throw new Exception("Unsupported image filter");
    }

    $username = $this->userdata->screen_name;

    // get the full sized avatar
    $data = $this->download($this->getErstellen Sie eine Twitter-OAuth-AnwendungImageURL());
    $img = $this->readImage($data);

    // apply the filter to the image
    imagefilter($img, $this->filters[$filter]);

    // save the image and return the path
    return $this->saveImage($img, $username . "_' . $filter . "_full");
}

这应该很容易理解,因为它与 generatePreviews() 方法非常相似。它接受一个参数来指定图像过滤器并检查它是否存在。然后它下载原始图像并对其应用过滤器,将生成图像的路径作为返回值传回。

现在我们需要将生成的图像实际发送到 Twitter 的方法,以更新用户的头像。该方法调用 processImage() 方法创建图像并通过 1/account/update_profile_image API 方法上传到 Twitter:

/**
 * Update user's avatar with a filtered version
 *
 * @param string $filter The filter to use
 * @return bool Operation successful
 */
public function commitAvatar($filter) {
    if(!$this->isAuthed()) {
        throw new Exception("Requires oauth authorization");
    }

    // generate the image and get the path
    $path = $this->processImage($filter);
    if(file_exists($path)) {

        // send a multipart POST request with the image file data
        $this->tmhOAuth->request("POST", $this->tmhOAuth->url("1/account/update_profile_image"), array(
            // format: @local/path.png;type=mime/type;filename=file_name.png
            'image' => '@' . $path . ';type=image/png;filename=' . basename($path)
        ), true, true);

        return ($this->tmhOAuth->response["code"] == 200);
    }

    return false;
}

这里棘手的部分是实际的 tmhOAuth POST 请求,它是一个包含原始图像数据的多部分请求。为此,我们必须将 tmhOAuth::request() 方法的最后一个参数设置为 true,并以特殊格式传递 image 变量:

@[图像路径];type=[mime_type];filename=[file_name]

例如,如果我们要上传 tmp/username_grayscale_full.png,则值为 @tmp/username_grayscale_full.png;type=image/png;filename=username_grayscale_full.png

这又是那部分代码:

// send a multipart POST request with the image file data
$this->tmhOAuth->request("POST", $this->tmhOAuth->url("1/account/update_profile_image"), array(
    // format: @local/path.png;type=mime/type;filename=file_name.png
    'image' => '@' . $path . ';type=image/png;filename=' . basename($path)
), true, true);

清理

所有这些文件操作的副作用是留下大量临时文件。下面是清理临时目录的方法:

/**
 * Delete leftover image files
 */
public function cleanupFiles() {

    // file to track when we last checked
    $flag = $this->path . "/.last_check';

    $time = time();

    // have we checked within the last hour?
    if(!file_exists($flag) || $time - filemtime($flag) > 3600) {

        // get an array of PNG files in the directory
        $files = glob($this->path . "/*.png");

        // loop through files, deleting old files (12+ hours)
        foreach($files as $file) {
            if($time - filemtime($file) > 60*60*12) {
                unlink($file);
            }
        }

        // update the timestamp of our flag file
        touch($flag);
    }
}

这只是循环遍历 PNG 文件,删除那些超过 12 小时的文件。它还检查自我们使用 .last_check 文件上的时间戳进行检查以来已经过去了多长时间,从而允许我们将检查限制为每小时一次。这样我们就可以在每个请求上调用这个方法,而不会浪费资源。

注意:我们在 PHP 中使用 glob() 函数,这是获取与模式匹配的文件数组的简单方法。


完整的 TwitterAvatars 类

&?php
class TwitterAvatars extends TwitterApp {
    
    /**
     * The path to our temporary files directory
     *
     * @var string Path to store image files
     */
    public $path;
    
    /**
     * These are all the GD image filters available in this class
     *
     * @var array Associative array of image filters
     */
    protected $filters = array(
        'grayscale'     => IMG_FILTER_GRAYSCALE,
        'negative'      => IMG_FILTER_NEGATE,
        'edgedetect'    => IMG_FILTER_EDGEDETECT,
        'embossed'      => IMG_FILTER_EMBOSS,
        'blurry'        => IMG_FILTER_GAUSSIAN_BLUR,
        'sketchy'       => IMG_FILTER_MEAN_REMOVAL
    );
    
    /**
     * Initialize a new TwitterAvatars object
     *
     * @param tmhOAuth $tmhOAuth A tmhOAuth object with consumer key and secret
     * @param string $path Path to store image files (default 'tmp")
     */
    public function  __construct(tmhOAuth $tmhOAuth, $path = 'tmp") {
        
        // call the parent class' constructor
        parent::__construct($tmhOAuth);

        // save the path variable
        $this->path = $path;
    }

    /**
     * Download data from specified URL
     *
     * @param string $url URL to download
     * @return string Downloaded data
     */
    protected function download($url) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        $ret = curl_exec($ch);
        curl_close($ch);

        return $ret;
    }

    /**
     * Get the URL to the standard sized avatar
     *
     * @return string The URL to the image file
     */
    protected function getImageURL() {

        // request user's 'bigger' profile image
        $this->tmhOAuth->request("GET", $this->tmhOAuth->url("1/users/profile_image/' . $this->userdata->screen_name), array(
            'screen_name'   => $this->userdata->screen_name,
            'size'          => 'bigger'
        ));

        if($this->tmhOAuth->response["code"] == 302) {
            
            // the direct URL is in the Location header
            return $this->tmhOAuth->response["headers"]["location"];
        }
        throw new Exception("Error locating image");
    }

    /**
     * Get the URL to the full sized avatar
     *
     * @return string The URL to the image file

     */
    protected function getErstellen Sie eine Twitter-OAuth-AnwendungImageURL() {

        // get the regular sized avatar
        $url = $this->userdata->profile_image_url;

        // save the extension for later
        $ext = strrchr($url, '.");

        // strip the "_normal' suffix and add back the extension
        return substr($url, 0, strrpos($url, "_")) . $ext;
    }

    /**
     * Convert raw image data to a GD resource
     *
     * @param string $data Binary image data to parse
     * @return resource A GD image resource identifier
     */
    protected function readImage($data) {

        // read in the original image
        $src = imagecreatefromstring($data);

        if(!$src) {
            throw new Exception("Error reading image");
        }

        // get the dimensions
        $width = imagesx($src);
        $height = imagesy($src);

        // create a blank true color image of the same size
        $img = imagecreatetruecolor($width, $height);

        // copy the original image to this new canvas
        imagecopy($img, $src, 0, 0, 0, 0, $width, $height);

        // discard the source image
        imagedestroy($src);

        return $img;
    }

    /**
     * Save a GD image resource to a PNG file
     *
     * @param resource $img GD image resource identifier
     * @param string $name Name of the image
     * @return string Path to the saved image
     */
    protected function saveImage($img, $name) {
        $path = $this->path . "/' . $name . '.png';
        imagepng($img, $path);
        imagedestroy($img);
        return $path;
    }

    /**
     * Generate previews for each image filter
     *
     * @return array Associative array of image previews
     */
    public function generatePreviews() {
        
        // we need valid user info to know whose avatar to handle
        if(!$this->isAuthed()) {
            throw new Exception("Requires oauth authorization");
        }
        $username = $this->userdata->screen_name;

        // cache the raw data to use
        $data = $this->download($this->getImageURL());

        // copy the original image
        $img = $this->readImage($data);
        $this->saveImage($img, $username . "_orig");
        
        // array to hold the list of previews
        $images = array();

        // loop through each filter to generate previews
        foreach($this->filters as $filter_name => $filter) {
            $img = $this->readImage($data);
            imagefilter($img, $filter);
            $images[$filter_name] = $this->saveImage($img, $username . "_' . $filter_name);
        }

        return $images;
    }

    /**
     * Get the path to a previously generated preview
     *
     * @param string $filter The image filter to get the preview for
     * @return string The path to the preview file or null if not found
     */
    public function getPreview($filter = 'orig") {
        if(!$this->isAuthed()) {
            throw new Exception("Requires oauth authorization");
        }
        $path = $this->path . "/' . $this->userdata->screen_name . "_' . $filter . '.png';
        if(file_exists($path)) {
            return $path;
        }
        return null;
    }

    /**
     * Process the user's full avatar using one of the filters
     *
     * @param string $filter The filter to apply to the image
     * @return string Path to the output file
     */
    protected function processImage($filter = 'grayscale") {
        
        // make sure the filter exists
        $filter = strtolower($filter);
        if(!array_key_exists($filter, $this->filters)) {
            throw new Exception("Unsupported image filter");
        }

        $username = $this->userdata->screen_name;

        // get the full sized avatar
        $data = $this->download($this->getErstellen Sie eine Twitter-OAuth-AnwendungImageURL());
        $img = $this->readImage($data);

        // apply the filter to the image
        imagefilter($img, $this->filters[$filter]);
        
        // save the image and return the path
        return $this->saveImage($img, $username . "_' . $filter . "_full");
    }

    /**
     * Update user's avatar with a filtered version
     *
     * @param string $filter The filter to use
     * @return bool Operation successful
     */
    public function commitAvatar($filter) {
        if(!$this->isAuthed()) {
            throw new Exception("Requires oauth authorization");
        }

        // generate the image and get the path
        $path = $this->processImage($filter);
        if(file_exists($path)) {

            // send a multipart POST request with the image file data
            $this->tmhOAuth->request("POST", $this->tmhOAuth->url("1/account/update_profile_image"), array(
                // format: @local/path.png;type=mime/type;filename=file_name.png
                'image' => '@' . $path . ';type=image/png;filename=' . basename($path)
            ), true, true);

            return ($this->tmhOAuth->response["code"] == 200);
        }

        return false;
    }

    /**
     * Delete leftover image files
     */
    public function cleanupFiles() {
        
        // file to track when we last checked
        $flag = $this->path . "/.last_check';

        $time = time();

        // have we checked within the last hour?
        if(!file_exists($flag) || $time - filemtime($flag) > 3600) {
            
            // get an array of PNG files in the directory
            $files = glob($this->path . "/*.png");

            // loop through files, deleting old files (12+ hours)
            foreach($files as $file) {
                if($time - filemtime($file) > 60*60*12) {
                    unlink($file);
                }
            }

            // update the timestamp of our flag file
            touch($flag);
        }
    }
}

前端

我们将应用程序的所有组件放在一起,所以现在我们需要的只是用户界面。这里的所有代码都将进入根目录中的index.php文件。我们将首先包含库并设置配置:

<?php

// include our libraries
include 'lib/tmhOAuth.php';
include 'lib/TwitterApp.php';
include 'lib/TwitterAvatars.php';

// set the consumer key and secret
define("CONSUMER_KEY",      'qSkJum23MqlG6greF8Z76A");
define("CONSUMER_SECRET",   'Bs738r5UY2R7e5mwp1ilU0voe8OtXAtifgtZe9EhXw");
?>

注意:请务必将 CONSUMER_KEYCONSUMER_SECRET 替换为您自己的。

我们将把代码放在 try-catch 块中,这样我们就可以优雅地处理任何错误,将它们的消息分配给 $error 变量。

try {
    
} catch(Exception $e) {

    // catch any errors that may occur
    $error = $e;
}

在 try 块中,我们可以开始编写代码,首先使用配置的 tmhOAuth 对象初始化名为 $ta 的 TwitterAvatars 对象:

    // our tmhOAuth settings
    $config = array(
        'consumer_key'      => CONSUMER_KEY,
        'consumer_secret'   => CONSUMER_SECRET
    );

    // create a new TwitterAvatars object
    $ta = new TwitterAvatars(new tmhOAuth($config));

此时我们可以清除所有旧的临时文件:

    // check for stale files
    $ta->cleanupFiles();

接下来,我们检查用户是否已通过身份验证,或者如果用户未通过身份验证,则检查用户是否已请求身份验证,在这种情况下,我们通过调用 auth() 方法来启动该过程:

    // check our authentication status
    if($ta->isAuthed()) {
        
    }
    // did the user request authorization?
    elseif(isset($_POST["auth"])) {

        // start authentication process
        $ta->auth();
    }

如果用户已通过身份验证,我们需要检查是否已选择某个选项,否则我们将生成预览:

    // check our authentication status
    if($ta->isAuthed()) {

        // has the user selected an option?
        if(isset($_POST["filter"])) {
            
        }
        // generate previews if the user has not chosen
        else {

            // $previews will be a list of images
            $previews = $ta->generatePreviews();
        }
    }

如果选择了某个选项,我们需要获取要显示的旧图像和新图像的路径:

        // has the user selected an option?
        if(isset($_POST["filter"])) {

            // get the image paths for display
            $original = $ta->getPreview();
            $newimage = $ta->getPreview($_POST["filter"]);
        }

最后,我们检查用户是否确认了他们的选择并应用更改。如果需要,我们还会发送一条推文,并将 $success 变量设置为 true:

        // has the user selected an option?
        if(isset($_POST["filter"])) {

            // is the user sure?
            if(isset($_POST["confirm"])) {

                // change the user's avatar
                $ta->commitAvatar($_POST["filter"]);

                // tweet if the user chose to
                if(isset($_POST["tweet"])) {
                    $ta->sendTweet("I just updated my avatar using Avatar Effects...");
                }

                $success = true;
            }

            // get the image paths for display
            $original = $ta->getPreview();
            $newimage = $ta->getPreview($_POST["filter"]);
        }

这是我们迄今为止所拥有的:

isAuthed()) {

        // has the user selected an option?
        if(isset($_POST["filter"])) {

            // is the user sure?
            if(isset($_POST["confirm"])) {

                // change the user's avatar
                $ta->commitAvatar($_POST["filter"]);

                // tweet if the user chose to
                if(isset($_POST["tweet"])) {
                    $ta->sendTweet("I just updated my avatar using Avatar Effects...");
                }

                $success = true;
            }

            // get the image paths for display
            $original = $ta->getPreview();
            $newimage = $ta->getPreview($_POST["filter"]);
        }
        // generate previews if the user has not chosen
        else {

            // $previews will be a list of images
            $previews = $ta->generatePreviews();
        }
    }
    // did the user request authorization?
    elseif(isset($_POST["auth"])) {

        // start authentication process
        $ta->auth();
    }
} catch(Exception $e) {

    // catch any errors that may occur
    $error = $e;
}
?>

HTML

在 PHP 代码之后,我们将输出适当的 HTML,从这个模板开始,它设置标题和主标题:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Twitter Avatar Effects</title>
    <link rel="stylesheet" href="css/style.css">
  </head>
  <body>
      <h1>Twitter Avatar Effects</h1>
  </body>
</html>

这里是我们显示带有每个预览的图像输入的表单的地方:

  <?php if(isset($previews)): ?>
      <h2>Choose your weapon...</h2>
      <form action="index.php" method="post">
      <?php foreach($previews as $filter => $path): ?>
          <input type="image" src="<?php echo $path; ?>"
                 alt="<?php echo ucfirst($filter); ?>"
                  width="73" height="73"
                 name="filter" value="<?php echo $filter; ?>">
      <?php endforeach; ?>
      </form>
      <p>Select one of the images above to change your Twitter avatar.</p>

这是成功页面:

  <?php elseif(isset($success)): ?>
      <h2>Success! Your Twitter avatar is now:</h2>
      <img  src="<?php echo $newimage; ? alt="Erstellen Sie eine Twitter-OAuth-Anwendung" >" alt="Your Avatar" width="73"    style="max-width:90%">
      <p><a href="http://twitter.com/<?php echo $ta->userdata->screen_name; ?>">Go see it</a></p>

这是确认页面,我们在其中显示比较并提供取消的机会:

  <?php elseif(isset($newimage)): ?>
      <h2>Are you sure?</h2>
      <img  src="<?php echo $original; ? alt="Erstellen Sie eine Twitter-OAuth-Anwendung" >" alt="Erstellen Sie eine Twitter-OAuth-Anwendung" width="73"    style="max-width:90%">
      <span class="arrow">&rArr;</span>
      <img  src="<?php echo $newimage; ? alt="Erstellen Sie eine Twitter-OAuth-Anwendung" >" alt="<?php echo ucfirst($_POST["filter"]); ?>">
      <form action="index.php" method="post">
          <input type="hidden" name="filter" value="<?php echo $_POST["filter"]; ?>">
          <input type="submit" name="confirm" value="Confirm">
          <a href="index.php">Cancel</a>
          <p><label>Tweet about your new avatar?
                  <input type="checkbox" name="tweet" value="true"></label></p>
      </form>

请注意,确认表单在隐藏字段中包含所选的过滤器。

如果出现错误,我们会显示:

  <?php elseif(isset($error)): ?>
      <p>Error. <a href="index.php">Try again?</a></p>

默认显示的是“连接到 Twitter”按钮作为图像输入(从本页底部下载一张图像到 img 目录):

  <?php else: ?>
      <form action="index.php" method="post">
          <input type="image" src="img/sign-in-with-twitter-l.png"
                 alt="Connect to Twitter" name="auth" value="1">
      </form>
      <p>Connect to Twitter to use this app.</p>
  <?php endif; ?>

这是完整的 HTML 部分:



  
    
    Twitter Avatar Effects
    
  
  
      

Twitter Avatar Effects

<?php if(isset($previews)): ?> <h2>Choose your weapon...</h2> <form action="index.php" method="post"> <?php foreach($previews as $filter => $path): ?> <input type="image" src="<?php echo $path; ?>" alt="<?php echo ucfirst($filter); ?>" width="73" height="73" name="filter" value="<?php echo $filter; ?>"> <?php endforeach; ?> </form> <p>Select one of the images above to change your Twitter avatar.</p> <?php elseif(isset($success)): ?> <h2>Success! Your Twitter avatar is now:</h2> <img src="<?php echo $newimage; ? alt="Erstellen Sie eine Twitter-OAuth-Anwendung" >" alt="Your Avatar" width="73" style="max-width:90%"> <p><a href="http://twitter.com/<?php echo $ta->userdata->screen_name; ?>">Go see it</a></p> <?php elseif(isset($newimage)): ?> <h2>Are you sure?</h2> <img src="<?php echo $original; ? alt="Erstellen Sie eine Twitter-OAuth-Anwendung" >" alt="Erstellen Sie eine Twitter-OAuth-Anwendung" width="73" style="max-width:90%"> <span class="arrow">&rArr;</span> <img src="<?php echo $newimage; ? alt="Erstellen Sie eine Twitter-OAuth-Anwendung" >" alt="<?php echo ucfirst($_POST["filter"]); ?>"> <form action="index.php" method="post"> <input type="hidden" name="filter" value="<?php echo $_POST["filter"]; ?>"> <input type="submit" name="confirm" value="Confirm"> <a href="index.php">Cancel</a> <p><label>Tweet about your new avatar? <input type="checkbox" name="tweet" value="true"></label></p> </form> <?php elseif(isset($error)): ?> <p>Error. <a href="index.php">Try again?</a></p> <?php else: ?> <form action="index.php" method="post"> <input type="image" src="img/sign-in-with-twitter-l.png" alt="Connect to Twitter" name="auth" value="1"> </form> <p>Connect to Twitter to use this app.</p> <?php endif; ?>

CSS

这里是一些使界面看起来更漂亮的基本 CSS,保存在 css/style.css 中:

html {
    background-color: #eee;
    text-align: center;
    font-family: "Lucida Grande",Verdana, sans-serif;
    font-size: 16px;
    color: #224;
}
body {
    width: 700px;
    margin: 30px auto;
    background-color: #acf;
    padding: 10px;
    border-radius: 10px;
    -moz-border-radius: 10px;
    -webkit-border-radius: 10px;
}
p {
    font-size: 1em;
}
h1 {
    font-size: 2em;
}
h2 {
    font-size: 1.6em;
}
.arrow {
    font-size: 4em;
    font-weight: bold;
}

结果

这是一个视频,详细介绍了我们完成的应用程序的外观:


结论

如果您完全按照本教程进行操作,您应该对 OAuth 以及创建简单 Twitter Web 应用程序所需的内容有很好的了解。一旦您了解了基本概念,使用 Twitter API 就会很容易 - 特别是如果您使用像 tmhOAuth 这样的库来处理次要细节。

我们在本教程中创建的简单示例可以轻松修改或扩展以执行任何操作。因此,如果您对一款很酷的新 Twitter 应用程序有好主意,请随意使用它作为基础。

感谢您的阅读。如果您对本教程有任何疑问或意见,请留言!

Das obige ist der detaillierte Inhalt vonErstellen Sie eine Twitter-OAuth-Anwendung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn