XML Serialize

  • Автор темы Автор темы Cloun
  • Дата начала Дата начала

Cloun

Новичок
XML Serialize

Всем привет. Вот совсем недавно занялся php и, естественно, меня это круто увлекло.
Вопрос: есть ли методы для сериализации объекто в xml формат (как это распространено в C#)??
Ответ, даже если не было - ничего страшного, я их написал =) Мда... ну надо же мне как-то самовыражаться. Написал такие удобные классы, и что? Надо похвастаться! =)
Если кому интересно - выложу. Если есть уже подобное - дайте глянуть!
 
да очень интересно посмотреть
меня например интересует вопрос сериализации референсов
 
Хм... на счет ссылок ничего сказать. В моем случае скорее всего в xml запишется значение объекта на которого ссылается ссылка, и при обратном действии, ссылка превратится в котэйнер этого объекта.
Честно скажу - не пробовал. Код ниже.

-~{}~ 12.09.05 18:11:

PHP:
<?php

class XmlSerialize
{
	var $m_iDepth;
	var $m_oResult;
	var $m_oCur;
	var $m_oChild;
	//это должен быть массив от depth
	var $m_oParent;
	var $m_parser;

	function ObjToXml($obj, $attrs = array(), $depth = 0)
	{
		$varname = get_class($obj);
		if(empty($varname))
			$varname = gettype($obj);
		$ret = str_repeat("\x9", $depth)."<$varname";
		foreach($attrs as $key => $value)
			$ret .= " $key=\"$value\"";
		$ret .= ">\n";
		$depth++;
		foreach($obj as $key => $value)
		{
			if(gettype($value) == "object" || gettype($value) == "array")
			{
				if($varname == "array")
					$ret .= XmlSerialize::ObjToXml($value, array("id" => $key), $depth);
				else
					$ret .= XmlSerialize::ObjToXml($value, array("name" => $key), $depth);
			}
			else
			{
				$type = gettype($value);
				$ret .= str_repeat("\x9", $depth)."<$key>$value</$key>\n";
			}
		}
		$depth--;
		$ret .= str_repeat("\x9", $depth)."</$varname>\n";
		return $ret;
	}

	function ObjToXmlFile($fname, $obj, $attrs = array(), $dept = 0, $head_xml = null, $tail_xml = null)
	{
		$fp = fopen($fname, "w");
		fwrite($fp, "<?xml version=\"1.0\" ?>\n");
		if($head_xml != null)
			fwrite($fp, $head_xml);
		fwrite($fp, XmlSerialize::ObjToXml($obj, $attrs, $dept));
		if($tail_xml != null)
			fwrite($fp, $tail_xml);
		fclose($fp);
	}

	function XmlFileToObj($fname)
	{
		if(empty($this))
			return null;
		$fp = fopen($fname, "r");
		$this->m_parser = xml_parser_create();
		xml_set_object($this->m_parser, $this);
		xml_set_element_handler($this->m_parser, "start_tag", "end_tag");
		xml_set_character_data_handler($this->m_parser, "body_tag");
		xml_parser_set_option($this->m_parser, XML_OPTION_CASE_FOLDING, 0);
		xml_parser_set_option($this->m_parser, XML_OPTION_SKIP_WHITE, 1);

		$this->m_iDepth = 0;
		$this->m_oResult = null;
		$this->m_oCur = &$this->m_oResult;
		while ($data = fread($fp, 0x1000))
		{
			if (!xml_parse($this->m_parser, $data, feof($fp)))
			{
				die(sprintf("XML error: %s at line %d",
        			xml_error_string(xml_get_error_code($this->m_parser)),
					xml_get_current_line_number($this->m_parser)));
			}
		}
		xml_parser_free($this->m_parser);
		fclose($fp);
		return $this->m_oResult;
	}

	//XML methods
	function start_tag($parser, $name, $attrs)
	{
		switch($name)
		{
		case "ARRAY":
		case "array":
			if(!empty($attrs) && array_key_exists("name", $attrs))
			{
				$this->parser[$this->m_iDepth] = &$this->m_oCur;
				$this->m_oCur = &$this->m_oCur->$attrs["name"];
			}
			else
				$this->m_oCur = array();
			break;
		default:
			if(!empty($attrs) && array_key_exists("id", $attrs))
			{
				$this->m_oCur[$attrs["id"]] = new $name;
				$this->m_oParent[$this->m_iDepth] = &$this->m_oCur;
				$this->m_oCur = &$this->m_oCur[$attrs["id"]];
			}
			else
			{
				if($this->m_iDepth == 0)
					$this->m_oCur = new $name;
				else
				{
					$this->m_oParent[$this->m_iDepth] = &$this->m_oCur;
					$this->m_oCur = &$this->m_oCur->$name;
				}
			}
			break;
		}
		$this->m_iDepth++;
	}

	function body_tag($parser, $data)
	{
		if(trim($data) != "")
			$this->m_oCur = $data;
	}

	function end_tag($parser, $name)
	{
		$this->m_iDepth--;
		$this->m_oCur = &$this->m_oParent[$this->m_iDepth];
	}
};

?>

-~{}~ 12.09.05 18:16:

Поясняю:
создаем класс, к примеру CWeapon
PHP:
class CEffect
{
	var $sCharacteristics;
	var $iValue;
}
class CWeapon
{
	var $sName;
	var $iWeight;
	var $sDescription;
	var $sImageUrl;
	var $oEffects;
}

