Ir para conteúdo

POWERED BY:

Arquivado

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

Alexsandro XPT

Implementando o padrão Singleton com PHP5

Recommended Posts

Estava lendo o artigo http://www.phpbrasil.com/articles/article.php/id/1242 e la dizia:

 

Temos uma classe de conexão com o banco de dados, o construtor dessa classe realiza a conexão e seleciona o bd.

Imagine que iremos utilizar este objeto para diversas consultas diferentes. Cada consulta abrirá uma conexão com o mysql, o que irá sobrecarregá-lo caso muitos usuários acessem a página simultamenamente.

 

 

Dai penso eu:

Que diabos está falando?

 

Ele está dizendo que se 20 browsers abrir uma pagina o servidor so vai abrir uma conexão com o DB?

 

Mas como isto é possível se cada pedido HTTP é independente?

 

Alguem ta afim de depater o assunto?

 

 

Obrigado

Compartilhar este post


Link para o post
Compartilhar em outros sites

Eu não estou usando esse padrão (inclusive preciso estudar um pouco e começar a usar), mas, ao que me parece, ele quis dizer que só será aberta uma conexão por navegador.

 

Por exemplo, se instanciarmos cinco classes num script, sendo que todas usam banco de dados, haverá cinco conexões por navegador. Com Singleton, só haverá uma conexão por browser.

 

Acho que é isso. :rolleyes:

Compartilhar este post


Link para o post
Compartilhar em outros sites

Isso mesmo cada pedido HTTP, mas na hora dele abrir a conexao ele vai verificar se jah existir ele usa a que jah existe não cria uma nova...tendeu?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pelo que o Beraldo disse faz sentido:

Por exemplo, se instanciarmos cinco classes num script, sendo que todas usam banco de dados, haverá cinco conexões por navegador. Com Singleton, só haverá uma conexão por browser.

 

Até porque tambem da pra fazer qualquer verificação em um script.

 

 

 

Mas pelo que você disse, está dificil de imaginar pois veja bem o que o manual fala:

 

Singleton

O padrão Singleton se aplica em situações em que é preciso haver uma só instância de uma classe. O exemplo mais comum é uma conexão com um banco de dados. Implementar esse padrão permite ao programador fazer essa instância única ser facilmente acessível por muitos outros objetos.

 

Nao fala de multiplos pedidos HTTP e nem fala do Scripting Engine analiza o servidor HTTP.

É algo meio obscuro de se pensar que o PHP vai verificar se algum script tem o resorce de alguma conexão(ou uma classe qualquer) pra compartilhar pra apontar pra outro script.

 

Por isto está me cheirando que é pra um unico script mesmo sendo assim 20 pedidos HTTP de um script será 20 instancia SIM de uma classe Singleton.

 

 

Alguem bate o pé e diz o contrario?

 

Se esta conversa render podemos tirar a prova assim:

 

class Exemplo
{
	// Guarda uma instância da classe
	static private $instance;
	private $tempo;
	
	// Um construtor privado
	private function __construct() 
	{
		echo 'Sou um construtor';
		$this->tempo = microtime();
	}

	// O método singleton 
	static public function singleton() 
	{
		if (!isset(self::$instance)) {
			$c = __CLASS__;
			self::$instance = new $c;
		}

		return self::$instance;
	}
	
}

Se tivemos q fazer o teste falta implentar o script. :P

 

Mas valew pela atençao ;)

 

Isso mesmo cada pedido HTTP, mas na hora dele abrir a conexao ele vai verificar se jah existir ele usa a que jah existe não cria uma nova...tendeu?

Compartilhar este post


Link para o post
Compartilhar em outros sites

pelo que eu entendi não é uma conexão unica pra um navegador, mas sim uma conexão unica por objeto, ou seja, vai evitar de voce fazer isso

 

$query1 = new db;
$query2 = new db;

porque ao fazer isso cada objeto tem sua propria conexão.

 

neste caso voce iria implementar a classe assim:

 

$query1 = db::singleton();
$query2 = db::singleton();

de forma que os dois objetos ($query1 e $query2) usariam a mesma conexão.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Concordo..

