Jump to content

Recommended Posts

I am using SimpleXML to analyze an XML file and output it as an HTML form. I want to give each form a unique name that was generated from the SimpleXML object. I tried hashing each object, but it always gave me the same hash. Here is an example of what I mean:

 

$xml = simplexml_load_file("calendar.xml");
foreach($xml->event as $event)
{
        $hash = MD5($event);
        echo "<form name=$hash>";
          ... fill in the rest of the form
        echo "</form>

}

 

The XML file looks like this:

 

<events startDate="2007-01-01" endDate="2007-12-31">

        <event title="Test Event 1" description="once on 10 february" startDate="2007-02-10 17:30:00" endDate="2007-02-10 19:30:00" allDay="0" eventType="once" />
        <event title="Test Event 2" description="once on 1 march" startDate="2007-03-01 09:30:00" endDate="2007-03-01 11:00:00" allDay="0" eventType="once" />
</events>   

 

So the script would output a page with 2 forms and I want them to have unique names, but the forms are ending up with the same name. Ideas on how to do this? Thanks

Link to comment
https://forums.phpfreaks.com/topic/64273-unique-object-identifier/
Share on other sites

You could try

 

foreach($xml->event as $k => $event)
{
        $hash = MD5($k . $event);
        echo "<form name=$hash>";
          ... fill in the rest of the form
        echo "</form>

}

 

That way it will throw the unique key from the event array in there aswell ;p.

spl_object_hash() will always give you the same unique hash, but only within a single run.

 

If you need an I'd that is constant across requests, why don't you simply introduce a name attribute into the root element of each XML file?

 

I've written something similar very recently (no support for selectboxes or radio/checkbox groups yet though):

 

Example Form file:

<?xml version="1.0"?>
<!DOCTYPE form PUBLIC "Backbone Form Map" "form.dtd">
<form name="login" action="/User/DoLogin" method="post" feedback="1">
<input name="user" type="text" value="" required="1" maxlen="20" description="Gebruiker"/>
<input name="pass" type="password" required="1" maxlen="20" description="Wachtwoord" />
<input name="submit" type="submit" value="Login" required="0"/>
</form>

 

DTD:

<!ELEMENT form (input+)>
<!ATTLIST form
name CDATA #REQUIRED
action CDATA #REQUIRED
method (post|get) #IMPLIED
feedback (0|1) #IMPLIED
>
<!ELEMENT input EMPTY>
<!ATTLIST input
name ID #REQUIRED
type (text|password|textarea|checkbox|radio|select|submit|reset) #REQUIRED
value CDATA #IMPLIED
required (0|1) #IMPLIED
maxlen CDATA #IMPLIED
minlen CDATA #IMPLIED
pregmatch CDATA #IMPLIED
description CDATA #IMPLIED
>

 

<?php
class Backbone_Form_DataMapper_Xml extends Backbone_Data_Mapper_Abstract {

private static $path;
private static $ext;

public static function init($path, $ext = '.form'){
	self::$path = $path;
	self::$ext = $ext;
}

public function find($name){

	$formMap = new DOMDocument();
	$formMap->validateOnParse = true;
	$file = self::$path.DIRECTORY_SEPARATOR.$name.self::$ext;
	if(!file_exists($file)){
		throw new Backbone_Form_DataMapper_Xml_Exception('Unable to load form map, file does not exist ("'.$file.'")');
	}
	$formMap->load($file);

	$formNode = $formMap->documentElement;
	if($formNode->getAttribute('name') != $name){
		throw new Backbone_Form_DataMapper_Xml_Exception('Xml- filename mismatch!');
	}
	$formObject = new Backbone_Form_Object(
		$formNode->getAttribute('name'),
		$formNode->getAttribute('action'),
		$formNode->hasAttribute('method')? $formNode->getAttribute('method') : 'post',
		$formNode->hasAttribute('feedback')? $formNode->getAttribute('feedback') : true
	);

	foreach($formMap->getElementsByTagName('input') as $input){
		$formObject->addElement(new Backbone_Form_Element(
			$input->getAttribute('name'),
			$input->getAttribute('type'),
			$input->hasAttribute('value')? $input->getAttribute('value') : null,
			$input->hasAttribute('required')? $input->getAttribute('required') : true,
			$input->hasAttribute('maxlen')? $input->getAttribute('maxlen') : null,
			$input->hasAttribute('minlen')? $input->getAttribute('minlen') : null,
			$input->hasAttribute('pregmatch')? $input->getAttribute('pregmatch') : null,
			$input->hasAttribute('description')? $input->getAttribute('description') : null
		));
	}
	return $formObject;
}
function delete(Backbone_DomainObject $object){}
function create(Backbone_DomainObject $object){}
function update(Backbone_DomainObject $object){}
function isStored($id){}
}
?>

Im going to hijack this thread and say, 448191, you should be using an Abstract Factory pattern (if you aren't already) with your approach

 

Backbone_Form_DataMapper <- Interface

Backbone_Data_Mapper_Abstract <- Factory

Backbone_Form_DataMapper_Xml <- Concrete Product.

 

So, I could make, say, Backbone_Form_DataMapper_CSV and no one would care :)

 

Just my 2c

In this case, there's no justification for Abstract Factory. Data Mappers are managed and created by a data controller (Unit of Work Controller/ad hoc Service Layer), and instantiating them requires no arguments.

 

		/**
 * Fetches Data Mapper from stack, creating one if required
 *
 * @param string|Backbone_Data_Domain_Object $domain
 * @return Backbone_Data_Mapper_Abstract
 */
public function getDataMapper($domain){
	if($domain instanceof Backbone_Data_Domain_Object){
		$mapperClass = get_class($domain).$this->mapperSuffix;
	}
		else {
		$mapperClass = $domain.$this->mapperSuffix;
	}
	if(!class_exists($mapperClass, true)) {
		throw new Backbone_Data_Controller_Exception('Mapper class "'.$domain.'" does not exist.');	

	}
	if(!isset($this->dataMappers[$mapperClass])){
		$this->dataMappers[$mapperClass] = new $mapperClass;
	}
	return $this->dataMappers[$mapperClass];
}

 

And yes, that would mean I could simply create Backbone_Form_DataMapper_CSV, without any other required changes (except for a configuration flag). At some point I might introduce an Abstract Factory, but right now I'm thinking YAGNI.

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.