Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

marcelobbt

Gerando Form em OO

Recommended Posts

Estou tentando gerar um Form usando OO, mas na hora de inserir os valores do type e value, está repetindo sempre os valores do primeiro campo informado.

 

Abaixo o código para montar o objeto:

<?php
   include 'classes/form.class.php'; //Faz um include da classe que contém o formulário
   $form = new Form; //Instancia o objeto form

   $form->setacao("index.php"); //indica a ação do form
   $form->setmetodo("post"); //indica o método que o formulário será submetido
   //Adiciona os campos do form
   $form->addcampo("login", "Login", "text", "teste");
   $form->addcampo("Senha", "Senha", "text", "");
   $form->addcampo("email", "E-mail", "text", "");
   $form->addcampo("sexo", "Masculino", "Radio", "");
   $form->addcampo("sexo", "Feminino", "Radio", "");
   $form->addcampo("datanasc", "Data de nascimento", "Text", "");
   
   $form->mostrarform();
?>

Abaixo código da classe:

<?php
   class Form {
	public $campo;
	public $tipo;
	public $valor;
	public $valor2;
	public $valor3;
	public $metodo;
	public $acao;
		
	public function getmetodo () {
		return $this->metodo;
	}
	
	public function setmetodo() {
		$this->metodo;
	}
	
	public function getacao () {
		return $this->acao;
	}
	
	public function setacao () {
		$this->acao;
	}
	
	public function addcampotext($name, $label) {
		$this->campos[$name] = $label;
	}
			
	public function addcampo($name, $label ,$type, $value) {
		$this->campo[$name] = $label;
		$this->tipo[$name] = $type;
		$this->valor[$name] = $value;
	}
	
	public function mostrarform () {
		echo "<form method=\"$this->metodo\" action=\"$this->acao\" ><br>"; //declaração do form com os métodos e ação
		//foreach para colocar os campos do form
		foreach ($this->campo as $chave => $valor ) {
			echo "<p><label for=\"$chave\">$valor:</label> <input name=\"$chave\" ";
		   foreach ($this->tipo as $chave2 => $valor2) {
			echo "type=\"$valor2\" ";
			foreach ($this->valor as $chave3 => $valor3) 
				echo "value=\"$valor3\" ></p>";
				break;
			}
			break;
		   }
		}
		echo "<input type=\"submit\" value=\"Cadastrar\"><br>"; //cria botão para submeter form
		echo "</form>"; //fecha o form
	}
	
   }
?>

 

Resultado abaixo (vermelho onde está saindo errado)

<form method="" action="" ><br>   <p><label for="login">Login:</label> <input name="login" type="text" value="teste" ></p>   <p><label for="Senha">Senha:</label> <input name="Senha" type="text" value="teste" ></p>   <p><label for="email">E-mail:</label> <input name="email" type="text" value="teste" ></p>   <p><label for="sexo">Feminino:</label> <input name="sexo" type="text" value="teste" ></p>   <p><label for="datanasc">Data de nascimento:</label> <input name="datanasc" type="text" value="teste" ></p>   <input type="submit" value="Cadastrar"><br></form>

Compartilhar este post


Link para o post
Compartilhar em outros sites

Resultado abaixo (vermelho onde está saindo errado)

 

Acho que sou daltônico :natalbiggrin:

 

Cara, se você quer trabalhar com OO, vamos usar boas práticas, esse negócio de dar echo dentro do método não é coisa que se faça, retorne uma string, já que você não possui uma classe de Response pode até dar um echo no retorno. E qual é o sentido de se usar encapsulamento se você deixa as variáveis públicas? Essa também não entendi.

 

Agora vamos ao problema, eu não sei pra que esse monte de foreach encadeado, os array's não tem os mesmos índices? Bastaria fazer algo como:

$html = "";

foreach ($this->campo as $name => $label) {
    $type = $this->tipo[$name];
    $value = $this->valor[$name];

    $html .= "<label>$label:</label>";
    $html .= "<input type=\"$type\" name=\"$name\" value=\"$value\">";
}

return $html;

E pronto! Seu método poderia estar assim.

 

Acho legal a sua atitude em querer usar OO, mas é legal também aplicar as boas práticas ou isso pode ser muito pior que programar estruturado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

As variáveis públicas foi na hora do desespero que não funcionava, aí comecei a fazer vários testes e acabei esquecendo de voltar para private.

 

Não sabia que não deveria se usar echo em um objeto. Legal essa dica.

 

Bem, vou pegar o que você me passou de código e tentar mudar minha classe. Depois retorno para dar o feedback. Obrigado!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Já que nosso amigo @cristianoolv deu a ideia, fiz um bom exemplo usando o Design Pattern Composite.

 

interface Renderizable {
    public function render();
}

interface Component extends Renderizable {
    public function setName($name);
    public function getName();
    public function setValue($value);
    public function getValue();
}

