PHP Dropbox Uploader类名称致命错误

时间:2014-12-24 18:33:58

标签: php dropbox-php

我已尝试将PHP Dropbox Uploader应用到我的网站(位于此处https://github.com/jakajancar/DropboxUploader),而我似乎无法正常使用它。我一直得到的错误是:

Fatal error: Class name must be a valid object or a string in [document name] on line 51. 

首先是我的上传页面上的php代码:

<?php
    if ($_POST) {
        require 'DropboxUploader.php';

        try {
            if ($_FILES['file']['error'] !== UPLOAD_ERR_OK)
                throw new Exception('File was not successfully uploaded from your computer.');

            if ($_FILES['file']['name'] === "")
                throw new Exception('File name not supplied by the browser.');

            // Upload
            $uploader = new DropboxUploader($_POST['user@email.com'], $_POST['mypassword']);
            $uploader->upload($_FILES['file']['tmp_name'], $_POST['NEWFORMS, INC'], $_FILES['file']['name']);

            echo '<span style="color: green">File successfully uploaded to your Dropbox!</span>';
        } catch (Exception $e) {
            // Handle Upload Exceptions
            $label = ($e->getCode() & $uploader::FLAG_DROPBOX_GENERIC) ? 'DropboxUploader' : 'Exception';
            $error = sprintf("[%s] #%d %s", $label, $e->getCode(), $e->getMessage());

            echo '<span style="color: red">Error: ' . htmlspecialchars($error) . '</span>';
        }
    }
    ?>

上传页面中的HTML:

<div class="cell-9">
   <h1 class="block-head"> Upload Files to our Dropbox </h1>
   <form method="POST" enctype="multipart/form-data">
     <dl>
       <dt><label for="email">Dropbox e-mail</label></dt>
           <dd><input type="text" id="email" name="email"></dd>
           <dt><label for="password">Dropbox password</label></dt>
           <dd><input type="password" id="password" name="password"></dd>
           <dt><label for="destination">Destination directory (optional)</label></dt>
           <dd><input type="text" id="destination" name="destination"> e.g. "dir/subdirectory", will              be created if it doesn't exist</dd>
           <dt><label for="file"></label>File</dt>
           <dd><input type="file" id="file" name="file"></dd>
           <dd><input type="submit" value="Upload the file to my Dropbox!"></dd>
     </dl>
  </form>
</div>

这是我的DropboxUploader PHP文件中的PHP:

    <?php

final class DropboxUploader {
    /**
     * Certificate Authority Certificate source types
     */
    const CACERT_SOURCE_SYSTEM = 0;
    const CACERT_SOURCE_FILE   = 1;
    const CACERT_SOURCE_DIR    = 2;
    /**
     * Dropbox configuration
     */
    const DROPBOX_UPLOAD_LIMIT_IN_BYTES = 314572800;
    const HTTPS_DROPBOX_COM_HOME        = 'https://www.dropbox.com/home';
    const HTTPS_DROPBOX_COM_LOGIN       = 'https://www.dropbox.com/login';
    const HTTPS_DROPBOX_COM_LOGINACTION = 'https://www.dropbox.com/ajax_login';
    const HTTPS_DROPBOX_COM_UPLOAD      = 'https://dl-web.dropbox.com/upload';
    const HTTPS_DROPBOX_COM_LOGOUT      = 'https://www.dropbox.com/logout';
    /**
     * DropboxUploader Error Flags and Codes
     */
    const FLAG_DROPBOX_GENERIC        = 0x10000000;
    const FLAG_LOCAL_FILE_IO          = 0x10010000;
    const CODE_FILE_READ_ERROR        = 0x10010101;
    const CODE_TEMP_FILE_CREATE_ERROR = 0x10010102;
    const CODE_TEMP_FILE_WRITE_ERROR  = 0x10010103;
    const FLAG_PARAMETER_INVALID      = 0x10020000;
    const CODE_PARAMETER_TYPE_ERROR   = 0x10020101;
    const CODE_FILESIZE_TOO_LARGE     = 0x10020201;
    const FLAG_REMOTE                 = 0x10040000;
    const CODE_CURL_ERROR             = 0x10040101;
    const CODE_LOGIN_ERROR            = 0x10040201;
    const CODE_UPLOAD_ERROR           = 0x10040401;
    const CODE_SCRAPING_FORM          = 0x10040801;
    const CODE_SCRAPING_LOGIN         = 0x10040802;
    const CODE_CURL_EXTENSION_MISSING = 0x10080101;
    private $email;
    private $password;
    private $caCertSourceType = self::CACERT_SOURCE_SYSTEM;
    private $caCertSource;
    private $loggedIn = FALSE;
    private $cookies = array();

/**
 * Constructor
 *
 * @param string $email
 * @param string $password
 * @throws Exception
 */
public function __construct($email, $password) {
    // Check requirements
    if (!extension_loaded('curl'))
        throw new Exception('DropboxUploader requires the cURL extension.', self::CODE_CURL_EXTENSION_MISSING);

    if (empty($email) || empty($password)) {
        throw new Exception((empty($email) ? 'Email' : 'Password') . ' must not be empty.', self::CODE_PARAMETER_TYPE_ERROR);
    }

    $this->email    = $email;
    $this->password = $password;
}

public function setCaCertificateDir($dir) {
    $this->caCertSourceType = self::CACERT_SOURCE_DIR;
    $this->caCertSource     = $dir;
}

public function setCaCertificateFile($file) {
    $this->caCertSourceType = self::CACERT_SOURCE_FILE;
    $this->caCertSource     = $file;
}

public function upload($source, $remoteDir = '/', $remoteName = NULL) {
    if (!is_file($source) or !is_readable($source))
        throw new Exception("File '$source' does not exist or is not readable.", self::CODE_FILE_READ_ERROR);

    $filesize = filesize($source);
    if ($filesize < 0 or $filesize > self::DROPBOX_UPLOAD_LIMIT_IN_BYTES) {
        throw new Exception("File '$source' too large ($filesize bytes).", self::CODE_FILESIZE_TOO_LARGE);
    }

    if (!is_string($remoteDir))
        throw new Exception("Remote directory must be a string, is " . gettype($remoteDir) . " instead.", self::CODE_PARAMETER_TYPE_ERROR);

    if (is_null($remoteName)) {
        # intentionally left blank
    } else if (!is_string($remoteName)) {
        throw new Exception("Remote filename must be a string, is " . gettype($remoteDir) . " instead.", self::CODE_PARAMETER_TYPE_ERROR);
    }

    if (!$this->loggedIn)
        $this->login();

    $data       = $this->request(self::HTTPS_DROPBOX_COM_HOME);
    $file       = $this->curlFileCreate($source, $remoteName);
    $token      = $this->extractFormValue($data, 't');
    $subjectUid = $this->extractFormValue($data, '_subject_uid');

    $postData = array(
        'plain'        => 'yes',
        'file'         => $file,
        'dest'         => $remoteDir,
        't'            => $token,
        '_subject_uid' => $subjectUid,
        'mtime_utc'    => filemtime($source),
    );

    $data     = $this->request(self::HTTPS_DROPBOX_COM_UPLOAD, $postData);
    if (strpos($data, 'HTTP/1.1 302 FOUND') === FALSE)
        throw new Exception('Upload failed!', self::CODE_UPLOAD_ERROR);
}

private function curlFileCreate($source, $remoteName) {
    if (function_exists('curl_file_create')) {
        return curl_file_create($source, NULL, $remoteName);
    }

    if ($remoteName !== NULL) {
        $source .= ';filename=' . $remoteName;
    }

    return '@' . $source;
}

public function uploadString($string, $remoteName, $remoteDir = '/') {
    $exception = NULL;

    $file = tempnam(sys_get_temp_dir(), 'DBUploadString');
    if (!is_file($file))
        throw new Exception("Can not create temporary file.", self::CODE_TEMP_FILE_CREATE_ERROR);

    $bytes = file_put_contents($file, $string);
    if ($bytes === FALSE) {
        unlink($file);
        throw new Exception("Can not write to temporary file '$file'.", self::CODE_TEMP_FILE_WRITE_ERROR);
    }

    try {
        $this->upload($file, $remoteDir, $remoteName);
    } catch (Exception $exception) {
        # intentionally left blank
    }

    unlink($file);

    if ($exception)
        throw $exception;
}

private function login() {
    $data  = $this->request(self::HTTPS_DROPBOX_COM_LOGIN);
    $token = $this->extractTokenFromLoginForm($data);

    $postData = array(
        'login_email'    => (string) $this->email,
        'login_password' => (string) $this->password,
        't'              => $token
    );
    $data     = $this->request(self::HTTPS_DROPBOX_COM_LOGINACTION, http_build_query($postData));

    if (stripos($data, '{"status": "OK", "csrf_token": "') === FALSE)
        throw new Exception('Login unsuccessful.', self::CODE_LOGIN_ERROR);

    $this->loggedIn = TRUE;
}

private function logout() {
    $data = $this->request(self::HTTPS_DROPBOX_COM_LOGOUT);

    if (!empty($data) && strpos($data, 'HTTP/1.1 302 FOUND') !== FALSE) {
        $this->loggedIn = FALSE;
    }
}

private function request($url, $postData = NULL) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, (string) $url);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
    switch ($this->caCertSourceType) {
        case self::CACERT_SOURCE_FILE:
            curl_setopt($ch, CURLOPT_CAINFO, (string) $this->caCertSource);
            break;
        case self::CACERT_SOURCE_DIR:
            curl_setopt($ch, CURLOPT_CAPATH, (string) $this->caCertSource);
            break;
    }
    curl_setopt($ch, CURLOPT_HEADER, TRUE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    if (NULL !== $postData) {
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
    }

    // Send cookies
    $rawCookies = array();
    foreach ($this->cookies as $k => $v)
        $rawCookies[] = "$k=$v";
    $rawCookies = implode(';', $rawCookies);
    curl_setopt($ch, CURLOPT_COOKIE, $rawCookies);

    $data  = curl_exec($ch);
    $error = sprintf('Curl error: (#%d) %s', curl_errno($ch), curl_error($ch));
    curl_close($ch);

    if ($data === FALSE) {
        throw new Exception($error, self::CODE_CURL_ERROR);
    }

    // Store received cookies
    preg_match_all('/Set-Cookie: ([^=]+)=(.*?);/i', $data, $matches, PREG_SET_ORDER);
    foreach ($matches as $match)
        $this->cookies[$match[1]] = $match[2];

    return $data;
}

private function extractFormValue($html, $name) {
    $action  = self::HTTPS_DROPBOX_COM_UPLOAD;
    $pattern = sprintf(
        '/<form [^>]*%s[^>]*>.*?(?:<input [^>]*name="%s" [^>]*value="(.*?)"[^>]*>).*?<\/form>/is'
        , preg_quote($action, '/')
        , preg_quote($name, '/')
    );
    if (!preg_match($pattern, $html, $matches))
        throw new Exception(sprintf("Cannot extract '%s'! (form action is '%s')", $name, $action), self::CODE_SCRAPING_FORM);
    return $matches[1];
}

private function extractTokenFromLoginForm($html) {
    // , "TOKEN": "gCvxU6JVukrW0CUndRPruFvY",
    if (!preg_match('#, "TOKEN": "([A-Za-z0-9_-]+)", #', $html, $matches))
        throw new Exception('Cannot extract login CSRF token.', self::CODE_SCRAPING_LOGIN);
    return $matches[1];
}

public function __destruct() {
    if ($this->loggedIn) {
        $this->logout();
    }
}

}

我删除了我的电子邮件和密码,原因很明显,但在我的实际文件中,我确实输入了它们。关于导致我的错误的原因以及如何解决它的任何想法?

1 个答案:

答案 0 :(得分:-1)

($ e-&gt; getCode()&amp; $ uploader :: FLAG_DROPBOX_GENERIC)到($ e-&gt; getCode()&amp;&amp; DropboxUploader :: FLAG_DROPBOX_GENERIC)

这是解决方法。谢谢@u_mulder的答案。欢呼!