Entao posso afirmar que uma classe sem Singleton:

20 pedidos contem 20 objetos no mínimo que possui 20 instância no MÍNIMO.

Sendo uma com Singleton seria:

20 pedidos contem 20 objetos no mínimo que possui 20 instância no MÁXIMO.

 

Esta é minha conclusão até quem prove o contrario. :P

 

Valew pessoal.

 

 

pelo que eu entendi não é uma conexão unica pra um navegador, mas sim uma conexão unica por objeto, ou seja, vai evitar de voce fazer isso

 

$query1 = new db;
$query2 = new db;

porque ao fazer isso cada objeto tem sua propria conexão.

 

neste caso voce iria implementar a classe assim:

 

$query1 = db::singleton();
$query2 = db::singleton();

de forma que os dois objetos ($query1 e $query2) usariam a mesma conexão.

Compartilhar este post


Link para o post
Compartilhar em outros sites

você disse:

com Singleton:

20 pedidos, 20 objetos, 1 instância

 

1 instancia??? nos acabamos de tirar aprova acima.

 

Nao tem como em 20 pedidos HTTP termos 1 so instância. nos provamos q temos apenas 1 instância por pagina que resulta 1 x 20 pedidos = 20 instancias nos 20 clientes( Pedidos HTTP, Browser )

 

 

1 instancia nao pode misturar com uma outra sessão nao, imagina, isto pode dar muitos problemas de logica :blink:

 

 

Se eu tenho um instância de uma classe Singleton e mudo uma propriedade pra TRUE.

 

E você entra na mesma pagina e o server compartilhar a instancia do meu objeto você vai pega-la com a propriedade TRUE, olha so que zona.

Entao eu continuo dizendo:

 

Sem Singleton:

20 pedidos contem 20 objetos no mínimo que possui 20 instância no MÍNIMO.

Com Singleton:

20 pedidos contem 20 objetos no mínimo que possui 20 instância no MÁXIMO.

 

 

Falow ;)

Obrigado pela atenção.

 

 

sem Singleton:

20 pedidos, 20 objetos, 20 instâncias diferentes

 

com Singleton:

20 pedidos, 20 objetos, 1 instância

Compartilhar este post


Link para o post
Compartilhar em outros sites

Amigão. o que eu quis dizer foi o seguinte:

 

imagina uma pagina aonde voce tenha 20 consultas ao banco de dados:

 

$consulta1 = new $db;

$consulta1->query("alguma query");

 

$consulta2 = new $db;

$consulta2->query("alguma query");

 

$consulta3 = new $db;

$consulta3->query("alguma query");

 

$consulta4 = new $db;

$consulta4->query("alguma query");

 

$consulta5 = new $db;

$consulta5->query("alguma query");

 

...

 

$consulta20 = new $db;

$consulta20->query("alguma query");

 

 

 

 

 

Neste caso teriamos 20 instancias diferentes da mesma classe, ou seja, 20 conexões diferentes ao banco de dados.

 

o que o singleton faz. simplesmente resume as 20 instancias ao mesmo objeto, ou seja, vão continuar sendo objetos diferentes mas usando a mesma conexão.

 

entendeu agora???

 

 

agora, é evidente que a cada solicitação http vai haver um reload de tudo e com isso tudo será instanciado novamente.

 

 

 

 

 

você disse:

com Singleton:

20 pedidos, 20 objetos, 1 instância

 

1 instancia??? nos acabamos de tirar aprova acima.

 

Nao tem como em 20 pedidos HTTP termos 1 so instância. nos provamos q temos apenas 1 instância por pagina que resulta 1 x 20 pedidos = 20 instancias nos 20 clientes( Pedidos HTTP, Browser )

 

 

1 instancia nao pode misturar com uma outra sessão nao, imagina, isto pode dar muitos problemas de logica :blink:

 

 

Se eu tenho um instância de uma classe Singleton e mudo uma propriedade pra TRUE.

 

E você entra na mesma pagina e o server compartilhar a instancia do meu objeto você vai pega-la com a propriedade TRUE, olha so que zona.

Entao eu continuo dizendo:

 

