Ir para conteúdo

POWERED BY:

Arquivado

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

BlackShadow

Como estruturar aplicação em OOP

Recommended Posts

Boa tarde gente,

 

Estou numa dúvida cruel e gostaria de saber opiniões vossas quanto a isto:

Sou iniciante em PHP Orientado a objetos, sempre trabalhei estruturado, e agora em fase de migração para OO estou em dúvida sobre como montar a estrutura lógica e física de arquivos/código.

 

A minha ideia inicial era ter uma classe específica para MySQL e daí extender outras apartir desta (exemplo: Usuario extends MySQL).

 

Já tenho uma classe MySQL com a qual me sinto confortável e daí gostaria de saber qual a vossa opinião quanto a alguns aspectos:

 

1) Criar para cada módulo uma única classe extendida do mysql contendo as operações básicas desse módulo ? (exemplo Usuario extends msql e dentro desta classe os métodos cadastraUser(), insereUser() ... etc)

 

2) Qual a estrutura que usam em questão de arquivos? Inicialmente imaginei algo como assim:

 

- www

-- libs (bibliotecas basicas de classes)

-- imagens

-- js

- index.php

 

Apesar do ponto 2 ser mais um item de curiosidade, o ponto 1 é o que mais me complica, pois está complicado conseguir a abstração ainda total para organizar o código, mas gostaria de saber como vocês geralmente desenvolvem sistemas e organizam o vosso código! Sei que a primeira resposta poderia ser: "cada um organiza como gosta e se sente mais confortável", mas por estar tão perdido é que vos pergunto pois pode ser que encontre uma estrutura que me agrade!

 

PS: não vou usar para já smarty ou qualquer sistema de templates

 

Muito obrigado desde já pelos esclarecimentos que possam dar http://forum.imasters.com.br/public/style_emoticons/default/thumbsup.gif

Compartilhar este post


Link para o post
Compartilhar em outros sites

Interessanta kra, eu tb tenho esse intuito mas só futuramente, como ja peguei o PHP antes do 5, terei um pouco de problemas... http://forum.imasters.com.br/public/style_emoticons/default/blush.gif

 

Quanto ao seu problemas é algo muito comum, pois não existe banco de dados orientado a objetos, ai sim complica. O q se faz é utilizar um Mapeamento Objeto Relacional no seu banco de dados, coisa muito comum com os programadores Java, é o tal do Hibernate que faz td pra você.

 

Logo, recomendo q você estuda mais um pouco sobre esse mapeamente, pois isso q deve ser feito no caso da orientação a objetos. Essa classe Mysql não sei se vai recolver :wacko:

 

abraço

Compartilhar este post


Link para o post
Compartilhar em outros sites

Eu organizo cada classe em um arquivo pois facilita na hora de fazer atualizações, principalmente usando controle de versões.

Eu estava organizando as classes em pastas separadas e importava através de uma função que tinha criado, porém observei que muita gente utiliza por padrão o __autoload para carregar as classes.

 

É bem simples, se cria uma função:

http://br.php.net/manual/pt_BR/function.spl-autoload.php

 

function __autoload($classname)
{
	 require("diretorio/{$classname}");
}

É bem prático, para cada objeto que você instanciar será chamada a função e incluida a classe. O legal é que se chamar a mesma classe 2x ele não fará o require novamente.

Porém tem que deixar todas as classes em um mesmo diretório.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Legal, a primeira dúvida é interessante.

A classe Usuario deve representar exatamente um Usuario. Um usuario tem nome, idade, login, senha etc, mas o usuario nao "insereUsuario", isso não é uma ação dele, quem faria isso, seria uma outra classe, o famoso DAO.

Mais em: http://www.javafree.org/content/view.jf?idContent=183 (em java, mas o conceito é que interessa aqui)

 

Att,

Guilherme Oenning.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Legal, a primeira dúvida é interessante.

