Implementare un server REST con lo stack LAMP: il codice PHP

Implementare un server REST con lo stack LAMP: il codice PHP

Il terzo passo per implementare un server REST utilizzando lo stack LAMP (Linux Apache MySQL PHP) è quello di creare il codice PHP.

Dobbiamo creare una classe astratta il cui compito principale sarà quello di mappare i metodi della classe concreta con gli URL delle nostre API. In pratica se abbiamo un URL come http://api.test/api/auth, la classe concreta dovrà avere un metodo pubblico chiamato auth():


<?php
abstract class API
{
	protected $_method = '';
	protected $_endpoint = '';
	protected $_verb = '';
	protected $_args = array();
	protected $_file = null;

	public function __construct()
	{

		$this->_args = explode('/', rtrim($_REQUEST['request'], '/'));
        $this->_endpoint = array_shift($this->_args);
        if (array_key_exists(0, $this->_args) && !is_numeric($this->_args[0])) {
            $this->_verb = array_shift($this->_args);
        }

        $this->_method = $_SERVER['REQUEST_METHOD'];

        switch($this->_method) {
        	case 'DELETE':
        	case 'POST':
            	$this->request = $this->_cleanInputs($_POST);
            	break;
        	case 'GET':
            	$this->request = $this->_cleanInputs($_GET);
            	break;
        	case 'PUT':
            	$this->request = $this->_cleanInputs($_GET);
            	$this->_file = file_get_contents('php://input');
            	break;
        	default:
            	$this->_response('Invalid Method', 405);
            	break;
        }
	}

	public function processAPI() 
	{
        if (method_exists($this, $this->_endpoint)) {
            return $this->_response($this->{$this->_endpoint}($this->_args));
        }
        return $this->_response("No Endpoint: $this->_endpoint", 404);
    }

	protected function _sendHeaders()
	{
        header('Access-Control-Allow-Methods: *');
        
	}

	protected function _response($data, $status = 200) 
	{
        
        $output = array();
        $stat = (string) $status;
        $output[$stat] = $data;
        return json_encode($output);
    }

	private function _cleanInputs($data) 
	{
        $cleanInput = array();
        if (is_array($data)) {
            foreach ($data as $k => $v) {
                $cleanIinput[$k] = $this->_cleanInputs($v);
            }
        } else {
            $cleanIinput = trim(strip_tags($data));
        }
        return $cleanInput;
    }

    private function _requestStatus($code) 
    {
        $status = array(  
            200 => 'OK',
            404 => 'Not Found',   
            405 => 'Method Not Allowed',
            500 => 'Internal Server Error',
        ); 
        return ($status[$code]) ? $status[$code] : $status[500]; 
    }

}

Ecco un esempio di classe concreta:


<?php
require_once('API.php');

class Test extends API
{
	public function __construct()
	{
		parent::__construct();
	}
	
	public function auth()
	// http://api.test/api/auth
	{
		// Accettiamo solo richieste POST
		if($this->_method == 'POST') {
			$username = trim($_REQUEST['username']);
			$password = base64_decode(trim($_REQUEST['password']));
			$output = array();
			
			// Se l'autenticazione ha successo
			
			$output['authenticated'] = '1';
			
			echo json_encode($output);
				
		} else {
			echo $this->_response('Invalid Method', 405);
		}
	}
}

Infine nel nostro file index.php avremo:


<?php
header('Content-Type: application/json');
require_once('Test.php');
$test = new Test();
$test->processAPI();

Torna su