Sem Singleton:

20 pedidos contem 20 objetos no mínimo que possui 20 instância no MÍNIMO.

Com Singleton:

20 pedidos contem 20 objetos no mínimo que possui 20 instância no MÁXIMO.

 

 

Falow ;)

Obrigado pela atenção.

 

 

sem Singleton:

20 pedidos, 20 objetos, 20 instâncias diferentes

 

com Singleton:

20 pedidos, 20 objetos, 1 instância

Compartilhar este post


Link para o post
Compartilhar em outros sites

Sobre abrir uma unica conexão com vários navegadores (isso mesmo, vários clientes independentes), tentei uma vez utilizando o mysql_pconnect (www.php.net/mysql_pconnect).

 

Tem um artigo bem longo no link abaixo explicando os prós e contras de usar conexões persistentes.

 

http://br2.php.net/manual/en/features.pers...connections.php

 

Nunca consegui utilizar ele sem dar erros de limite de conexão excedida (o que teoricamente não deveria acontecer, pois o usuário, senha e host são os mesmos - os quais são os dados necessários para que uma conexão seja persistente).

 

Tenho usado a maneira tradicional (mysql_connect) fechando corretamente a conexão ao termino de cada script, e não tenho tido problemas (tenho clientes que tem média de mais 10.000 visitas / dia e não tem dado problema).

 

Acredito que se estudado bem e aplicado da maneira correta, o mysql_pconnect possa ser mais útil, dependendo o caso do número de acessos.

 

Sobre o padrão singleton, sem dúvida alguma é a maneira mais elegante de se trabalhar com banco de dados.

Tenho um "framework" que estou desenvolvendo (e usando em vários clientes) que está funcionando muito bem, e utiliza o padrão singleton (além de me facilitar o código):

 

$pessoa = new Pessoa;
$pessoa->setFrom( $_POST ); // pega os dados do form
$pessoa->save(); // insere / atualiza conforme o caso

@braços e fiquem com Deus!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Estou tb criando um Framework MVC com Web 2.0, na blicandeira vai o pacote Smarty e Javascripts pra ajax e intereçoes Web 2.0

Tem ele atualamente usa conexao com MSSQL trata os charset com iconv automaticamente e muiltas outras coisas so nao estou suando esta conexao pesistente que você citou ai.

Eu ja li varias vezes sobre ela mais ainda nao achei vantagem, porque todas as paginas q eu uso nunca precisou de usar mais de uma conexao. :P

 

Mas falando do seu framework eu achei legal.

 

$pessoa = new Pessoa;
$pessoa->setFrom( $_POST ); // pega os dados do form
$pessoa->save(); // insere / atualiza conforme o caso

mas como você trata isto:

 

Ex:

Seu form tem mais campos que sua table SQL, como você tranta isto, pois você manda o objeto $_POST todo.

 

 

OBs. Espero que você esteja passando este objeto $_POST por referencia. rs.. http://forum.imasters.com.br/public/style_emoticons/default/grin.gif

 

Falow.

 

Sobre abrir uma unica conexão com vários navegadores (isso mesmo, vários clientes independentes), tentei uma vez utilizando o mysql_pconnect (www.php.net/mysql_pconnect).

 

Tem um artigo bem longo no link abaixo explicando os prós e contras de usar conexões persistentes.

 

http://br2.php.net/manual/en/features.pers...connections.php

 

Nunca consegui utilizar ele sem dar erros de limite de conexão excedida (o que teoricamente não deveria acontecer, pois o usuário, senha e host são os mesmos - os quais são os dados necessários para que uma conexão seja persistente).

 

Tenho usado a maneira tradicional (mysql_connect) fechando corretamente a conexão ao termino de cada script, e não tenho tido problemas (tenho clientes que tem média de mais 10.000 visitas / dia e não tem dado problema).

 

Acredito que se estudado bem e aplicado da maneira correta, o mysql_pconnect possa ser mais útil, dependendo o caso do número de acessos.

 

Sobre o padrão singleton, sem dúvida alguma é a maneira mais elegante de se trabalhar com banco de dados.