A classe Usuario deve representar exatamente um Usuario. Um usuario tem nome, idade, login, senha etc, mas o usuario nao "insereUsuario", isso não é uma ação dele, quem faria isso, seria uma outra classe, o famoso DAO.

Mais em: http://www.javafree.org/content/view.jf?idContent=183 (em java, mas o conceito é que interessa aqui)

 

Att,

Guilherme Oenning.

 

Muito interessante! Gostei dessa abordagem e organização lógica do código. Teria como exemplificar algum caso de uso da mesma ?

 

por exemplo assumindo essa mesma classe Usuario?

 

muito obrigado de novo a todos os que colaboraram e ajudaram até agora

Compartilhar este post


Link para o post
Compartilhar em outros sites

Usuario nunca deve extender de MSSQL.

Uma coisa é usuario, outra um gerenciador de dados.

Oenning, de acordo com o que você disse sobre 'usuário não cria usuário', e aproveitando a oportunidade, veja o que eu costumo fazer:

 

// criando um novo
$NovoUsuario = new TUser;
$NovoUsuario->setNome( 'João' );
$NovoUsuario->etc, etc, etc.
$NovoUsuario->persist( ); // aqui a instância é persistida no Banco, um novo usuário foi criado.

// manipulando um existente
$VelhoUsuario = new TUser( 2 ); // o identificador da instancia
$VelhoUsuario->getNome(  ); // imprime o nome do usuario
$VelhoUsuario->setNome( 'Rogério' ); //
$VelhoUsuario->persist( ); // persiste
Sem fugir do conceito. Espero que esta abordagem seja útil.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Usuario nunca deve extender de MSSQL.

Uma coisa é usuario, outra um gerenciador de dados.

Oenning, de acordo com o que você disse sobre 'usuário não cria usuário', veja o que eu costumo fazer:

 

// criando um novo
$NovoUsuario = new TUser;
$NovoUsuario->setNome( 'João' );
$NovoUsuario->etc, etc, etc.
$NovoUsuario->persist( ); // aqui a instância é persistida no Banco, um novo usuário foi criado.

// manipulando um existente
$VelhoUsuario = new TUser( 2 ); // o identificador da instancia
$VelhoUsuario->getNome(  ); // imprime o nome do usuario
$VelhoUsuario->setNome( 'Rogério' ); //
$VelhoUsuario->persist( ); // persiste
Sem fugir do conceito. Espero que esta abordagem seja útil.

Sem dúvida que é útil. Creio que já cheguei a um modelo que me sinto confortável e que me parece bem lógico. Encontrei 2 artigos muito interessantes sobre PDO que me esclareceram imenso além das vossas participações.

Para quem possa estar com uma dúvida semelhante à minha aqui ficam os 2 links

 

PHP Data Object: ConnectionFactory

DAO – Data Access Object

 

Um grande obrigado a todos os que participaram e ajudaram a esclarecer as dúvidas! http://forum.imasters.com.br/public/style_emoticons/default/thumbsup.gif Este tópico pode ser marcado como resolvido!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Gente peço desculpa por "reabrir" este post mas surgiu-me aqui um problema. Ao executar o código dos 2 links que mencionei

 

PHP Data Object: ConnectionFactory

DAO – Data Access Object

 

apareceu-me um erro que acredito que seja de escopo.

 

Fatal error: Call to a member function prepare() on a non-object in C:\xampp\htdocs\ado\AgendaPDO.class.php on line 25

 

Alguém me poderá dar uma luz sobre onde possa estar o erro?

 

Estou usando no arquivo de persistencia:

public function getConnection()
	{	
		try
		{				
			$this->con = new PDO($this->dbType.":host=".$this->host.";dbname=".$this->db, $this->user, $this->senha,array( PDO::ATTR_PERSISTENT => $this->persistent ) );
					
			return $this->con;			
				
		}
		catch ( PDOException $ex )
		{ 
			echo "Erro: ".$ex->getMessage(); 
		}	
	}