abstract class AbstractComponent implements Component {
	
    private $value;
    private $name;
	
    //getters e setters
    ...
}


class InputText extends AbstractComponent {
	
    public function render() {
        return "<input type='text' value='{$this->value}'>";
    }
}

class Label extends AbstractComponent {
	
    public function render() {
	return "<label>{$this->value}</label>";
    }
}


class Form implements Renderizable {
	
    private $components = array();
    private $method = 'post';
    private $action;
	
    public function addComponent(Component $component) {
	$this->components[] = $component;
        return $this;
    }
	
    //getters e setters
    ...
	
    private function renderComponents() {
        $html = "";
		
	foreach ($this->components as $component) {
	    $html .= $component->render();
	}
		
	return $html;
    }
	
    public function render() {
	if ($this->action == null) {
	     throw new Exception('Action não definida.');
	}
		
	$html = "<form action='{$this->action}' method='{$this->method}'>";
	$html .= $this->renderComponents();		
	$html .= "</form>";
		
	return $html;
    }
}

 

Uso:

$label = new Label();
$label->setValue('Nome');

$text = new InputText();
$text->setName('nome');

$form = new Form();
$form->addComponent($label)
     ->addComponent($text)
     ->setAction('/save.php');

echo $form->render(); //formulário renderizado

 

 

O Composite além de proporcionar uma melhor organização, te daria mais flexibilidade podendo criar vários tipos de componente entende, essa seria uma grande vantagem sendo que podemos ter textarea's por exemplo, fugindo do padrão dos input's, ou como eu fiz criando uma label que também foge do padrão, então em outras palavras poderíamos tratar casos diversos separadamente sem fugir do contexto de se criar a string do componente. :natallaugh:

Compartilhar este post


Link para o post
Compartilhar em outros sites

Já que estão entrando nesse nível, vem minha pergunta.

 

Como estou iniciando no OO acham que eu já devia partir logo para esse tal composite ou melhor antes eu firmar os conceitos de OO?

 

Não consegui nem imprimir o primeiro exemplo que o Marcelo fez.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Então eu te recomendo à ir estudar OOP. Resolvendo todos aqueles erros já seria o suficiente pra solucionar o seu problema. Depois de estudar e entender todos conceitos de OOP, coloque em prática. Aí pode-se começar a pensar em estudar as dezenas de Design Patterns e volte ao tópico e análise o meu exemplo e compare com o primeiro, certamente você terá conhecimento e entenderá as diferenças.

 

 

* Só uma correção na classe "AbstractComponent", os atributos devem ser protected.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Eu nunca usei, também não vejo necessidade, mas se fosse usar seria pra gerar formulários automaticamente com campos do banco por exemplo..

Compartilhar este post


Link para o post
Compartilhar em outros sites

Que faça com snippets HTML, mas não invente de gerar tags desse jeito. PHP foi feito para ser adicionado ao HTML, não o contrário...

Compartilhar este post


Link para o post
Compartilhar em outros sites

PHP foi feito para ser adicionado ao HTML, não o contrário...

 

Exato :yes: aliás, aproveitando..sou contra o cara fazer isso:

echo "<p>$a</p>";

ao invés disso:

<p><?php echo $a ?></p>

 

Imprimir HTML..Bom, se parar pra pensar realmente não é diferente de se usar objetos para gerar HTML :sleep: então te dou razão, melhor não misturar. ^_^

Compartilhar este post


Link para o post
Compartilhar em outros sites

Apenas argumentando, o que você me diz sobre alguns Framework's (sem citar um) que criam esses objetos que geram HTML??

 

(MINHA OPINIÃO) O PHP adicionou os conceitos de OO, porém não é preparado e não sei se um dia será, para trabalhar de maneira correta com OO, no fim das contas eu acho que essa seria só uma forma de "organizar melhor as coisas".

 

Esclarecendo também que eu apenas dei uma ideia e corrigi o problema do autor.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Eu acho até legal quando não é doloroso e aumenta a elegância e a simplicidade da view. Exemplos bons disso são o Rails, o Django e o Laravel, mas Symfony, Cake, Zend, etc. implementam de forma que complica o código e só faz aumentar a complexidade.

Compartilhar este post


Link para o post
Compartilhar em outros sites

A galera agora me desmotivou... :upset:

 

Na verdade eu estava pesquisando na web de como fazer o cadastro num bd após receber os dados de um form. Então encontrei um exemplo que criava o form. Me pareceu bem prático, mas na hora que tentei dar uma incrementada nele (gerar outros tipos de campo), me compliquei com o código e vim pedir uma ajuda.

 

Mas acho que vou seguir o conselho da maioria e fazer OO apenas na parte do cadastro e fazer o form manualmente. De qualquer forma já valeu para aprender outras coisas. Obrigado galera!

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.