Матвей Земсков

Заметки веб-мастера

Понедельник, 24 сентября 2018 20:18

Создаем RESTful веб-службу на PHP

Оцените материал
(9 голосов)

REST(Representational State Transfer) является архитектурным стилем. Веб-службы, которые придерживаются принципов REST называются RESTful веб-службами. URI в них служат для доступа к ресурсам. В RESTful-терминологии данные и функции называются ресурсами. Поэтому в конечном итоге данные и функции - это то, к чему мы будем обращаться через службы.

В этом руководстве по RESTful веб-службам автор расскажет о том, как создать такой веб-сервис. Весь код будет написан на «чистом» PHP без применения какого-либо фреймворка. В большинстве случаев автор статьи предпочитает писать свой код без использования фреймворков, в чем есть свои преимущества.

В Интернете можно найти учебные пособия по веб-сервисам, но в большинстве случаев они оказываются неполными или содержат ошибки. Процесс тестирования упомянутых веб-сервисов с помощью REST-клиента часто заканчивался неудачей.

ДЕМО

Целями разработки RESTful веб-службы, создание которой описано в этой статье, являются:

  • Создание RESTful веб-сервиса;
  • Написание его на чистом PHP без использования фреймворков;
  • Обеспечение соответствия шаблонов URI принципам REST;
  • RESTful веб-служба должна отвечать на запросы в таких форматах, как JSON и XML;
  • Возвращение разных кодов состояния HTTP при разных сценариях работы;
  • Демонстрация использования заголовков запроса;
  • Обеспечение возможности тестирования веб-службы с помощью REST-клиента;

Пример RESTful веб-сервиса

Приведем пример класса домена, используемого для демонстрации RESTful веб-служб.

PHP

<?php
/* 
Класс домена, используемого для демонстрации RESTful веб-служб
*/
Class Mobile {	
	private $mobiles = array(
		1 => 'Apple iPhone 6S',  
		2 => 'Samsung Galaxy S6',  
		3 => 'Apple iPhone 6S Plus',  			
		4 => 'LG G4',  			
		5 => 'Samsung Galaxy S6 edge',  
		6 => 'OnePlus 2');
		
	/*
	здесь вы должны подключить Data Access Object (DAO) 
	*/
	public function getAllMobile(){
		return $this->mobiles;
	}	
	public function getMobile($id){		
		$mobile = array($id => ($this->mobiles[$id]) ? $this->mobiles[$id] : $this->mobiles[1]);
		return $mobile;
	}	
}
?>

Преобразование URI в RESTful веб-службах

RESTful веб-службы должны иметь чистые унифицированные URI. Для сопоставления URL-адресов между запросом и реальным файлом используется файл .htaccess. В нашем примере мы используем 2 URI.

Чтобы получить список мобильных устройств: http://localhost/restexample/mobile/list/

Чтобы получить детальную информацию о конкретном устройстве URI должен содержать его ID. Например, “2” в следующем примере – как раз ID устройства: http://localhost/restexample/mobile/list/2/

Ниже приведен файл .htaccess, который получает URL-адрес запроса и перенаправляет запрос в PHP- файл.

.htaccess

	# активируем преобразование URL
	Options +FollowSymlinks
	RewriteEngine on

	# прописываем соответствие URL и файла, который будет его обрабатывать
	RewriteRule ^mobile/list/$   RestController.php?view=all [nc,qsa]
	RewriteRule ^mobile/list/([0-9]+)/$   RestController.php?view=single&id=$1 [nc,qsa]

Контроллер RESTful веб-службы

В файле .htaccess.htaccess мы перенаправили все запросы на файл RestController.php с параметром view. Этот параметр идентифицирует действие, которое должен выполнить скрипт. Файл RestController.php содержит код, который описывает действия, передаваемые в параметре URL.

