XML Serialize

Cloun

Новичок
XML Serialize

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

neko

tеam neko
да очень интересно посмотреть
меня например интересует вопрос сериализации референсов
 

Cloun

Новичок
Хм... на счет ссылок ничего сказать. В моем случае скорее всего в 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:

Я этот код дописал только сегодня. Поэтому тут куча багов. Кто чего заметить - отпишитесь сюда, плз. Буду всем замечаниям очень благодарен.
 

slach

Новичок
ок, вопрос в практическом применении?
скажем в C# это более или менее оправдано, но тоже далеко не быстро реализовано... а в PHP ?
 

Cloun

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

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

Фанат

oncle terrible
Команда форума
не понял.
а зачем админу понимать состояние объекта в программе?

А смысл вопроса в том, что в пхп есть СТАНДАРТНЫЙ сериалайз.
и сериализация/десериализация делается в одну строчку. без этих дудовых страданий.
 

Фанат

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

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

в общем, судя по всему, у него очень простая система.
игрушка в солдатики.
данные игрушка хранит в XML
для работы, соответственно, она их хавает и превращает в массив, с которым и работает
вот только сделано это натуральным российским методом - гланды удаляются исключительно через задний проход =)
 

HEm

Сетевой бобер
кстати, а в чем глубинный смысл такой сериализации?
 

Cloun

Новичок
Чтоб не вводить в заблуждение читабщих данный топик хочу добавить что все что написал Фанат в сообщении 15.09.05 не верная информация. Ничего такого на сайте не делается.
 

AlexVN

Новичок
При том, что есть широко используемые интерфейсы для сериализации, которые являются результатом труда десятков, если не сотен специалистов и многие тысячи людей их используют.

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

И надо тщательно документировать свой код! Хотя бы public методы.
 

H@rdDrive

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

Cloun

Новичок
Спасибо =)
Спасибо и за критику, и за поддержку =)
На самом деле я уже давно задокументировал код, и немного его переделал. Опять же если интересно - могу предъявить.

-~{}~ 22.09.05 18:53:

H@rdDrive
А если менять на dom, то под линухом работать будет??
 

H@rdDrive

Новичок
Cloun
Зависит не от операционной системы, а от установленных в php4 расширений (dom_xml) или наличия php5 (dom встроен в ядро, стандартное именование методов).
С помощью Вашего кода удобно сохранять и считывать конфигурацию с удобной возможностью ручной корректировки (чего не скажешь о стандартной сериализации).
 

Cloun

Новичок
H@rdDrive
Именно для таких целей и задумывалось. Единственное - это то что не совсем коректный xml получается. После сдачи экзаменов я код подправлю. И перевелу на dom_xml.
Про dom, я думал, что это фитча от microsoft...

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