Статьи

Как создать XML для прокси-сервера JSON в PHP

Если вы не новичок в этой области веб-разработки, вы будете знать, что «X» в «AJAX» обозначает XML — расширяемый язык разметки . Но вы, вероятно, не используете XML. Если да, то вы бы предпочли не делать этого. Все классные дети используют JSON или JSON-P : он имеет меньшую полезную нагрузку, его проще использовать и быстрее обрабатывать.

Это не значит, что XML не должен использоваться. Он существует уже давно и хорошо поддерживается большинством языков, включая JavaScript. Если вы обмениваетесь данными между различными системами и платформами, XML почти наверняка является наиболее практичным выбором. Но это не облегчает ваши усилия по написанию кода на стороне клиента.

К счастью, есть пара решений, которые позволяют вам сохранить преимущества обмена данными XML, но обеспечивают простоту JSON в JavaScript. В этой статье мы собираемся создать прокси-сервер XML в JSON на PHP.

Это звучит сложно?

Не волнуйся, это не так. По сути, прокси находится между клиентом и сервером, передавая сообщения между ними. Возможно, вы сейчас сидите за прокси-сервером — они используются в Интернете для кэширования данных и сокращения сетевого трафика. Тем не менее, они также могут обрабатывать данные; мы создадим простой прокси-сервер PHP, который переводит XML-сообщения в JSON, прежде чем они достигнут вашего кода JavaScript.

План прокси

Наша система будет:

  1. Отправьте запрос Ajax из JavaScript, который вызывает прокси PHP. Он передаст один закодированный URL как параметр GET с именем ‘url’.
  2. Прокси-сервер извлечет содержимое переданного URL-адреса в виде строки, проанализирует его как XML и преобразует его в JSON.
  3. Строка JSON будет возвращена вызывающему процессу JavaScript.

При необходимости мы могли бы создать полный REST-осведомленный прокси, который анализировал бы параметры POST, PUT и DELETE. Но это простое решение подойдет для 99% запросов Ajax и обладает рядом других преимуществ:

  • Можно вызывать веб-сервисы на чужих доменах — это не всегда возможно с помощью решения только для JavaScript.
  • При необходимости прокси-сервер может удалить ненужные данные из сообщения, чтобы уменьшить полезную нагрузку.
  • Нам потребуется меньше кода JavaScript, и он будет выполняться быстрее.

PHP

PHP обеспечивает поддержку как XML, так и JSON, поэтому создание нашего прокси, xmlproxy.php, достаточно просто.

Тем не менее, многое может пойти не так. Наш скрипт может завершиться с ошибкой, удаленный сервис может выйти из строя или возвращенный XML может быть искажен. Мы не хотим, чтобы ошибки PHP отправлялись обратно в JavaScript, поэтому мы определим обработчик исключений, чтобы скрыть их:


<?php
ini_set('display_errors', false);
set_exception_handler('ReturnError');

Теперь нам нужны две переменные для ответа ($ r) и переданного URL ($ url):

 
$r = '';
$url = (isset($_GET['url']) ? $_GET['url'] : null);

PHP библиотека cURL используется для извлечения контента из URL и передачи его в строку $ r:

 
if ($url) {

	// fetch XML
	$c = curl_init();
	curl_setopt_array($c, array(
		CURLOPT_URL => $url,
		CURLOPT_HEADER => false,
		CURLOPT_TIMEOUT => 10,
		CURLOPT_RETURNTRANSFER => true
	));
	$r = curl_exec($c);
	curl_close($c);

}

Предполагая, что что-то было возвращено, мы загрузим это как объект SimpleXMLElement и вернем сообщение в кодировке JSON:

 
if ($r) {
	// XML to JSON
	echo json_encode(new SimpleXMLElement($r));
}

Если ничего не было возвращено, мы вызовем нашу функцию обработчика исключений ReturnError (), которая выводит код ошибки в кодировке JSON:

 
else {
	// nothing returned?
	ReturnError();
}

// return JSON error flag
function ReturnError() {
	echo '{"error":true}';
}

JavaScript

Наш JavaScript должен определить удаленный URL для вызова, например

 
// example XML feed
var url = "http://domain.com/example.xml?status=123&date=2011-01-01";

URL добавляется к прокси-адресу PHP как параметр ‘url’ и передается методу open () нашего вызова XMLHttpRequest (Ajax):

 
// AJAX request
var xhr = (window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"));
xhr.onreadystatechange = XHRhandler;
xhr.open("GET", "xmlproxy.php?url=" + escape(url), true);
xhr.send(null);

Наконец, наш обработчик XMLHttpRequest onreadystatechange получает данные и преобразует строку JSON в настоящий объект JavaScript:

 
// handle response
function XHRhandler() {

	if (xhr.readyState == 4) {
	
		// parse response as JSON
		var json;
		if (JSON && JSON.parse) {
			json = JSON.parse(xhr.responseText);
		}
		else {
			eval("var json = " + xhr.responseText);
		}
		
		// do something with our returned JSON data...
		console.log(json);
		
		xhr = null;
	
	}

}

Загрузите код , распакуйте файлы на веб-сервер с поддержкой PHP и откройте proxy.html в браузере.

Замечание о кодировке атрибутов XML

XML имеет более богатый синтаксис, чем JSON, и данные могут быть закодированы как элементы или атрибуты — даже с тем же именем, например

 
<?xml version="1.0"?>
<statuses>
	<status id="one">
		<id>1</id>
	</status>
</statuses>

Функция PHP json_encode переводит атрибуты в отдельный объект @attributes, т.е.

 
{
	"status": {
		"@attributes": { "id": "one" },
		"id": "1"
	}
}

Я надеюсь, что вы найдете код полезным. Это позволяет вам иметь свой XML торт и использовать его как JSON!