Smart Guide On Creating a Complete PHP Package Using Composer
Tags: composer, composerpackage, composerinstall
Published: 2017-01-13 12:15:18

---
title: Smart Guide On Creating a Complete PHP Package Using Composer
published: true
description: Composer is the best solution for managing dependencies in PHP projects. Learn how to create a package using Composer
cover_image: http://i.imgur.com/Zd4Nezu.jpg
tags: composer, composer package, composer install
---
Composer is a dependency manager for PHP created by [Nils Adermann](http://naderman.de/), [Jordi Boggiano](http://nelm.io/jordi) and other community contributors. With Composer, developers could develop code that include components from several libraries and packages. Composer installs all required libraries and packages automatically, and thus the code does not break because of the absence of a required code component.

Another important use of Composer is the creation of a self-contained package that contains all the required code components in one place. Thus, instead of pulling code from several locations and resources, the developer has to include a single package and focus solely on implementation of the logic rather than worrying about external code resources.

The most common usage of the Composer is the following single command that installs a particular package:

`$ composer install 'packagename:version'`

## Package Creation Using Composer

Composer is also used to create custom packages from open source packages and/or [private packages](https://packagist.com/). These custom packages could then be installed using the above mentioned command.  In this article, I will demonstrate the package creation capability of Composer by creating a package for Twitter search API. I will then [register it](http://packagist.org) and then install it on my server.

Before starting, make sure that Composer is installed on the local system.

### Git Repo Creation

The first step is to create a public Git repo. Go to the GitHub account and create a new repository with .gitignore file. Next, add the following folder and file to .gitignore file. ( in some instances, these items are auto-generated)

```php
composer.phar
/vendor/
```
Once the repo has been created, clone it to the local system. The next step is the creation of a **TwitterSearch** class, which will be based on Twitter API.

## The TwitterSearch Class

I will base the Twitter PHP-SDK on PSR-4 namespacing. Before getting started with the class creation, run the following command in the local Git repository folder to install Guzzle HTTP Client for handling Twitter request and response.

`$composer require "guzzlehttp/guzzle:^6.2";`



In the local Git folder create a new folder and name it **Twitter**. Next, in this folder, create a new file and name it **Base.php**. Open this file in your code editor and add the following code to it:

```php
namespace Twitter;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Psr7\Request;

/**
*
*/
class Base
{
    
    const API_URL = "https://api.twitter.com/1.1";
    
    protected $client;
    protected $token;
    protected $tokensecret;
    protected $accesstoken;
    public function __construct()
    {
        $this->client = new \GuzzleHttp\Client();
    }
    
    public function setToken($token,$secret)
    {
        $this->token = $token;
        $this->tokensecret = $secret;
    }
    
    protected function prepareAccessToken()
    {
        try{
            $url = "https://api.twitter.com/oauth2/token";
            $value = ['grant_type' => "client_credentials"
            ];
            $header = array('Authorization'=>'Basic ' .base64_encode($this->token.":".$this->tokensecret),
            "Content-Type"=>"application/x-www-form-urlencoded;charset=UTF-8");
            $response = $this->client->post($url, ['query' => $value,'headers' => $header]);
            $result = json_decode($response->getBody()->getContents());
            
            $this->accesstoken = $result->access_token;
        }
        catch (RequestException $e) {
            $response = $this->statusCodeHandling($e);
            return $response;
        }
    }
    protected function callTwitteAPIr($method,$request,$post = [])
    {
        try{
            $this->prepareAccessToken();
            $url = self::API_URL . $request;
            $header = array('Authorization'=>'Bearer ' . $this->accesstoken);
            $response = $this->client->request($method,$url, array('query' => $post,'headers' => $header));
            return json_decode($response->getBody()->getContents());
        } catch (RequestException $e) {
            $response = $this->StatusCodeHandling($e);
            return $response;
        }
    }
    protected function statusCodeHandling($e)
    {
        $response = array("statuscode" => $e->getResponse()->getStatusCode(),
        "error" => json_decode($e->getResponse()->getBody(true)->getContents()));
        return $response;
    }
}
```

This is the base class that is responsible for the generation of access tokens for Twitter API and API related requests.

I will now explain some aspects of this class.

First I initialized the namespace, and then the Guzzle classes. Next, I created a constant for Twitter API URL, various variables, and a constructor that call **Guzzle\Client**.


```php
const API_URL = "https://api.twitter.com/1.1";
    
    protected $client;
    protected $token;
    protected $tokensecret;
    protected $accesstoken;
    public function __construct()
    {
        $this->client = new \GuzzleHttp\Client();
    }
```

Next, I created functions for preparing the access token and calling the user-generated Twitter API requests.

```php
public function setToken($token,$secret)
    {
        $this->token = $token;
        $this->tokensecret = $secret;
    }
```
Next, I created functions for preparing the access token and calling the user-generated Twitter API requests.

```php
  protected function prepareAccessToken()
    {
        try{
            $url = "https://api.twitter.com/oauth2/token";
            $value = ['grant_type' => "client_credentials"
            ];
            $header = array('Authorization'=>'Basic ' .base64_encode($this->token.":".$this->tokensecret),
            "Content-Type"=>"application/x-www-form-urlencoded;charset=UTF-8");
            $response = $this->client->post($url, ['query' => $value,'headers' => $header]);
            $result = json_decode($response->getBody()->getContents());
            
            $this->accesstoken = $result->access_token;
        }
        catch (RequestException $e) {
            $response = $this->statusCodeHandling($e);
            return $response;
        }
    }
    protected function callTwitter($method,$request,$post = [])
    {
        try{
            $this->prepareAccessToken();
            $url = self::API_URL . $request;
            $header = array('Authorization'=>'Bearer ' . $this->accesstoken);
            $response = $this->client->request($method,$url, array('query' => $post,'headers' => $header));
            return json_decode($response->getBody()->getContents());
        } catch (RequestException $e) {
            $response = $this->StatusCodeHandling($e);
            return $response;
        }
    }
    protected function statusCodeHandling($e)
    {
        $response = array("statuscode" => $e->getResponse()->getStatusCode(),
        "error" => json_decode($e->getResponse()->getBody(true)->getContents()));
        return $response;
    }
```

In addition, I have created a function for handling the error codes.

Now create a new folder in the local Git repo folder and name it **Search**. In this folder create a new file,  name it **Search.php** and paste the following code in it:


```php
namespace Twitter\Search;
/**
 * 
 */
class Search extends \Twitter\Base
{

    public function search($value)
    {
        try{
            $url = "/search/tweets.json";
            $response = $this->callTwitter("get",$url,$value);
            return $response;
        } catch (RequestException $e) {
            $response = $this->StatusCodeHandling($e);
            return $response;
        }
    }    
}
```

Let me explain the code in some detail.

First, I gave a **namespace** for the class and then extend it to the **Base class**. Next, I created a function **Search()** to perform search via [Twitter Search API](https://dev.twitter.com/rest/public/search). **Search()** accepts the variable **$value** that contains the parameters of the search query as defined in the Twitter API.

```php
public function search($value)
    {
        try{
            $url = "/search/tweets.json";
            $response = $this->callTwitter("get",$url,$value);
            return $response;
        } catch (RequestException $e) {
            $response = $this->StatusCodeHandling($e);
            return $response;
        }
    }
```

Next, I will add the namespace in **composer.json** file that will be included in the **autoload.php**. Open **composer.json** file and add the following lines to it:


``` json
,
"autoload": {
        "psr-4": {
            "Twitter\\" : "Twitter/"
        }
    }
```

The new **composer.json** file will look like this:

```json
{
    "require": {
        "guzzlehttp/guzzle": "^6.2"
    },
    "autoload": {
        "psr-4": {
            "Twitter\\" : "Twitter/"
        }
    }
}
```

Now run the following command.

`$ composer dump-autoload`



### Get the Keys

The next step is to get the consumer key and the consumer secret key for Twitter API.

To get the keys, login to [https://apps.twitter.com/](https://apps.twitter.com/). Create a new application in order to get the consumer keys.



### Test the Project

Now that I have all the necessary components of the project, I could now test them to make sure that everything is working properly.



In the root of the Git folder, create a new file with the name **index.php,** and paste the following code in it:


```php
include "vendor/autoload.php";

use Twitter\Search\Search;

$search = new Search();
$search->setTokken("afmowdkHQTZVZWMxx0dh5Bz4r","fuJ4HNNTkI27qZEFdv3g4MEMXdVoZHUIVXCwmDbqXBRWMrEQAU");
$value = ["q" => "ahmed khan"];
echo "<pre>";
print_r($search->search($value));
echo "</pre>";
```

Now run **index.php** on the localhost. If you get the result array, things are working correctly!



Now that the project is completed and working perfectly, I will now convert it into a Composer package.

## Create the Composer Package

Open **composer.json** and replace the code with the following:


```json
{
    "name": "ahmed.khan/twittersdkphp", //naming our package
    "description": "A PHP-SDK for Twitter Search API", // Description about package
    "keywords": ["twitter search", "search"], // Keywords
    "type": "package", //Since it's a package  we define its type package
    "require": {
        "guzzlehttp/guzzle": "^6.2"
    },
    "license": "MIT",
    "authors": [{ //Your information
        "name": "Ahmed Khan", 
        "email": "ahmedkhan_847@hotmail.com"
    }],
    "autoload": {
        "psr-4": {
            "Twitter\\": "Twitter/"
        }
    },
    "version": "1.0.0", //Version of the package
    "minimum-stability": "dev" //Stability

}
```

All the schema can be found [here](https://getcomposer.org/doc/04-schema.md). Now push all the code to the Git repository. Once it is done, go to [https://packagist.org/](https://packagist.org/). Login with GitHub and then click **Submit** in the top menu. Paste the URL of the Git repository and click the **Check** button.





Wait for the verification process to finish and then click the **Submit** button.



Once done, the following message will appear:


***"The packagist is not auto-updated"***

In order to resolve this issue, go to the GitHub account and the page to the settings of the related repository. Click **Integrations &amp; Services &gt; Add Service,** find and click **Packagist.**



You might be prompted to enter your GitHub password. In the next window, add your Packagist username and token. Check the **Active** box and then click the **Add service** button.



Once the service has been added, click the **Test service** button.



Now refresh the page and observe that the error is gone!



Now that the package has been created, I will now test it!

## Test the Composer Package

Now on a separate machine or a server, run the following command to install the package via Composer.


`$ composer require "ahmedkhan847/twittersdkphp:dev-master"`



You will notice that the package is being installed.

## Conclusion

In this tutorial, I created a Composer package based on Twitter Search API. I also submitted the package to Packagist, and then tested it by installing the package via Composer. You can find this complete package on [Github](https://github.com/ahmedkhan847/twittersearchphpsdk/)and on [Packagist](https://packagist.org/packages/ahmedkhan847/twittersdkphp). If you face any issue during the process, leave a comment below.