Pastebin.ca PHP API

In my boredom, I find I do a lot of things. Some of those things range from very silly to intense coding sessions. So, out of boredom tonight, I have built a script to use the Pastebin.ca API to make pastes remotely.

Below you will find the code and an example. Let me know if you have any issues 🙂

UPDATES:

  • November 20, 2017: Small changes to code, a little cleanup.
<?php

/**
 * Object oriented wrapper for the cURL library.
 *
 * @author  Eric Sizemore <[email protected]>
 * @author  David Hopkins <semlabs.co.uk>
 * @package OO cURL Class
 *
 * Based on the cURL class by David Hopkins (semlabs.co.uk).
 */
class cURL
{
    private static $instance;

    public $sessions = [];
    public $retries  = 0;

    /**
     * Constructor.
     */
    private function __construct() {}

    /**
     * Creates an instance of the class.
     * @return	cURL
     */
    public static function getInstance(): cURL
    {
        if (!self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Adds a cURL session.
     *
     * @param	$url		string	URL
     * @param	$options	array	Optional array of cURL options/values
     */
    public function addSession(string $url, array $options = [])
    {
        $this->sessions[] = curl_init($url);

        if (!empty($options)) {
            $this->setOptions($options, (count($this->sessions) - 1));
        }
    }

    /**
     * Sets an option to a cURL session.
     *
     * @param	$option		constant	cURL option
     * @param	$value		mixed		value of option
     * @param	$key		integer		session key to set option for
     */
    public function setOption($option, $value, int $key = 0)
    {
        curl_setopt($this->sessions[$key], $option, $value);
    }

    /**
     * Sets an array of options to a cURL session.
     *
     * @param	$options	array		array of cURL options/values
     * @param	$key		integer		session key to set option for
     */
    public function setOptions(array $options, int $key = 0)
    {
        curl_setopt_array($this->sessions[$key], $options);
    }

    /**
     * Executes as cURL session.
     *
     * @param	$key	integer		Optional argument if you want to execute only one session
     */
    public function exec($key = false)
    {
        $session_count = count($this->sessions);

        if ($session_count == 1) {
            $result = $this->execSingle();
        } elseif ($session_count > 1) {
            if ($key === false) {
                $result = $this->execMultiple();
            } else {
                $result = $this->execSingle($key);
            }
        }

        if ($result) {
            return $result;
        }
    }

    /**
     * Executes a single cURL session.
     *
     * @param	$key	integer		id of session to execute
     * @return			array		content if CURLOPT_RETURNTRANSFER is set
     */
    public function execSingle(int $key = 0): array
    {
        if ($this->retries > 0) {
            $retries = $this->retries;
            $http_code = 0;

            while ($retries >= 0 AND ($http_code[0] == 0 OR $http_code[0] >= 400)) {
                $result = curl_exec($this->sessions[$key]);

                $http_code = $this->info($key, CURLINFO_HTTP_CODE);

                $retries--;
            }
        } else {
            $result = curl_exec($this->sessions[$key]);
        }
        return $result;
    }

    /**
     * Executes multiple sessions.
     *
     * @return	array	content if CURLOPT_RETURNTRANSFER is set
     */
    public function execMultiple(): array
    {
        $mh = curl_multi_init();

        foreach ($this->sessions AS $i => $url) {
            curl_multi_add_handle($mh, $this->sessions[$i]);
        }

        do {
            $mrc = curl_multi_exec($mh, $active);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);

        while ($active AND $mrc == CURLM_OK) {
            if (curl_multi_select($mh) != -1) {
                do {
                    $mrc = curl_multi_exec($mh, $active);
                } while ($mrc == CURLM_CALL_MULTI_PERFORM);
            }
        }

        if ($mrc != CURLM_OK) {
            echo "Curl multi read error $mrc\n";
        }

        foreach ($this->sessions AS $i => $url) {
            $http_code = $this->info($i, CURLINFO_HTTP_CODE);

            if ($http_code[0] > 0 AND $http_code[0] < 400) {
                $result[] = curl_multi_getcontent($this->sessions[$i]);
            } else {
                if ($this->retries > 0) {
                    $retries = $this->retries;
                    $this->retries -= 1;

                    $exec = $this->execSingle($i);

                    if ($exec) {
                        $result[] = $exec;
                    } else {
                        $result[] = false;
                    }

                    $this->retries = $retries;
                }
                else
                {
                    $result[] = false;
                }
            }
            curl_multi_remove_handle($mh, $this->sessions[$i]);
        }
        curl_multi_close($mh);

        return $result;
    }

    /**
     * Closes cURL sessions.
     *
     * @param	$key	integer		Optional, session close
     */
    public function close($key = false)
    {
        if ($key === false) {
            foreach ($this->sessions AS $session) {
                curl_close($session);
            }
        } else {
            curl_close($this->sessions[$key]);
        }
    }

    /**
     * Remove all cURL sessions.
     */
    public function clear()
    {
        foreach ($this->sessions AS $session) {
            curl_close($session);
        }
        $this->sessions = [];
    }

    /**
     * Returns an array of session information.
     *
     * @param	$key		integer		Optional session key to return info on
     * @param	$option		constant	Optional option to return
     * @return				array
     */
    public function info($key = false, $option = false): array
    {
        if ($key === false) {
            foreach ($this->sessions AS $key => $session) {
                if ($option) {
                    $info[] = curl_getinfo($this->sessions[$key], $option);
                } else {
                    $info[] = curl_getinfo($this->sessions[$key]);
                }
            }
        } else {
            if ($option) {
                $info[] = curl_getinfo($this->sessions[$key], $option);
            } else {
                $info[] = curl_getinfo($this->sessions[$key]);
            }
        }
        return $info;
    }

    /**
     * Returns an array of errors.
     *
     * @param	$key	integer		Optional session key to retun error on
     * @return			array		error messages
     */
    public function error($key = false): array
    {
        if ($key === false) {
            foreach ($this->sessions AS $session) {
                $errors[] = curl_error($session);
            }
        }
        else
        {
            $errors[] = curl_error($this->sessions[$key]);
        }
        return $errors;
    }

    /**
     * Returns an array of session error numbers.
     *
     * @param	$key	integer		Optional session key to retun error on
     * @return			array		error codes
     */
    public function errorNumber($key = false)
    {
        if ($key === false) {
            foreach ($this->sessions AS $session) {
                $errors[] = curl_errno($session);
            }
        } else {
            $errors[] = curl_errno($this->sessions[$key]);
        }
        return $errors;
    }
}

class Pastebin
{
    /**
     * Used for spam protection methods. You will need to get an API Key at:
     * http://pastebin.ca/apikey.php
     */
    const API_KEY = '';
    const API_URL = 'http://pastebin.ca/quiet-paste.php?api=%s';
    const API_ROOT = 'http://pastebin.ca';
    const API_POST = '&content=%s&description=%s&type=%d&expiry=%s&name=%s';

    /**
     * Class instance.
     *
     * @var	object
     */
    private static $instance;

    /**
     * Types of text, and their option number
     *
     * @var	array
     */
    private $languages = [
        22 => 'ASP',
        18 => 'Action Script',
        19 => 'Ada Source',
        20 => 'Apache Configuration',
        21 => 'Assembly (NASM)',
        2  => 'Asterisk Configuration',
        23 => 'BASH Script',
        3  => 'C Source',
        9  => 'C# Source',
        4  => 'C++ Source',
        24 => 'CSS',
        25 => 'Delphi Source',
        26 => 'HTML 4.0 Strict',
        7  => 'Java Source',
        27 => 'JavaScript',
        28 => 'LISP Source',
        29 => 'Lua Source',
        30 => 'Microprocessor ASM',
        31 => 'Objective C',
        5  => 'PHP Source',
        14 => 'PL',
        12 => 'Pascal Source',
        6  => 'Perl Source',
        11 => 'Python Source',
        1  => 'Raw',
        10 => 'Ruby Source',
        33 => 'Script Log',
        16 => 'SQL Statement',
        17 => 'Scheme Source',
        32 => 'Visual Basic .NET',
        8  => 'Visual Basic Source',
        15 => 'XML Document',
        13 => 'mIRC Script'
    ];

    /**
     * Expiry options
     *
     * @var	array
     */
    private $expiration = [
        'Never',
        '5 minutes',
        '10 minutes',
        '15 minutes',
        '30 minutes',
        '45 minutes',
        '1 hour',
        '2 hours',
        '4 hours',
        '8 hours',
        '12 hours',
        '1 day',
        '2 days',
        '3 days',
        '1 week',
        '2 weeks',
        '3 weeks',
        '1 month',
        '2 months',
        '3 months',
        '4 months',
        '5 months',
        '6 months',
        '1 year'
    ];
    
    /**
     * Constructor.
     */
    private function __construct()
    {
        if (self::API_KEY == '') {
            throw new Exception('You have not specified a Pastebin.ca API Key for Pastebin::API_KEY');
        }
    }

    /**
     * Creates an instance of the class.
     *
     * @return	Pastebin
     */
    public static function getInstance(): Pastebin
    {
        if (!self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Submit paste request to pastebin.ca
     *
     * @param	string		$content		Paste content
     * @param	string		$description	Paste description (optional)
     * @param	integer		$type			Paste format/language, 1=Raw, 5=PHP, etc {@see self::$languages}
     * @param	string		$expiry			Paste expiration time {@see self::$expiration}
     * @param	string		$name			Paste name/from
     * @return	mixed						Pastebin URL on success, false or error string on failure.
     */
    public function post(string $content, string $description = '', int $type = 1, string $expiry = '', string $name = 'clueless')
    {
        if (empty($content)) {
            throw new Exception('$content cannot be empty');
        }

        if (!isset($this->languages[$type])) {
            $type = 1; // Raw
        }

        if ($expiry == 'Never' OR !in_array($expiry, $this->expiration)) {
            $expiry = ''; // Never is empty.
        }

        if (empty($name)) {
            $name = 'clueless';
        }

        $curl = cURL::getInstance();
        $curl->addSession(sprintf(self::API_URL, self::API_KEY), [
            CURLOPT_HEADER         => false,
            CURLOPT_POST           => true,
            CURLOPT_POSTFIELDS     => sprintf(self::API_POST, $content, $description, $type, $expiry, $name),
            CURLOPT_REFERER        => self::API_ROOT,
            CURLOPT_RETURNTRANSFER => true
        ]);

        $result = $curl->exec();

        $curl->clear();

        if ($result) {
            $result = explode(':', $result);
            return self::API_ROOT . "/$result[1]";
        } else {
            if ($curl->error()) {
                return implode("<br />\n", $curl->error());
            }
        }
        return false;
    }
}

?>

And an example:

<?php

$pb = Pastebin::getInstance();
$paste = $pb->post('<?php

echo "This is a test again";

?>', 'test', 5, '', 'anonymous');

if ($paste !== false) {
	echo $paste;
}

?>

Enjoy. 🙂

Eric Sizemore

I’m a 36 year old Web Developer, Programmer, and Domainer. I specialize in PHP and MySQL, and have used both extensively since early 2005.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.