Tenho um "framework" que estou desenvolvendo (e usando em vários clientes) que está funcionando muito bem, e utiliza o padrão singleton (além de me facilitar o código):

 

$pessoa = new Pessoa;
$pessoa->setFrom( $_POST ); // pega os dados do form
$pessoa->save(); // insere / atualiza conforme o caso

@braços e fiquem com Deus!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Então, funciona assim: eu crio minhas classes em PHP que extendem uma classe padrão, essa classe que é a responsável por quase toda a aplicação.

Assim eu consigo fazer coisas do genero:

 

Lumine::import('Pessoa','Grupo');

$pessoa = new Pessoa;
$grupo = new Grupo;

$total_encontrado = $pessoa->alias('p')
  ->join($grupo,'inner','g')
  ->select('p.nome, p.datanascimento, g.nome as nomegrupo')
  ->where('p.idusuario = ?', $_SESSION['idusuario'])
  ->find( true );

Isso irá executar uma consulta parecida com

 

SELECT p.nome, p.datanascimento, g.nome as nomegrupo FROM tbl_pessoa p INNER JOIN tbl_grupo g ON (p.idpessoa = g.idpessoa)
WHERE p.idpessoa = 32

 

Assim fica beeeeeeeeem mais fácil trabalhar.

Estou desenvolvendo ele já a algum tempo, mas tem muita coisa pra melhorar... depois quero ver se coloco ele em um servidor de controle de versão decente, para poder angariar mais pessoas no projeto.

 

Estou re-desenvolvendo o site, porque o site que está on é da versão antiga

 

http://www.hufersil.com.br/lumine

 

Estou desenvolvendo uma nova versão (por enquanto só roda MySQL e o PostgreSQL, mas o PostgreSQL estou tendo uns probleminhas quanto a escape de strings).

 

Se quiser baixar pra brincar, o endereço é http://www.hufersil.com.br/lumine.rar (ainda não comecei a fazer a documentação da nova versão mas está quase tudo igual para fazer, exceto que não uso mais mapeamento em XML).

 

PS.: Dentro da pasta lib/ui tem um arquivo chamado REVERSE.PHP. Se acessá-lo pelo navegador, você poderá fazer uma engenharia reversa de seu banco, assim ele já cria as classes e fica bem mais fácil. Se usar InnoDB e tiver relacionamentos, ele também já pega os relacionamentos.

 

@braços e fique com Deus

Compartilhar este post


Link para o post
Compartilhar em outros sites

Falando em Smarty, eu uso muuuuuuuuuuuuito o Smarty com Lumine. Um exemplo é que no Lumine tem um método chamado allToArray, daeh ele manda uma lista prontinha pra usar no Smarty :D

 

// pegando os modulos do usuario e jogando no smarty

$modulo = new Modulo;
$grupo = new Grupo;
$usuario = new Usuario;

$usuario->alias('u')
  ->join($grupo->alias('g')
	->join($modulo,'inner','m')
  )
  ->select('m.nome, m.codmodulo, m.codpai, m.url, m.icone, m.ordem')
  ->where('u.codusuario = ?', $sessao['codusuario'])
  ->order('m.ordem asc')
  ->group('m.codmodulo')
  ->find();

$smarty->assign('modulos', $usuario->allToArray());

@braços e fique com Deus!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ae, eu ja tinha visto o Lumine no site que tu passou.

 

 

Eu to pensando agora como é que eu vou tornar o MVC em PHP em uma coisa tao boa como no Ruby on Rails http://forum.imasters.com.br/public/style_emoticons/default/blush.gif

 

 

O bom do Rails é que o HTTP nao é orientado a arquivos pelo que vi é por procedimentos( URL amigaveis ), e isto em PHP pelo menos no IIS e no Apache ta sendo um saco.

 

Ta dificil concluir o que vou fazer.... aiai...

 

 

Falow

fica com Deus..

Compartilhar este post


Link para o post
Compartilhar em outros sites

cara, no apache não tenho dificuldades com URL's amigáveis, acho até bem legal...

nunca mexi (nem procurei saber ainda) como funciona o Ruby on Rails, mas tenho ouvido falar muito bem dele.

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.