PHP

	<?php
	require_once("MobileRestHandler.php");
			
	$view = "";
	if(isset($_GET["view"]))
		$view = $_GET["view"];
	/*
	соответствие URL и методов RESTful веб-службы
	*/
	switch($view){

		case "all":
			// обрабатывает REST Url /mobile/list/
			$mobileRestHandler = new MobileRestHandler();
			$mobileRestHandler->getAllMobiles();
			break;
			
		case "single":
			// обрабатывает REST Url /mobile/show/<id>/
			$mobileRestHandler = new MobileRestHandler();
			$mobileRestHandler->getMobile($_GET["id"]);
			break;

		case "" :
			//404 – не найден;
			break;
	}
	?>

Простой базовый класс RESTful

Следующий класс имеет несколько методов, которые могут быть широко использованы во всех обработчиках веб-сервиса REStful. Один метод используется для построения ответа, а другие методы - содержат обработчики HTTP-кодов состояния и возвращают соответствующие им сообщения. Методы, содержащиеся в классе являются общими для всех веб-служб, поэтому этот класс можно считать базовым для всех классов REStful веб-сервиса. Сохраним этот код в файле SimpleRest.php

PHP

	<?php 
	/*
	Простой базовый класс веб-сервисов RESTful
	Используйте его как шаблон 
	*/
	class SimpleRest {
		
		private $httpVersion = "HTTP/1.1";

		public function setHttpHeaders($contentType, $statusCode){
			
			$statusMessage = $this -> getHttpStatusMessage($statusCode);
			
			header($this->httpVersion. " ". $statusCode ." ". $statusMessage);		
			header("Content-Type:". $contentType);
		}
		
		public function getHttpStatusMessage($statusCode){
			$httpStatus = array(
				100 => 'Continue',  
				101 => 'Switching Protocols',  
				200 => 'OK',
				201 => 'Created',  
				202 => 'Accepted',  
				203 => 'Non-Authoritative Information',  
				204 => 'No Content',  
				205 => 'Reset Content',  
				206 => 'Partial Content',  
				300 => 'Multiple Choices',  
				301 => 'Moved Permanently',  
				302 => 'Found',  
				303 => 'See Other',  
				304 => 'Not Modified',  
				305 => 'Use Proxy',  
				306 => '(Unused)',  
				307 => 'Temporary Redirect',  
				400 => 'Bad Request',  
				401 => 'Unauthorized',  
				402 => 'Payment Required',  
				403 => 'Forbidden',  
				404 => 'Not Found',  
				405 => 'Method Not Allowed',  
				406 => 'Not Acceptable',  
				407 => 'Proxy Authentication Required',  
				408 => 'Request Timeout',  
				409 => 'Conflict',  
				410 => 'Gone',  
				411 => 'Length Required',  
				412 => 'Precondition Failed',  
				413 => 'Request Entity Too Large',  
				414 => 'Request-URI Too Long',  
				415 => 'Unsupported Media Type',  
				416 => 'Requested Range Not Satisfiable',  
				417 => 'Expectation Failed',  
				500 => 'Internal Server Error',  
				501 => 'Not Implemented',  
				502 => 'Bad Gateway',  
				503 => 'Service Unavailable',  
				504 => 'Gateway Timeout',  
				505 => 'HTTP Version Not Supported');
			return ($httpStatus[$statusCode]) ? $httpStatus[$statusCode] : $status[500];
		}
	}
	?>

Обработчик RESTful веб-сервиса

Это класс, который обрабатывает REST запрос. Вы должны обратить внимание на несколько вещей. Во-первых, как обработчик REST решает, какой формат ответа следует отправить назад. Это определяется на основе параметра заголовка запроса “Accept”. По протоколу при отправке запроса должен быть установлен и отправлен заголовок “Accept”. Его значения могут быть следующими: “application/json”, “application/xml” или “text/html”. Во-вторых, вы должны использовать коды состояния. При успешном результате работы скрипта, вместе с ответом от сервера вы должны отправить статус с кодом 200. Существуют разные коды состояния и их следует использовать аналогично упомянутому коду 200 в соответствии с ситуацией.

PHP

<?php
require_once("SimpleRest.php");
require_once("Mobile.php");
		
class MobileRestHandler extends SimpleRest {