e na classe ADO

 

public function Insere( $agenda )
	{
		try{

			$stmt = $this->conex->con->prepare("INSERT INTO agenda (id, nome, email, telefone) VALUES (?, ?, ?, ?)");
	
			$stmt->bindValue(1, $agenda->getId() );
			$stmt->bindValue(2, $agenda->getNome() );
			$stmt->bindValue(3, $agenda->getEmail() );
			$stmt->bindValue(4, $agenda->getTelefone() );
	
			$stmt->execute();
	
			$this->conex = null;

		}
		catch ( PDOException $ex )
		{ 
		 	echo "Erro: ".$ex->getMessage(); 
		}
	}

 

Mais uma vez obrigado por tudo, mas nestes primeiros passos com o "amigo" OO toda a ajuda é bem-vinda!!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Isto acontece quando você tenta executar um método de algo que não é um objeto, por exemplo:

 

$User = 'Márcio';

echo $User->nome;

Ou seja, o objeto não foi corretamente criado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Entendi, mas ainda não consegui achar o erro .... vou detalhar um pouco mais pode ser que alguem ai consiga descobrir onde está a falha:

 

PDOConnection.class.php

class PDOConnection
{

	public $con = null;
	public $dbType = "mysql";	
	
	public $host 	= "localhost";	
	public $user 	= "root";	
	public $senha 	= "";	
	public $db 		= "teste";

	public $persistent = false;

	public function PDOConnection( $persistent=false )
	{	
		if( $persistent != false)
		{ 
			$this->persistent = true; 
		}	
	}
	
	public function getConnection()
	{	
		try
		{				
			$this->con = new PDO($this->dbType.":host=".$this->host.";dbname=".$this->db, $this->user, $this->senha,array( PDO::ATTR_PERSISTENT => $this->persistent ) );
		
			return $this->con;				
		}
		catch ( PDOException $ex )
		{ 
			echo "Erro: ".$ex->getMessage(); 
		}	
	}

AgendaPDO.class.php

class AgendaPDO extends PDOConnection 
{	

	public $conex = null;
	
	public function AgendaPDO()
	{
		$this->conex = PDOConnection::getConnection();
	}

	public function Insere( $agenda )
	{
		try{
			$stmt = $this->conex->con->prepare("INSERT INTO agenda (id, nome, email, telefone) VALUES (?, ?, ?, ?)");
	
			$stmt->bindValue(1, $agenda->getId() );
			$stmt->bindValue(2, $agenda->getNome() );
			$stmt->bindValue(3, $agenda->getEmail() );
			$stmt->bindValue(4, $agenda->getTelefone() );

			$stmt->execute();

			$this->conex = null;

		}
		catch ( PDOException $ex )
		{ 
		 	echo "Erro: ".$ex->getMessage(); 
		}
	}

Agenda.class.php

class Agenda
{
	public $id;
	public $nome;
	public $email;
	public $telefone;

	public function Agenda()
	{
	
	}
	
	############## CONJUNTO DE SET'S
	public function setId( $id )
	{
		$this->id = $id;
	}
	
	public function setNome( $nome )
	{
		$this->nome = $nome;
	}
	
	public function setEmail( $email )
	{
		$this->email = $email;
	}
	
	public function setTelefone( $telefone )
	{
		$this->telefone = $telefone;
	}
	
	public function getId()
	{
		return $this->id;
	}
	
	public function getNome()
	{
		return $this->nome;
	}
	
	public function getEmail()
	{
		return $this->email;
	}
	
