on Tutorials

OOP PHP tips and tricks and example on Wordnik API

2 comments
wordnik
Tweet about this on TwitterShare on FacebookShare on Google+Share on LinkedInShare on RedditShare on StumbleUpon

Every day I stumble across interesting APIs which provide REST, XML or JSON type of service. Wouldn’t it be nice to build a generic code which you can use with minimum amount of changes on basically all the APIs?

I will try to show you how to build a class to communicate with Wordnik dictionary API.

Wordnik is a dictionary and thesaurus application with great free service. It provides several types of searching, spell checker functionality, related words, word of a day and much more.

Whenever you need to write some code to call API functions, you should explore the developers documentation. If you go to Wordnik Word of the Day documentation (which I will use later) you can see that there is some parameters to be sent to some URL and you get a response.

The demo of the final app can be seen below:


So let us build our skeleton class. I usually write skeleton code trying to see what methods to use and how will my final class look like.

/**
* Wordnik class
*/
class Wordnik {
      
    const URI = 'http://api.wordnik.com/api';
    
    var $apiKey;
    
    public function __construct($apiKey) {
        
        if(!isset($apiKey) or trim($apiKey) == '') {
            throw new Exception("You must provide a valid API key!");
        }
        
        $this->apiKey = $apiKey;
    }
    
    
    /**
    * Method for retrieving Word of the day 
    */
    public function getWordOfTheDay() {
        
    }
    
    /**
    * Method for retrieving Word definitions
    * 
    * @param mixed $word
    * @param mixed $count
    * @param mixed $partOfSpeech
    * @returns json object with word definitions
    */
    public function getWordDefinitions($word, $count = 10, $partOfSpeech = null) {
        
    }

    /**
    * Method for retrieving Example sentences for given word
    * 
    * @param string $word
    * @return object with example sentences 
    */
    public function getWordExamples($word) {
        
    }
    
    /**
    * Method for API calls
    * 
    * @param string $url
    * @param array $params
    * @param string $method
    * @returns response data
    */
    private function apiCall($url, $params = array(), $method = 'get') {
        
    }
}

This is how the class will look like. In our __construct method I am checking for a presence of API key and throwing an exception if there isn’t one provided.

Methods getWordDefinitions and getWordOfTheDay will use the method apiCall to talk to the API. So let us write that code first.

I will try to cover as much diversity in this method, but for the scope of this tutorial, I will use only JSON response. So, here is how I have written apiCall method:

private function apiCall($url, $params = array(), $method = 'get') {
        
        $data = null;

        $headers = array();
        $headers[] = "Content-type: application/json";
        $headers[] = "api_key: " . $this->apiKey;

        $url = (self::URI . $url);

        $curl = curl_init();
        curl_setopt($curl, CURLOPT_TIMEOUT, 3); 
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);

        if ($method == 'get' && !empty($params)) { 
            $url = ($url . '?' . http_build_query($params));
        } else if ($method == 'post') { 
            curl_setopt($curl, CURLOPT_POST, true);
            curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($params));
        }

        curl_setopt($curl, CURLOPT_URL, $url);
        
        // make the request
        $response = curl_exec($curl);
        $responseInfo = curl_getinfo($curl);
        
        switch($responseInfo['http_code']) {
            case 0:
                throw new Exception('Timeout reached when calling ' . $url);
            break;
            case 200:
                $data = json_decode($response);
            break;
            case 401:
                throw new Exception('Unauthorized request to ' . $url . ': '.json_decode($response)->message );
            break;
            case 404;
                $data = null;
            break;
            default:
                throw new Exception('Connect to API failed with response: ' . $responseInfo['http_code']);
            break;
        }
        
        return $data;    
    }

This method is private and can not (and should not) be called directly. Its purpose is to provide API call functionality to other methods in class.

There are some interesting parts in this method worth mentioning. For example function http_build_query. I am using this function a lot lately. It generates a URL-encoded query string from the associative (or indexed) array provided. Very useful.

Another interesting part is that it can request data through GET or POST.

Now let us build the getWordOfTheDay method:

public function getWordOfTheDay() {
    
    return $this->apiCall('/wordoftheday.json/');    
}

That’s it. This call does not need any parameters. What about getWordDefinitions method:

    public function getWordDefinitions($word, $count = 10, $partOfSpeech = null) {
    
        if(is_null($word) or trim($word) == '') {
            throw new Exception("Method getWordDefinitions expects a word to be passed!");
        }
        $params = array();
        $params['count'] = $count;
        if (isset($partOfSpeech)) {
          $params['partOfSpeech'] = $part_of_speech;
        }
        
        return $this->apiCall('/word.json/' . rawurlencode($word) . '/definitions', $params);    
    }

And lastly, the method for retrieving example sentences for a given word:

    public function getWordExamples($word) {
        
        if(is_null($word) || trim($word) == '') {
            throw new Exception("Method getWordExamples expects a word to be passed!");
        }
        
        return $this->apiCall( '/word.json/' . rawurlencode($word) . '/examples' );
    }

Now we have a working class (I hope) for making a small Wordnik API application. Here is the code for it:

<?php
    require_once("my_wordnik.php");
    
    try {
        $wordnik = new Wordnik("YOUR_API_KEY_HERE");
        
        // get the Word of the Day
        $temp = $wordnik->getWordOfTheDay();
        $wordOfTheDay = $temp->wordstring;
        
        if(isset($_GET['submit'])) { // form was submitted
            $word = filter_input(INPUT_GET, 'word', FILTER_SANITIZE_SPECIAL_CHARS);
        }
        
    } catch (Exception $e) {
        echo $e->getMessage();
    }
?>

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Wordnik API demo - Codeforest, web development blog</title>

<link rel="stylesheet" type="text/css" href="default.css" />

</head>

<body>

<div id="page">

    <div class="block rounded">
        <h1>Wordnik API demo</h1>
    </div>
    
    <div class="block_main rounded">
    
        <h3>Today's word of the day is: <em><?php echo $wordOfTheDay; ?></em></h3>
        
        <form method="get" action="index.php">
            Word: <input type="text" id="name" name="word" />
            <input type="submit" name="submit" value="Submit" />
        </form>
        
        <?php if (isset($word)): ?>
          <hr />
          <div>
            <?php $definitions = $wordnik->getWordDefinitions($word); ?>
            <h2>Definitions of <em><?php echo($word) ?></em></h2>
            <?php if (empty($definitions)): ?>
              <em>Sorry, no definitions found!</em>
            <?php else: ?>
              <ul>
                <?php 
                  foreach($definitions as $definition) {
                    if (isset($definition->text)) {
                      echo("<li>".$definition->text."</li>");
                    }
                  }
                ?>
              </ul>
              <a target="_blank" href="http://wordnik.com/words/<?php echo(urlencode($word)) ?>">Read more ...</a>
            <?php endif ?>
          </div>
          <br />
          <hr /><br />
          <div>
            <?php $examples = $wordnik->getWordExamples($word); ?>
            <h2>Examples of <em><?php echo($word) ?></em></h2>
            <?php if (empty($examples)): ?>
              <em>Sorry, no examples for given word!</em>
            <?php else: ?>
              <ul>
                <?php
                  foreach($examples as $example) {
                    if (isset($example->display)) {
                      echo("<li>".$example->display);
                      if (isset($example->title)) {
                        echo("<br />- <em>".$example->title."</em>");
                      }
                    }
                  }
                ?>
              </ul>
              <a target="_blank" href="http://wordnik.com/words/<?php echo(urlencode($word)) ?>">Read more ...</a>
            <?php endif ?>
          </div>
        <?php endif ?>

    </div>

<div class="footer block_footer rounded">
      <a href="http://www.codeforest.net">By Codeforest</a>
    </div>
</div>
</body>
</html>

That’s it for today, I hope you learned something new and that this techniques will help you to become a great PHP developer. Stay tuned as I am going to add some more code to this class and show you how to use it with jQuery AJAX.

Tweet about this on TwitterShare on FacebookShare on Google+Share on LinkedInShare on RedditShare on StumbleUpon