$a[] = new CWeapon;
$a[] = new CWeapon;
//.запоняем значениями объекты
$a[0]->oEffects[] = new CEffect;
//...
//потом создаем экземпляр класса
$Xml = new  XmlSerialize;
$Xml->ObjToXmlFile("weapon.xml", $a);
Теперь у нас получается достаточно удобный для чтения xml файл.
Обратно еще проще - указываем файл, получаем объект. В данном случае массив из объектов.

-~{}~ 12.09.05 18:22:

Приводить результат тут не имеет смысла, т.к. он выглядит не так красиво как на самом деле =(

-~{}~ 12.09.05 18:34:

Я этот код дописал только сегодня. Поэтому тут куча багов. Кто чего заметить - отпишитесь сюда, плз. Буду всем замечаниям очень благодарен.
 
ок, вопрос в практическом применении?
скажем в C# это более или менее оправдано, но тоже далеко не быстро реализовано... а в PHP ?
 
Автор оригинала: slach
ок, вопрос в практическом применении?
скажем в C# это более или менее оправдано, но тоже далеко не быстро реализовано... а в PHP ?
Хм... я не очень понимаю смысл вопроса... Что такое xml? Текстовый файл. Древовидная структура. И ничего большего. Никаких сложных алгоритмов.
Т.е. если говорить о производительности процесса парсинга xml файла - то это такие же затраты как, например, разборка html документа броузером. Или разборка любого другого текстового файла.
Преобразование тектовых данных в объеткы - понятия не имею сколько нужно ресурсов php модулю, чтоб добавить в ассоциативный масив эллемент. На мой взгляд весь php построен на таких массивах (поправте меня, если я не прав).
В заключении скажу, что на мой взгляд этот код достаточно обычен, и не требует от сервера ничего такого.
Если вам нужно хранить данные в каких-то внешних источниках, и это не БД (по каким либо причинам). То xml это хорошее решение. ИМХО.

Еще добавлю: когда при программировании у вас встает задача общения с пользователем, то вы выбираете такое решение, которое будет легко реализовать (например, командная строка) и удобно будет пользователю (например оконный интерфэйс). В данном случа речь идет не о юзерах, а о админах, но xml - это консенсус. Его легко понимает фдмин, и так же его легко использовать в программе.
 
не понял.
а зачем админу понимать состояние объекта в программе?

А смысл вопроса в том, что в пхп есть СТАНДАРТНЫЙ сериалайз.
и сериализация/десериализация делается в одну строчку. без этих дудовых страданий.
 
Насколько я понял, у него какая-то странная метода.
сериализует объект (причём объект для него - это именно исключительно хранилище данных), затем программа ОБМЕНИВАЕТСЯ(!!!) своим объектом с некой третьей стороной, получает его взад, и далее продолжает работать.

То есть.
У него реализован банальнейший механизм - обмен xml-данными. единственная, собственно, задача, для которой xml и нужен.
НО. сделано это через сериализацию объектов.
а не по-человечески, когда объект импортирует и экспортирует данные, если ему надо с кем-то поменяться. с помощью пары методов.
импортирует ДАННЫЕ. а не целиком своё состояние.
но для него-то это одно и то же! поскольку объект для него - это всего лишь структура ХРАНЕНИЯ ДАНЫХ.

в общем, судя по всему, у него очень простая система.
игрушка в солдатики.
данные игрушка хранит в XML
для работы, соответственно, она их хавает и превращает в массив, с которым и работает
вот только сделано это натуральным российским методом - гланды удаляются исключительно через задний проход =)
 
кстати, а в чем глубинный смысл такой сериализации?
 
Чтоб не вводить в заблуждение читабщих данный топик хочу добавить что все что написал Фанат в сообщении 15.09.05 не верная информация. Ничего такого на сайте не делается.
 
При том, что есть широко используемые интерфейсы для сериализации, которые являются результатом труда десятков, если не сотен специалистов и многие тысячи людей их используют.

Поэтому сначала желательно разобраться с сериализацией в общем, а уже потом рассматривать её частный! случай: сериализацию объектов в Xml.

И надо тщательно документировать свой код! Хотя бы public методы.
 
Спасибо, Cloun, за хорошую идею! Мне Ваш код пригодился, только поменял expat на dom.
А для успокоения по поводу местных устоев общества прочтите где-нибудь А.А. Розова "Хомоэволюция. Битва с дураками."
 
Спасибо =)
Спасибо и за критику, и за поддержку =)
На самом деле я уже давно задокументировал код, и немного его переделал. Опять же если интересно - могу предъявить.

-~{}~ 22.09.05 18:53:

H@rdDrive
А если менять на dom, то под линухом работать будет??
 
Cloun
Зависит не от операционной системы, а от установленных в php4 расширений (dom_xml) или наличия php5 (dom встроен в ядро, стандартное именование методов).
С помощью Вашего кода удобно сохранять и считывать конфигурацию с удобной возможностью ручной корректировки (чего не скажешь о стандартной сериализации).
 
H@rdDrive
Именно для таких целей и задумывалось. Единственное - это то что не совсем коректный xml получается. После сдачи экзаменов я код подправлю. И перевелу на dom_xml.
Про dom, я думал, что это фитча от microsoft...

PS: Вопрос не по теме: а php5 стоит ставить себе? Или он еще сыроват? Дело в том что сервер у меня стоит пустой, и пока я не закончу этот сайт, он не нужен. И имеет ли смысл писать сайт под 4, когда не за горами (???) релиз пятерки? Или он за горами?
 
Сверху