	public function getTelefone()
	{
		return $this->telefone;
	}
}

teste.php

@require("PDOConnection.class.php");
@require("AgendaPDO.class.php");
@require("Agenda.class.php");


$agenda = new Agenda();

$agenda->setNome("eu");
$agenda->setEmail("eu@gmail.com");
$agenda->setTelefone("5555 5555");

$PDO = new AgendaPDO();
$PDO->Insere($agenda);

Compartilhar este post


Link para o post
Compartilhar em outros sites

Vou analisar seu código, mas antes retire todos os arrobas e rode pra ver se dá algum erro.

Compartilhar este post


Link para o post
Compartilhar em outros sites

O erro está sendo causado porque a classe PDO não foi encontrada. Este erro não apareceu porque o servidor que você está usando para desenvolver não está configurado para reportar todos os erros.

Se você colocar no início do código:

ini_set('display_errors', 'On');
error_reporting(E_ALL);
vai ver o erro da PDO não encontrada.

Desenvolver sem a reportagem de erros é muito complicado, porque, como neste caso, você não encontra a raiz do problema, mas apenas suas consequências.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Habilitou a reportagem de todos os erros como eu disse acima ?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Notice: Undefined property: PDO::$con in C:\xampp\htdocs\ado\AgendaPDO.class.php on line 25

 

Fatal error: Call to a member function prepare() on a non-object in C:\xampp\htdocs\ado\AgendaPDO.class.php on line 25

Compartilhar este post


Link para o post
Compartilhar em outros sites

Agora sim.

 

Veja na AgendaPDO:

public function AgendaPDO()
{
	$this->conex = PDOConnection::getConnection();
}

Você chama um método estático, e veja o que tem no método:

$this->con = new PDO($thi ...

Você não pode usar $this em métodos estáticos.

Só não deu erro na construção do código porque o método não foi explicitamente declarado como estático.

Coloque static na assinatura do método para ver o que acontece, assim:

public static function getConnection()
Sempre que for utilizar métodos estáticos, defina isso na assinatura do mesmo, assim você evita este tipo de problema, e garante que o mesmo estará sendo utilizado da forma adequada.

Compartilhar este post


Link para o post
Compartilhar em outros sites

entendi. Fiz a alteração que falou e daí agora no PDConnection.php recebi o seguinte erro

 

Fatal error: Using $this when not in object context in C:\xampp\htdocs\ado\PDOConnection.class.php on line 40

 

correspondente à seguinte linha:

 

$this->con = new PDO($this->dbType.":host=".$this->host.";dbname=".$this->db, $this->user, $this->senha,array( PDO::ATTR_PERSISTENT => $this->persistent ) );

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não não...

Você precisa rever a logica da sua classe, definir se o método em questão é estático ou não. Se for estático, não faz sentido você usar $this, que só existe em um objeto.

Pergunte a si mesmo: faz sentido instanciar a classe para obter o resultado deste método?

Veja um exemplo de método estático:

 

class Validador
{
	public static function validaCPF( $string )
	{
		//
	}
	
	public static function validaRG( $string )
	{
		//
	}
	
	public static function validaData( $string )
	{
		//
	}
}

Aí por exemplo, eu não preciso criar um objeto pra fazer uma validação. Não faz sentido.

Outro lugar onde você usa métodos estáticos é em aplicação do pattern singleton ( o 'getInstancia()' ), alguns factory´s, etc.

Compartilhar este post


Link para o post
Compartilhar em outros sites

como eu falei eu baseei-me naqueles 2 links lá , carreguei o banco de dados e estou testando para estudar aquela maneira de organizar o código.

 

A meu ver o metodo getConnection() uma vez que está inserido numa classe da qual derivam outras classes "filhas" acho que poderia ser estático, pois nao haverá nenhuma reutilização/alteração do mesmo. Posso estar pensando errado, mas o que você acha relativamente ao código apresentado?

 

http://www.revistaphp.com.br/artigo.php?id=132

http://www.revistaphp.com.br/artigo.php?id=133

 

(Relembro que me baseei nos 2 links acima)

 

Mais uma coisa: obrigadíssimo pela paciência Marcio! Você está incansável e ajudando mto!

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.