	function getAllMobiles() {	

		$mobile = new Mobile();
		$rawData = $mobile->getAllMobile();

		if(empty($rawData)) {
			$statusCode = 404;
			$rawData = array('error' => 'No mobiles found!');		
		} else {
			$statusCode = 200;
		}

		$requestContentType = $_SERVER['HTTP_ACCEPT'];
		$this ->setHttpHeaders($requestContentType, $statusCode);
				
		if(strpos($requestContentType,'application/json') !== false){
			$response = $this->encodeJson($rawData);
			echo $response;
		} else if(strpos($requestContentType,'text/html') !== false){
			$response = $this->encodeHtml($rawData);
			echo $response;
		} else if(strpos($requestContentType,'application/xml') !== false){
			$response = $this->encodeXml($rawData);
			echo $response;
		}
	}
	
	public function encodeHtml($responseData) {
	
		$htmlResponse = "<table border='1'>";
		foreach($responseData as $key=>$value) {
    			$htmlResponse .= "<tr><td>". $key. "</td><td>". $value. "</td></tr>";
		}
		$htmlResponse .= "</table>";
		return $htmlResponse;		
	}
	
	public function encodeJson($responseData) {
		$jsonResponse = json_encode($responseData);
		return $jsonResponse;		
	}
	
	public function encodeXml($responseData) {
		// creating object of SimpleXMLElement
		$xml = new SimpleXMLElement('<?xml version="1.0"?><mobile></mobile>');
		foreach($responseData as $key=>$value) {
			$xml->addChild($key, $value);
		}
		return $xml->asXML();
	}
	
	public function getMobile($id) {

		$mobile = new Mobile();
		$rawData = $mobile->getMobile($id);

		if(empty($rawData)) {
			$statusCode = 404;
			$rawData = array('error' => 'No mobiles found!');		
		} else {
			$statusCode = 200;
		}

		$requestContentType = $_SERVER['HTTP_ACCEPT'];
		$this ->setHttpHeaders($requestContentType, $statusCode);
				
		if(strpos($requestContentType,'application/json') !== false){
			$response = $this->encodeJson($rawData);
			echo $response;
		} else if(strpos($requestContentType,'text/html') !== false){
			$response = $this->encodeHtml($rawData);
			echo $response;
		} else if(strpos($requestContentType,'application/xml') !== false){
			$response = $this->encodeXml($rawData);
			echo $response;
		}
	}
}
?>

Клиент RESTful веб-службы

Чтобы протестировать RESTful веб-сервис, вам нужно написать скрипт REST-клиента и воспользоваться им. Альтернативным решением может быть использование уже готового REST-клиента. В сети существует множество автономных REST –клиентов. Автор статьи обычно использует в качестве REST-клиента плагин для браузера Google Chrome. Расширение для Google Chrome под названием “Advance Rest Client” является достойным REST-клиентом. Вам необходимо добавить расширение и использовать его, как показано ниже. Ниже приведены скриншоты тестирования вышеупомянутого RESTful веб-сервиса.

Результат работы веб-сервиса в формате XML
Результат работы веб-сервиса в формате XML
Результат работы веб-сервиса в формате XML
Результат работы веб-сервиса в формате JSON

Скачать архив с кодом из статьи

Демо-страница

В следующих уроках автор подробнее расскажет о RESTful веб-сервисах, таких как проверка REST, REST CRUD и многое другое. Эта руководство было опубликовано 18 октября 2015 года.

Оригинал статьи: https://phppot.com/php/php-restful-web-service/

Перевод: Земсков Матвей

Прочитано 14533 раз
Мои услуги

Предлагаю следующие услуги:

  • Верстка шаблона сайта из дизайн-макета для CMS «1С-Битрикс Управление сайтом» и CMS “Joomla”
  • Создание форм различной сложности (обратная связь, анкеты и тп) для указанных CMS
  • Настройка и кастомизация компонентов и модулей для указанных CMS
  • Доработка модулей и компонентов для указанных CMS, добавление нестандартного функционала
  • Разработка лендингов (landing-pages)

По все вопросам обращайтесь через форму обратной связи

Скачать

Предлагаю вашему вниманию:

Наверх