Ir para conteúdo

Publicidade

Conteúdo mais reputado


#1576410 Padrões GoF

Postado por João Batista Neto em 17 julho 2010 - 11:23

Tópico índice sobre design patterns GoF em PHP:

Padrões de Criação:

AbstractFactory:

http://forum.imaster...ost__p__1572696

Builder

 

http://forum.imaster...ost__p__1600194

FactoryMethod:

 

 

http://forum.imaster...ost__p__1574437

Singleton:

 

 

http://forum.imaster...ost__p__1565817

 

 


Padrões Estruturais:

 

Composite:

 

http://forum.imaster...ost__p__1576365
http://forum.imaster...ando-composite/
 

Decorator:

 

http://forum.imaster...84#entry1706584

 

 


Padrões Comportamentais:

 

Interpreter:

 

http://forum.imaster...ost__p__1572696
http://forum.imaster...95#entry1732595
Imagem Postadahttp://forum.imaster...ost__p__1763132

Iterator:

 

http://forum.imaster...ost__p__1535665

Mediator:

 

 

http://forum.imaster...ost__p__1490482

State:

 

 

http://forum.imaster...design-pattern/
 

Strategy:

 

 

http://forum.imaster...79#entry1701079
 

Observer:

 

 

http://forum.imaster...ost__p__1685860

Command:

 

 

http://forum.imaster...30#entry1686430

Chain Of Responsibility:

 

 

http://forum.imaster...ost__p__1789686

Memento:

 

 

http://forum.imaster...30#entry1686430

 

 

 

Novos tópicos ou posts poderão ser adicionados conforme forem surgindo.


  • 25


#1815097 Como pensar em Orientação a Objetos

Postado por João Batista Neto em 01 março 2012 - 21:45

E existe um padrão específico para esse exemplo da estante ou dos funciona´rios ou é apenas uma Coleção simples?


Nesse caso da estante ou da empresa, suas representações enquanto entidades, são meras associações. O diagrama abaixo exemplifica os tipos:
Imagem Postada

O primeiro relacionamento é uma associação simples, uma empresa pode ter 1..* funcionários. Se um funcionário morrer, a empresa não deixará de funcionar.

O segundo relacionamento chama-se agregação, se tirarmos as rodas do carro, ele não andará, mas também não deixará de existir, assim como as rodas não deixarão de existir.

O terceiro relacionamento chama-se composição, é o relacionamento mais forte que temos. Se cortarmos a cabeça, Fulano morre. Da mesma forma, se removermos um capítulo de um livro, vamos estragá-lo.

;)
  • 20


#2167182 ATENÇÃO: Orientações e Regras do Fórum de PHP

Postado por Beraldo em 15 outubro 2015 - 12:42

Orientações e Regras do Fórum de PHP
 
Siga estas simples Orientações e Regras e seus tópicos serão até 1297% mais eficientes, com mais visualizações e respostas.
 
Regras
 
1 - Use Títulos Condizentes Com Suas Dúvidas
Descreva no título do tópico exatamente o que você precisa, qual é sua dúvida ou problema.
Evite títulos como: "Ajuda", "Help" e títulos que sejam generalizados demais.
Jamais escreva "URGENTE" o título do tópico. Tudo que é urgente é aquilo que deveria ter sido feito por você ontem mas não foi feito.
 
 
2 - Estamos Aqui Para Orientar
Poste um trecho do que você já fez. Estamos aqui para te orientar e para te ajudar a aprender. Não vamos fazer seu trabalho por você.
 
 
3 - Tenha Calma e Paciência
Não responda o próprio tópico com a intenção de atualizá-lo (UP).
Todos nós temos trabalhos próprios e outros compromissos. Os membros do fórum responderão os tópicos quando possível.

E vale lembrar que Moderadores não têm obrigação de responder tópicos. Eles estão aqui essencialmente para auxiliar na organização do fórum.
 
 
4. Para Dúvidas, Use o Fórum
Não envie dúvidas por MP (mensagem privada). Para isso utilize o fórum, dessa forma em vez de apenas um, muitos membros poderão ajudar você a resolver seu problema, além de a solução ficará publicada, para ajudar muitos outros usuários.
 

5. O fórum de PHP é relacionado EXCLUSIVAMENTE à linguagem de Programação PHP
Ao iniciar um tópico no fórum de PHP, certifique-se de que sua dúvida está relacionada com a linguagem PHP, seguindo o contexto do fórum. Se sua dúvida for relacionado a qualquer outra linguagem, tecnologia ou framework, como jQuery, Ajax, HTML, procure o fórum correspondente para tratar do assunto.
 
 
Orientações
 

 

1. Seja Claro e Específico

Descreva sua dúvida da forma mais clara possível. Explique o máximo que puder.

Muitas vezes, você tem a ideia bem clara em sua cabeça e tudo parece simples, mas quem lê o tópico não vai entender, se você não explicar detalhadamente.

 

2. Use a Tag Código
Sempre que postar códigos, adicione-o entre as tags [ code ] e [ /code ] (sem os espaços), para facilitar a leitura.
Você também pode usar o Botão Code (símbolo "<>"), ao lado do Botão Imagem, no editor de textos do fórum.
 

3. Habilite Todas as Exibições de Erro
Configure seu código para exibir TODAS as mensagens de erro, adicionando este código ao topo do script.


ini_set('display_errors', true);
error_reporting(E_ALL);

 
 
4. Leia as Mensagens de Erro
Leia os erros que aparecerem, pois normalmente eles dizem o que há de errado no código.
Verifique se o erro está na lista dos erros mais comuns do PHP. Você pode corrigi-lo facilmente, sem precisar abrir um tópico só para isso.

Se não entender as mensagens de erro, poste-as em seu tópico, apontando a linha exata onde ele ocorre. Assim saberemos onde está o problema
 
  
5. Faça Debug de Suas Queries
Exiba os erros do banco de dados, para ajudar no debug, seguindo estes exemplos:

// Para MySQL
mysql_query("sua query aqui") or exit(mysql_error());
 
// Para MySQLi
// ($mysqli é o link de conexão, retornado por mysqli_connect)
mysqli_query($mysqli, "sua query aqui") or exit(mysqli_error($mysqli));
 
// Para PDO sem Prepared Statements
// ($PDO é o objeto PDO, retornado por "new PDO")
$PDO->query("sua query aqui") or exit(print_r($PDO->errorInfo(), true));
 
// Para PDO com Prepared Statements
// ($stmt é o objeto PDOStatement, retornado pelo método prepare)
$stmt->execute() or exit(print_r($stmt->errorInfo(), true));

 
 
6. Dúvidas Sobre Uma Função do PHP?
Se a dúvida for sobre a utilização de uma função, leia o manual dela, acessando php.net/nome_da_funcao.
 
 
7. Marque Seus Tópicos Como Resolvido
Quando um membro postar algo que resolva seu problema, marque esse post como solução.
Uma vez marcado como resolvido, o post útil será mandado para o topo da página, facilitando a visualização de todos que o procurarem.
 
 
8. Evite Citação Desnecessária
Ao utilizar o botão "Citação" ou "Multicitação", no canto inferior direito de cada post, o conteúdo do post será inserido em sua resposta, para citação.
Isso ocupa bastante espaço na tela. Por isso, apenas cite quando realmente necessário.
Prefira usar o botão Responder, inserindo apenas a sua resposta.
 

9. Apenas Uma Dúvida Por Tópico
Ao criar seu tópico, seja claro na sua dúvida e mantenha somente uma dúvida por tópico.
Não aproveite tópicos com dúvidas de outros usuários para postar sua dúvida. Nesse caso, abra um novo tópico
 
 
10. De Novo, Seja Paciente
Lembre-se que o fórum é composto por voluntários que também possuem seus próprios problemas e compromissos. Não espere uma resposta imediata, muitas vezes um membro que pode ter a solução para seu problema ainda não leu sua dúvida.
 
 
Equipe iMasters


  • 17


#631536 Sistema de Cadastro em PHP/MySQL

Postado por Fabyo em 02 setembro 2006 - 19:24

Pessoal to dando continuidade nos tutoriais para iniciantes e esse aqui é para quem ja leu:

http://forum.imaster...howtopic=191441

Esse tutorial é para usuarios iniciantes que estao começando agora e querem aprender a mecher com PHP e banco de dados, sei que é dificil achar um tutorial bem mastigado assim, e falta exemplos completos no manual do php, e as vezes a pessoa acaba pegando um script pronto mas nao entende muito e o pior a maioria das vezes o sistema esta mal feito assim o usuario acaba aprendendo errado pensando que é o certo.

esse tutorial é bem basico, e criei como exemplo 2 tabelas uma para usuario e outra para estados
e é mais para você aprender mesmo , acabei criando varias funções que ficaram mais para aprendizado do que funcional, mas a ideia é você entender como as coisas funcionam

com esse sistema você vai aprender:

* Listar os dados de um banco de dados
* Salvar dados do formulario para banco de dados
* Excluir dados do banco
* Editar dados do banco
* Carregar um combobox(select do html) com dados vindos do banco de dados
* Validações especiais para deixar o php funcionando 100% sem erros
* Varios macetes e dicas de uso em sistemas com o uso de um arquivo de verificações basicas o init.php

OBS Esse sistema esta puro em PHP nao me preocupei com nenhuma validação em javascript
para isso voce pode acessar o forum de javascript e tirar as duvidas sobre validações de formulario
e tambem nao me preocupei com validações de dados vindos do formulario, pois eu estou planejando fazer um tutorial só para isso, para validações em php com filtros e segurança de dados


tabela.sql

CREATE TABLE usuarios (
id_usuario SMALLINT ( 5 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
nome VARCHAR ( 45 ) NOT NULL,
email VARCHAR ( 64 ) NOT NULL UNIQUE,
data_nascimento DATE NOT NULL,
sexo ENUM ( 'M', 'F' ) NOT NULL,
preferencias SET ( 'R', 'S', 'P', 'F' ) NOT NULL COMMENT 'R=Romance;S=Suspense;P=Policial;F=Ficção',
salario DECIMAL ( 10,2 ) NOT NULL,
endereco VARCHAR ( 30 ) NOT NULL,
bairro VARCHAR ( 20 ) NOT NULL,
cidade VARCHAR ( 45 ) NOT NULL,
fk_estado SMALLINT ( 5 ) UNSIGNED NOT NULL,
login VARCHAR ( 40 ) NOT NULL,
senha CHAR ( 32 ) NOT NULL
);

CREATE TABLE estados (
id_estado SMALLINT ( 5 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
uf CHAR ( 2 ) NOT NULL,
estado VARCHAR ( 19 ) NOT NULL UNIQUE
);

INSERT INTO estados VALUES ( NULL , "AC", "Acre");
INSERT INTO estados VALUES ( NULL , "AL", "Alagoas");
INSERT INTO estados VALUES ( NULL , "AP", "Amapá");
INSERT INTO estados VALUES ( NULL , "AM", "Amazonas");
INSERT INTO estados VALUES ( NULL , "BA", "Bahia");
INSERT INTO estados VALUES ( NULL , "CE", "Ceará");
INSERT INTO estados VALUES ( NULL , "DF", "Distrito Federal");
INSERT INTO estados VALUES ( NULL , "ES", "Espirito Santo");
INSERT INTO estados VALUES ( NULL , "GO", "Goiás");
INSERT INTO estados VALUES ( NULL , "MA", "Maranhão");
INSERT INTO estados VALUES ( NULL , "MT", "Mato Grosso");
INSERT INTO estados VALUES ( NULL , "MS", "Mato Grosso do Sul");
INSERT INTO estados VALUES ( NULL , "MG", "Minas Gerais");
INSERT INTO estados VALUES ( NULL , "PA", "Pará");
INSERT INTO estados VALUES ( NULL , "PB", "Paraíba");
INSERT INTO estados VALUES ( NULL , "PR", "Paraná");
INSERT INTO estados VALUES ( NULL , "PE", "Pernambuco");
INSERT INTO estados VALUES ( NULL , "PI", "Piauí");
INSERT INTO estados VALUES ( NULL , "RN", "Rio Grande do Norte");
INSERT INTO estados VALUES ( NULL , "RS", "Rio Grande do Sul");
INSERT INTO estados VALUES ( NULL , "RJ", "Rio de Janeiro");
INSERT INTO estados VALUES ( NULL , "RO", "Rondônia");
INSERT INTO estados VALUES ( NULL , "RR", "Roraima");
INSERT INTO estados VALUES ( NULL , "SC", "Santa Catarina");
INSERT INTO estados VALUES ( NULL , "SP", "São Paulo");
INSERT INTO estados VALUES ( NULL , "SE", "Sergipe");
INSERT INTO estados VALUES ( NULL , "TO", "Tocantins"); </div>

como podem ver é uma tabela apenas para podermos usar no sistema, sao coisas ficticias que usei apenas para passar exemplos uteis de varios campos no banco de dados, talves o unico campo que você nao saiba para que serve nessa tabela é o "preferencias", esse preferencia é para o usuario escolher qual tipo de filme ele gosta, usei esse exemplo para você entender como usar o campo SET() do mysql

pessoal eu nao faço codigos html fora do padrao, e todos meus codigos sao valido pelo W3C, mas eu nao me preocupei em deixar os codigos validos pois a ideia é passar mais informação sobre o sistema de cadastro, e se eu for me preoculpar com tudo isso eu nunca iria postar esse tutorial, pois meu tempo anda curto demais.

index.html:
<a href="cadastro.php">Cadastrar Usuarios</a><br />
<a href="listar.php">Listar Usuarios</a>

cadastro.php
<?php
//Verifico se o arquivo existe
if(file_exists("init.php")) {
	require "init.php";		
} else {
	echo "Arquivo init.php nao foi encontrado";
	exit;
}
//verifico se a função que eu criei existe, vai que alguem pegou meu script e apagou ela = )
if(!function_exists("Abre_Conexao")) {
	echo "Erro o arquivo init.php foi auterado, nao existe a função Abre_Conexao";
	exit;
}

Abre_Conexao();
$re = mysql_query("select * from estados order by estado");
//verifico se nao deu erro de mysql
if(mysql_errno() != 0) {
                //verifico se a $errros existe, mesma coisa vai que alguem meche no script e apagou ela
	if(!isset($erros)) {
		echo "Erro o arquivo init.php foi auterado, nao existe \$erros";
		exit;
	}
	echo $erros[mysql_errno()];
	exit;
}	
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Cadastro</title>
<style>
<!--
.textBox { border:1px solid gray; width:200px;} 
-->
</style>
</head>

<body>
<form id="form1" name="form1" method="post" action="salvar.php">
  <table width="400" border="0" align="center">
    <tr>
      <td width="145">Nome</td>
      <td width="245"><input name="nome" type="text" id="nome" maxlength="45" class="textBox" /></td>
    </tr>
    <tr>
      <td>Email</td>
      <td><input name="email" type="text" id="email" maxlength="64" class="textBox" /></td>
    </tr>
    <tr>
      <td>Data Nascimento</td>
      <td>
		<?php	
                                                /*aqui eu criei uma função para montar o combo para mim, na propria função a seguir eu explico como ela funciona*/		
			echo monta_select("dia", 1, 31);	
			echo monta_select("mes", 1, 12);	
			echo monta_select("ano", 1940, 1988);
		?>	
	</td>
    </tr>
    <tr>
      <td>Sexo</td>
      <td><input name="sexo" type="radio" value="M" checked="checked" /><label>Masculino</label> 
      <input name="sexo" type="radio" value="F" /> <label>Feminino</label></td>
    </tr>
    <tr>
      <td>Preferencias de Filmes </td>
      <td><select name="preferencias[]" class="textBox" multiple="multiple" id="preferencias">
        <option value="R">Romance</option>
        <option value="S">Suspense</option>
        <option value="P">Policial</option>
        <option value="F">Ficção</option>
      </select>
      </td>
    </tr>
    <tr>
      <td>Salario</td>
      <td><input name="salario" type="text" id="salario" maxlength="5" class="textBox" /></td>
    </tr>
    <tr>
      <td>Endereco</td>
      <td><input name="endereco" type="text" id="endereco" maxlength="30" class="textBox" /></td>
    </tr>
    <tr>
      <td>Bairro</td>
      <td><input name="bairro" type="text" id="bairro" maxlength="20" class="textBox" /></td>
    </tr>
    <tr>
      <td>Cidade</td>
      <td><input name="cidade" type="text" id="cidade" maxlength="45" class="textBox" /></td>
    </tr>
    <tr>
      <td>Estado</td>
      <td><select name="estados" id="estados" class="textBox" >	  	
<?php
//pego os dados do banco para montar o combo do estados
while($l = mysql_fetch_array($re)) {
	$id     = $l["id_estado"];
	$estado = $l["estado"];
	$uf     = $l["uf"];				
	echo "<option value=\"$id\">$uf - $estado</option>\n";
}
//fecho a conexao com o banco
@mysql_close();
		
?>
      </select>      </td>
    </tr>
    <tr>
      <td>Login</td>
      <td><input name="login" type="text" id="login" maxlength="40" class="textBox" /></td>
    </tr>
    <tr>
      <td>Senha</td>
      <td><input name="senha" type="password" id="senha" maxlength="10" class="textBox" /></td>
    </tr>
    <tr>
      <td> </td>
      <td><input type="submit" name="Submit" value="Salvar" style="cursor:pointer;" /></td>
    </tr>
  </table>
</form>
</body>
</html></div>
salvar.php

<?php
/*verifico se os dados estao vindos do formulario, porque se uma pessoa acessar essa pagina diretamente
poderia dar erro, entao eu testo antes*/
if($_SERVER["REQUEST_METHOD"] == "POST") {
$nome = $_POST["nome"];
$email = $_POST["email"];
$data = "{$_POST["ano"]}-{$_POST["mes"]}-{$_POST["dia"]}";
$sexo = $_POST["sexo"];
//if e else simplificado, verifico se foi escolhido alguma preferencia e crio um array
$preferencias = isset($_POST["preferencias"]) ? implode(",", $_POST["preferencias"]) : "";
$salario = $_POST["salario"];
$endereco = $_POST["endereco"];
$bairro = $_POST["bairro"];
$cidade = $_POST["cidade"];
$estados = $_POST["estados"];
$login = $_POST["login"];
$senha = $_POST["senha"];

//aqui ja expliquei, mas denovo: ele verifica se o arquivo existe
if(file_exists("init.php")) {
require "init.php";
} else {
echo "Arquivo init.php nao foi encontrado";
exit;
}
//ja expliquei, mas ultima vez: verifica se a função que eu vou usar existe
if(!function_exists("Abre_Conexao")) {
echo "Erro o arquivo init.php foi auterado, nao existe a função Abre_Conexao";
exit;
}

Abre_Conexao();
if(@mysql_query("INSERT INTO usuarios VALUES ( NULL , '$nome', '$email', '$data' , '$sexo',
'$preferencias', '$salario', '$endereco', '$bairro', '$cidade', '$estados', '$login', MD5( '$senha' ) )")) {
//verifiquei acima se deu certo o comando e aqui verifico se foi mesmo gravado o dado no banco
if(mysql_affected_rows() == 1){
echo "Registro efetuado com sucesso<br />";
}

} else {
//verifico se nao estao tentando gravar um dado que ja existe, pois usei UNIQUE na tabela
if(mysql_errno() == 1062) {
echo $erros[mysql_errno()];
exit;
} else {
echo "Erro nao foi possivel efetuar o cadastro";
exit;
}
@mysql_close();
}

}
?>
<a href="index.html">Voltar</a>


listar.php

<a href="index.html">Voltar</a>
<?php
if(file_exists("init.php")) {
require "init.php";
} else {
echo "Arquivo init.php nao foi encontrado";
exit;
}

if(!function_exists("Abre_Conexao")) {
echo "Erro o arquivo init.php foi auterado, nao existe a função Abre_Conexao";
exit;
}

Abre_Conexao();
$re = mysql_query("SELECT * FROM usuarios INNER JOIN estados ON usuarios.fk_estado = estados.id_estado ORDER BY usuarios.nome;");
if(mysql_errno() != 0) {
if(!isset($erros)) {
echo "Erro o arquivo init.php foi auterado, nao existe $erros";
exit;
}
echo $erros[mysql_errno()];
exit;
}
?>

<table width="100%" border="1">
<tr>
<td>Ações</td>
<td>Nome</td>
<td>Email</td>
<td>Data Nasc.</td>
<td>Sexo</td>
<td>Preferencias</td>
<td>salario</td>
<td>Endereço</td>
<td>Bairro</td>
<td>Cidade</td>
<td>Estado</td>
<td>Login</td>
</tr>
<?php
while($l = mysql_fetch_array($re)) {
$id = $l["id_usuario"];
$nome = $l["nome"];
$email = $l["email"];
$data = implode("/", array_reverse(explode("-", $l["data_nascimento"])));
$sexo = $l["sexo"] == "M" ? "Masculino" : "Feminino";
$preferencia = Pega_Preferencia($l["preferencias"]);
$salario = $l["salario"];
$endereco = $l["endereco"];
$bairro = $l["bairro"];
$cidade = $l["cidade"];
$estado = $l["estado"];
$login = $l["login"];

echo "
<tr>
<td><a href=\"editar.php?id=$id\">[Editar]</a> <a href=\"excluir.php?id=$id\">[Excluir]</a></td>
<td> $nome</td>
<td> $email</td>
<td> $data</td>
<td> $sexo</td>
<td> ". monta_combo($preferencia). "</td>
<td> ". number_format($salario, 2, ",", "."). "</td>
<td> $endereco</td>
<td> $bairro</td>
<td> $cidade</td>
<td> $estado</td>
<td> $login</td>
</tr>\n";
}
@mysql_close();
?>
</table>


editar.php

<?php
if(file_exists("init.php")) {
require "init.php";
} else {
echo "Arquivo init.php nao foi encontrado";
exit;
}

if(!function_exists("Abre_Conexao")) {
echo "Erro o arquivo init.php foi auterado, nao existe a função Abre_Conexao";
exit;
}
$id = $_GET["id"];

Abre_Conexao();
$re = mysql_query("select count(*) as total from usuarios where id_usuario = $id");
$total = mysql_result($re, 0, "total");

if($total == 1) {
$re = mysql_query("select * from usuarios, estados where estados.id_estado = usuarios.fk_estado and usuarios.id_usuario = $id");
$dados = mysql_fetch_array($re);
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Cadastro</title>
<style>
<!--
.textBox { border:1px solid gray; width:200px;}
-->
</style>
</head>

<body>
<form id="form1" name="form1" method="post" action="salvar_edicao.php">
<input type="hidden" name="id" value="<?php echo $id; ?>" />
<table width="400" border="0" align="center">
<tr>
<td width="145">Nome</td>
<td width="245"><input name="nome" type="text" id="nome" maxlength="45" class="textBox" value="<?php echo $dados["nome"]; ?>" /></td>
</tr>
<tr>
<td>Email</td>
<td><input name="email" type="text" id="email" maxlength="64" class="textBox" value="<?php echo $dados["email"]; ?>" /></td>
</tr>
<tr>
<td>Data Nascimento</td>
<td>
<?php
$arr = explode("-", $dados["data_nascimento"]);

echo Seleciona_Item($arr[2], monta_select("dia", 1, 31));
echo Seleciona_Item($arr[1], monta_select("mes", 1, 12));
echo Seleciona_Item($arr[0], monta_select("ano", 1940, 1988));
?>
</td>
</tr>
<tr>
<td>Sexo</td>
<td><input name="sexo" type="radio" value="M" <?php echo $dados["sexo"] == "M" ? "checked=\"checked\"" : ""; ?> /><label>Masculino</label>
<input name="sexo" type="radio" value="F" <?php echo $dados["sexo"] == "F" ? "checked=\"checked\"" : ""; ?> /> <label>Feminino</label></td>
</tr>
<tr>
<td>Preferencias de Filmes </td>
<td><select name="preferencias[]" class="textBox" multiple="multiple" id="preferencias">
<?php
$combo = "<option value=\"R\">Romance</option>
<option value=\"S\">Suspense</option>
<option value=\"P\">Policial</option>
<option value=\"F\">Ficção</option>";

$arr = explode(",", $dados["preferencias"]);
for($i = 0; $i < count($arr); $i++) {
$combo = preg_replace("#<option value=\"{$arr[$i]}\">#is", "<option value=\"{$arr[$i]}\" selected=\"selected\">", $combo);
}
echo $combo;
?>

</select>
</td>
</tr>
<tr>
<td>Salario</td>
<td><input name="salario" type="text" id="salario" maxlength="5" class="textBox" /></td>
</tr>
<tr>
<td>Endereco</td>
<td><input name="endereco" type="text" id="endereco" maxlength="30" class="textBox" /></td>
</tr>
<tr>
<td>Bairro</td>
<td><input name="bairro" type="text" id="bairro" maxlength="20" class="textBox" /></td>
</tr>
<tr>
<td>Cidade</td>
<td><input name="cidade" type="text" id="cidade" maxlength="45" class="textBox" /></td>
</tr>
<tr>
<td>Estado</td>
<td><select name="estados" id="estados" class="textBox" >
<option value="0">Selecione</option>
<?php
$re = mysql_query("select * from estados order by estado");
if(mysql_errno() != 0) {
if(!isset($erros)) {
echo "Erro o arquivo init.php foi auterado, nao existe $erros";
exit;
}
echo $erros[mysql_errno()];
exit;
}
while($l = mysql_fetch_array($re)) {
$id = $l["id_estado"];
$estado = $l["estado"];
$uf = $l["uf"];
echo Seleciona_Item($dados["id_estado"], "<option value=\"$id\">$uf - $estado</option>");

}
@mysql_close();

?>
</select> </td>
</tr>
<tr>
<td>Login</td>
<td><input name="login" type="text" id="login" maxlength="40" class="textBox" /></td>
</tr>
<tr>
<td>Senha</td>
<td><input name="senha" type="password" id="senha" maxlength="10" class="textBox" /></td>
</tr>
<tr>
<td> </td>
<td><input type="submit" name="Submit" value="Salvar" style="cursor:pointer;" /></td>
</tr>
</table>
</form>
</body>
</html>


excluir.php

<?php
if($_SERVER["REQUEST_METHOD"] == "GET") {
if(file_exists("init.php")) {
	require "init.php";		
} else {
	echo "Arquivo init.php nao foi encontrado";
	exit;
}

if(!function_exists("Abre_Conexao")) {
	echo "Erro o arquivo init.php foi auterado, nao existe a função Abre_Conexao";
	exit;
}
$id = $_GET["id"];

Abre_Conexao();
if(mysql_query("delete from usuarios where id_usuario = $id")) {
	if(mysql_affected_rows() == 1){
		echo "Registro deletado com sucesso<br />";
	}	
}	
}

?>
<a href="listar.php">Voltar</a>

salvar_edicao.php

<?php
if($_SERVER["REQUEST_METHOD"] == "POST") {
$id = $_POST["id"];
$nome = $_POST["nome"];
$email = $_POST["email"];
$data = "{$_POST["ano"]}-{$_POST["mes"]}-{$_POST["dia"]}";
$sexo = $_POST["sexo"];
$preferencias = isset($_POST["preferencias"]) ? implode(",", $_POST["preferencias"]) : "";
$salario = $_POST["salario"];
$endereco = $_POST["endereco"];
$bairro = $_POST["bairro"];
$cidade = $_POST["cidade"];
$estados = $_POST["estados"];
$login = $_POST["login"];
$senha = $_POST["senha"];

if(file_exists("init.php")) {
require "init.php";
} else {
echo "Arquivo init.php nao foi encontrado";
exit;
}

if(!function_exists("Abre_Conexao")) {
echo "Erro o arquivo init.php foi auterado, nao existe a função Abre_Conexao";
exit;
}

Abre_Conexao();
if(@mysql_query("UPDATE usuarios SET nome = '$nome',
email = '$email',
sexo = '$sexo',
preferencias = '$preferencias',
salario = '$salario',
endereco = '$endereco',
bairro = '$bairro',
cidade = '$cidade',
fk_estado = '$estados',
login = '$login',
senha = MD5( '$senha' ) WHERE id_usuario = $id")) {

if(mysql_affected_rows() == 1){
echo "Registro atualizado com sucesso";
}

} else {
if(mysql_errno() == 1062) {
echo $erros[mysql_errno()];
exit;
} else {
echo "Erro nao foi possivel efetuar a edição";
exit;
}
@mysql_close();
}

}
?>
<a href="listar.php">Voltar</a>



arquivos completos para download: Arquivo anexado  Cadastro.zip   8,03K   18124 Downloads
Pessoal qualquer duvida quanto os sistema ou alguma duvida só postar no forum mesmo que responderemos

bom espero que esse exemplo seja util

versao do sistema de cadastro mais simples
http://forum.imaster...howtopic=201046

abraços

OBS Topico atualizado 24/06/2009 ir para ultimas paginas nelas tem outras atualizações do sistema de cadastro incluindo sistema de login com niveis de acesso
  • 16


#1965569 Vale a pena? ultilizar frameworks ?

Postado por Evandro Oliveira em 30 abril 2013 - 17:51

Calcula, pra mim, a raiz quadrada de 1048576 e me diz se vale a pena ou não utilizar calculadora ;)
  • 14


#1867650 Realidade Vs Adobe Flash Plugin

Postado por Prog em 23 julho 2012 - 15:40

Como meu computador é...

Na realidade...
Imagem Postada

Como eu gostaria...
Imagem Postada

Como a Adobe acha que é...
Imagem Postada

------------------------------------------------------------------

O funcionamento do meu computador...

Na realidade...
Imagem Postada

Como eu gostaria...
Imagem Postada

Como a Adobe faz ser...
Imagem Postada

------------------------------------------------------------------

Quando estou me divertindo no computador...

Na realidade...
Imagem Postada

Como eu gostaria...
Imagem Postada

Como a Adobe faz ser...
Imagem Postada

------------------------------------------------------------------
  • 13


#1772073 [Resolvido] Namespace

Postado por João Batista Neto em 31 outubro 2011 - 13:04

É interessante como as coisas são.

Já pararam para pensar que há 5~6 anos atrás, esse tipo de discussãoseria inimaginável em um fórum de PHP! Tenho certeza que se surgisse uma discussão sobre empacotamento em PHP, alguém certamente diria: "Isso é coisa de Java".

O mais interessante é que, com a evolução da linguagem, problemas que até então não existiam, passam a existir:

Namespaces:

Quero definir um namespace pra varias classes ao mesmo tempo, sendo que todas elas estariam dentro ou incluídas(include/require) em um único arquivo pra não precisar fazer isso ai de cima pra cada nova classe ou função.


A primeira coisa que se precisa compreender é que namespace é a definição de contexto em linguagens de programação. Definir todas as classes dentro de um único namespace é um erro pois, dessa forma, perde-se a definição de contexto e, consequentemente, o sentido de se utilizar um namespace.

Não coloque 2 classes por aquivo.


Ai surge um outro problema: Porque colocar apenas 1 classe em um arquivo? Porque não devemos colocar mais do que uma classe no mesmo arquivo? Se o contexto estiver bem definido e o namespace representar corretamente aquele conjunto de classes, qual o problema em ter várias classes dentro de um único arquivo?

Há quem diga simplesmente: "Pois esse é o padrão!".

Okay, é o padrão, mas o que significa isso?

Um padrão não surge ao acaso. Antes de se ter um padrão, teremos sempre um problema. Esse problema chama-se manutenção: Escrever código orientado a objetos é difícil, mas manter um código desorganizado é impossível (do ponto de vista do alto custo de manutenção).

Vamos imaginar a seguinte situação: Temos um sistema de armazenamento de arquivos, fazemos download do arquivo "class" de uma origem, depois fazemos o download do arquivo "class" de outra origem:

[neto@localhost namespace]$ ls
class  class(1)

Perceba que, para evitar a sobrescrita do identificador class, um nome diferente foi dado ao arquivo. Conforme as aplicações vão crescendo, identificadores homônimos vão se tornando cada vez mais prováveis e, resolver os problemas relacionados com colisão de nomes vão se tornando cada vez mais complexos. Porém, quando temos cada arquivo representando uma classe, fica mais fácil identificar o problema.

Imagine que tenhamos 2 diretórios: fruits e pasta:

Dentro do diretório fruits tenhamos os arquivos: Apple, Banana e Orange.
Dentro do diretório pasta tenhamos os arquivos: Capellini, Spaghetti e Penne.

[neto@localhost food]$ find
.
./pasta
./pasta/Capellini
./pasta/Penne
./pasta/Spaghetti
./fruits
./fruits/Apple
./fruits/Banana
./fruits/Orange

Perceba que, como os arquivos estão organizados, identificar algum problema é fácil. Não precisamos sair abrindo os arquivos que representam um namespace, basta listar os arquivos contidos em um diretório que representa um namespace que veremos as classes que estão contidas nesse namespace.

Porém, existe uma exceção à essa regra que justifica ter mais do que uma classe em um mesmo arquivo. Algumas vezes, uma abstração precisa oferecer uma implementação para uma operação e, quando apenas a abstração usa essa implementação, ela é feita no mesmo arquivo da abstração:

SomeInterface.php

<?php
namespace example;

interface SomeInterface {
public function doSomething();
}


Abstraction.php

<?php
namespace example;

abstract class Abstraction {
public abstract function helloWorld();

/**
* @return SomeInterface
*/
public function createSomething() {
return new SomeImplementation();
}
}

class SomeImplementation implements SomeInterface {
public function doSomething() {
echo 'Hello world!';
}
}


Concretion.php

<?php
namespace implementation;

use example\Abstraction;

class Concretion extends Abstraction {
public function helloWorld() {
$this->createSomething()->doSomething();
}
}


Como podemos ver, Concretion usa a implementação simples oferecida pela Abstraction, mas poderia também ter sua própria implementação. Como a interface SomeInterface está separada, Concretion pode ignorar a implementação simples oferecida por Abstraction e implementar SomeInterface para ter sua própria implementação.

Client.php

<?php
use example\Abstraction;

class Client {
public function usesAbstraction( Abstraction $a ) {
$a->helloWorld();
}
}


Para o Client, tanto faz quem ou como é implementado a operação helloWorld(), o Client apenas usa a operação e sequer tem conhecimento de que existe um outro participante envolvido. Nesses casos, quando uma implementação é oferecida por uma abstração e é usada somente por essa abstração, ter essa implementação no mesmo arquivo da abstração é completamente justificável.

Princípios de empacotamento:

Captei a idéia de vocês, seria reunir automaticamente todas as classes em um único arquivo somente para ambiente de produção. ^_^

Realmente interessante isso, mas somente se não forem muitas classes, se não como eu disse vai ter um desperdiço muito grande de memória aí.

Só espero que o mestre dos padrões (João Batista Neto) não arrance os seus cabelos ao ler este tópico. haha


Eu tenho créditos para arrancar os cabelos, quem já viu uma foto minha sabe do que estou falando. hehehe :P

Bom, agora chegamos na parte divertida da história, o empacotamento!!!

A primeira coisa que precisamos ter consciência aqui é que não existe mágica. Conforme a aplicação vai crescendo, a alta granularidade das classes pode se tornar um problema e, para isso, utilizamos um sistema de organização de nível mais alto. Um pacote é como uma caixa que contém vários recursos de um sistema, esses recursos devem ser agrupados de forma lógica e segundo alguns princípios.

:seta: Quem desenvolve aplicações orientadas a objetos e nunca ouviu falar de reutilização, que jogue o primeiro objeto.

Reutilização não é copiar um código de um lugar e colar em outro, reutilizar também não é fazer um clone um arquivo de um repositório para um projeto e utilizá-lo na aplicação. Reutilização é a capacidade de se utilizar um código sem precisar ler código. É a capacidade de se utilizar um código dependendo exclusivamente da abstração, sem precisar saber como é feita a implementação.

Sabemos que devemos depender de abstrações e não de implementações. E quando aos pacotes?

Quando utilizamos uma biblioteca empacotada, estamos utilizando as funcionalidades que ela oferece, por exemplo, eu desenvolvo um framework para construção de GUI:

Imagem Postada

Se eu empacotar esse framework e vendê-lo como uma biblioteca, o que você, como consumidor desse produto, espera?

Você espera que, caso eu lance uma nova versão dessa biblioteca, você possa se beneficiar dessa nova versão, você possa decidir entre utilizar a versão atual ou a nova versão, você espera ainda que a migração para a nova versão possa ocorrer apenas no momento que você tiver tempo disponível. De fato, você espera que possa utilizar essa versão apenas quando as mudanças que eu fiz na biblioteca interessarem à você.

Imagem Postada

Se você simplesmente copiar e colar um código que eu escrevi e usar na sua aplicação, você terá a preocupação em procurar as classes que eu modifiquei e fazer os ajustes necessários para que a nova versão funcione corretamente. Se eu fizer melhorias ou correções de bugs na biblioteca, você não será beneficiado de imediato por essas modificações. Com o tempo, muito possivelmente, sua versão será diferente da minha e, consequentemente, você deixará de se beneficiar dos novos recursos e bug fixes que eu fizer.

Mas, o que colocar em um pacote?

Esse problema já foi mencionado nesse tópico. Classes em um pacote são reutilizadas em conjunto, se você reutiliza uma classe de um pacote, você reutiliza todas. Esse deve ser o princípio base na hora de decidir o que colocar em um pacote. Se classes forem reutilizadas em conjunto, então elas deverão ser empacotadas em conjunto.

Como todo princípio, fica mais fácil perceber o fundamento quando estamos diante do problema, então, vamos ver um exemplo:

Imagem Postada

Perceba que, quando você for utilizar esse pacote, além de todas as classes de GUI, você estará utilizando também classes relacionadas com DBA, existe algum sentido nisso? Qual a relação existente entre um framework para construção de elementos de interface de usuário e um framework para abstração de bancos de dados?

Da mesma forma que temos o princípio da responsabilidade única (S.R.P.) para classes, temos o princípio da reutilização comum (C.R.P.) para pacotes, ou seja, um pacote precisa ser coeso. Se temos um pacote para construção de GUI, temos que ter dentro dele apenas coisas para construção de GUI.

O problema da falta de coesão é o mesmo que ocorre quando violamos o princípio da responsabilidade única. Quando uma nova versão da minha biblioteca é lançada, você terá que revalidar sua aplicação e ver se tudo está funcionando como deveria. Se eu empacoto coisas que não são coesas com o objetivo do pacote, uma mudança na minha camada de abstração com banco de dados poderá interferir na sua interface de usuário, ou seja, você será afetado por mudanças feitas em classes que você nem utiliza.

Manutenção de aplicações é cara, então é certo dizer que, mais importante que reutilização, é a manutenibilidade.

Uma mudança em uma classe do pacote afeta todas as classes do pacote então, de fato, classes em um pacote devem ser coesas, mas também precisam ser empacotadas de acordo com o tipo de mudança que elas sofrem. Se tivermos classes que mudam juntas, então elas devem ser empacotadas juntas, isso minimiza o esforço no processo de revalidação do sistema. Se tivermos N classes em um pacote e apenas 10 mudarem, todo o pacote precisará ser revalidado, por outro lado, se as 10 classes forem colocadas juntas em outro pacote, tudo fica mais simples.

Pacotes no PHP:

Desde a versão 5.3 o PHP introduziu nativamente os pacotes Phar. Um pacote Phar é, de certa forma, parecido com um pacote jar do Java.

Qual era a dúvida do tópico mesmo?

sendo que todas elas estariam dentro ou incluídas(include/require) em um único arquivo


hummmm....

What is phar? Phar archives are best characterized as a convenient way to group several files into a single file...


Então, além de já sabermos alguns princípios de empacotamento, temos uma solução nativa para o problema!!!

Vamos ver isso de perto, vamos empacotar nosso framework de gui:

[neto@localhost example]$ find com/imasters/gui
com/imasters/gui
com/imasters/gui/Component.php
com/imasters/gui/Composite.php
com/imasters/gui/Panel.php

Como podemos ver, temos 3 arquivos. Vamos escrever o código responsável pelo empacotamento:


<?php
$phar = new Phar( 'com.imasters.gui.phar' , 0 );
$phar->startBuffering();
$phar->buildFromIterator( new DirectoryIterator( 'com/imasters/gui' ) , '.' );
$phar->setStub( <<<'STUB'
<?php
Phar::interceptFileFuncs();

spl_autoload_register( function( $class ) {
$file = 'phar://' . __FILE__ . '/';
$file .= implode( DIRECTORY_SEPARATOR , explode( '\\' , $class ) );
$file .= '.php';

if ( is_file( $file ) ) {
require_once $file;
}
} );

__HALT_COMPILER();
STUB
);

$phar->stopBuffering();


O resultado disso é um arquivo chamado: com.imasters.gui.phar. Utilizando o arquivo:


<?php
require_once 'com.imasters.gui.phar';

use com\imasters\gui\Panel;

$p = new Panel();
$p->addAttribute( 'id' , 'example' );

echo $p->draw();


Resultado:
[neto@localhost example]$ php test.php 
<div id="example"></div>

O arquivo test.php faz o include apenas no pacote da biblioteca que contém todas as classes necessárias. Se distribuirmos esse pacote, qualquer pessoa poderá se beneficiar do framework de construção de GUI e, caso eu venha a lançar uma nova versão, bastará baixar a biblioteca e revalidar a aplicação.

De fato, empacotamento é um tema muito interessante (extenso também) e que será cada dia mais comum no universo PHP.

;)
  • 13


#1572696 Organizar código

Postado por João Batista Neto em 10 julho 2010 - 14:35

essa dúvida também não é para reinventar a roda, apenas, achar a melhor solução para melhorar a organização do código.


Bom, você está diante de duas situações, DRY e KISS

A boa notícia é que, se você enxergou isso, significa que você está começando a ver além.
A má notícia é que isso, invariavelmente, indica falta de planejamento e erro de modelagem.

Existem vários problemas no seu código, por exemplo:


class Recados {
private $_db;

public function __construct(){
$this->_db = Mysql::getInstance();
}
}


O fragmento acima é totalmente problemático, quase um crime; Quando um objeto conhece outro você fica dependente da implementação.

Você pode perguntar: Como assim ?

Bom, imagina que amanhã você, por qualquer motivo precise mudar de MySQL para Cassandra ou SQL Server ou Oracle, o que você vai fazer ??? Reescrever a aplicação ?
Ou ainda pior, vai utilizar cometer o maior crime que que um desenvolvedor pode cometer, vai utilizar Ctrl + C, Ctrl + V, criar uma cópia do arquivo, editar a cópia e substituir MySQL::getInstance() para Cassandra::getInstance() ???


public function insert($array) {
$this->_db->openConnection();

return $this->_db->insert("recados", $array);

$this->_db->closeConnection();
}


No fragmento acima, sua intensão era abrir conexão, inserir os dados, fechar conexão e retornar.

Ignorando o fato de que, o seu return interrompe a execução e, consequentemente, o método closeConnection() jamais será executado. Sua intensão era que a conexão fosse fechada e isso é um erro:

Onde está a persistência ???

Qual o sentido de se utilizar Singleton se você está abrindo e fechando a conexão nas operações de CRUD ???

Veja bem, expus os problemas acima de forma dura no sentido de "dar um chaqualhão" e o fiz exatamente porque, se você conseguiu ver que tem um problema é porque você está começando a dar um passo e é sempre melhor dar um passo na direção correta, que ter que dar dois passos para trás amanhã.

---------------------------

Vamos por partes agora:

Problema:

Você armazenará dados em algum lugar, hoje MySQL mas amanhã poderá ser em outro lugar. Para não ficar dependente da implementação e consequentemente ter que reescrever código, seus objetos jamais deverão conhecer o objeto de acesso a dados.

Solução:

Para que seus objetos não conheçam uns aos outros e, assim, garantir a abstração, você poderá utilizar um padrão de projeto de criação chamado AbstractFactory.

AbstractFactory http://forum.imaster...tyle_emoticons/default/seta.gif Criação

Conhecido também como:

Kit

Motivação:

Vários bancos de dados possuem formas diferentes para criar, ler, atualizar e excluir os dados, mesmo os bancos que trabalham com SQL, implementam essa sub linguagem de forma diferente, sem contar que as conexões diferem umas das outras. Quando você utiliza, em seus objetos, uma classe específica de banco de dados, você poderá ter um problema no futuro caso seja necessário mudar.
Se, em vez de instanciar uma classe específica, você utilizar uma classe abstrata que define uma interface para a criação dos objetos Connection e Statement, seus objetos jamais ficarão dependentes de uma implementação específica, na verdade, eles jamais saberão qual implementação você estará utilizando já que, de fato, eles estarão trabalhando com a interface de um objeto.

Estrutura:
Imagem Postada

Participantes:

AbstractFactory (AbstractConnection)

Declara a interface para criação dos produtos abstratos.

ConcreteFactory (MySQL, PgSQL)

Implementação de fábrica de produtos concretos.

AbstractProduct (AbstractConnector, AbstractStatement)

Declara a interface para os produtos abstratos.

ConcreteProduct (MySQLConnector, MySQLStatement, PgSQLConnector, PgSQLStatement)

Implementação dos produtos concretos.

Client

É o cara que vai usar tudo isso, sem saber o que estará utilizando.


Problema:

Você fará operações de CRUD, essas operações são, muitas vezes diferentes para bancos de dados diferentes. Imagine que você vá paginar algum resultado, ai você modela sua aplicação pensando em MySQL e, amanhã, muda seu banco de dados para SQL Server; Como você modelou sua aplicação totalmente dependente da implementação de paginação em MySQL, você será obrigado a reescrever código para adaptar ao novo banco de dados.

Solução:

Para não ficar dependente da sub linguagem SQL e ter problemas com implementações diferentes dela em bancos diferente ou, se você for trabalhar com outro mecanismo de armazenamento que não usa SQL, você deve abstrair o SQL das operações de CRUD. Nesse caso, você pode utilizar um padrão de projeto comportamental chamado Interpreter; Na verdade, não será o Interpreter que você deverá utilizar, mas uma derivação dele, conhecida como Criteria.

Interpreter http://forum.imaster...tyle_emoticons/default/seta.gif Comportamental

Intensão:

Definir uma representação da gramática de uma determinada linguagem.

Estrutura:

Imagem Postada

Você também disse:

meu medo também e estar programando de forma "procedural" e achando que estou programando em objetos.


E logo após veio com:

 Recados::find();
 Recados::select("WHERE id=10 ORDER BY titulo ASC")


Perceba que seu código, apesar de estar organizado dentro de uma classe, é totalmente procedural; Cade o objeto ???

Bom, aqui vai um exemplo de código para abstração do banco de dados e do SQL:

Interfaces:

AbstractConnectorConfig.php

<?php
/**
* Interface para configuração de uma conexão com banco de dados
*/
abstract class AbstractConnectorConfig {
/**
* Servidor
* @var string
*/
private $host;

/**
* Nome do banco
* @var string
*/
private $name;

/**
* Senha de conexão
* @var string
*/
private $pswd;

/**
* Usuário de conexão
* @var string
*/
private $user;

/**
* Constroi um objeto de configuração de conexão
* @param string $host Servidor de banco de dados
* @param string $name Nome do banco de dados
* @param string $user Usuário de conexão
* @param string $pswd Senha de conexão
*/
public function __construct( $host , $name , $user = null , $pswd = null ){
$this->host = $host;
$this->name = $name;
$this->user = $user;
$this->pswd = $pswd;
}

/**
* Recupera o servidor de banco de dados
* @return string
*/
public function getHost(){
return $this->host;
}

/**
* Recupera o nome do banco de dados
* @return string
*/
public function getName(){
return $this->name;
}

/**
* Recupera o usuário de conexão com o banco de dados
* @return string
*/
public function getUser(){
return $this->user;
}

/**
* Recupera a senha de conexão com o banco de dados
* @return string
*/
public function getPswd(){
return $this->pswd;
}

/**
* Recupera a string de conexão com o banco de dados
* @return string
*/
abstract public function getDSN();
}


StatementExpression.php

<?php
/**
* Interface para expressão de uma operação com banco de dados
*/
interface StatementExpression {
/**
* Interpreta a expressão
* @param Connector $connector
*/
public function interpret( Connector $connector );
}


Statement.php

<?php
/**
* Interface para uma operação com banco de dados
*/
interface Statement extends StatementExpression, IteratorAggregate {
/**
* Recupera uma linha do resultado
* @return stdClass
*/
public function fetch();

/**
* Recupera um Iterator com todas as linhas do resultado
* @return Iterator
*/
public function fetchAll();

/**
* Define a classe que será utilizada para instanciar o Iterator
* retornado por getIterator() e fetchAll()
* @param string $class A classe que implementa Iterator
* @see IteratorAggregate::getIterator()
*/
public function setIteratorClass( $class );
}


AbstractStatement.php

<?php
/**
* Base para definição de uma operação com banco de dados
*/
abstract class AbstractStatement implements Statement {
/**
* @var string
*/
private $iteratorClass = 'ArrayIterator';

/**
* Recupera uma instância do Iterator
* @param array $params Lista de parâmetros que serão passados à instância do Iterator
* @return Iterator
*/
protected function createIteratorInstance( array $params ){
$reflection = new ReflectionClass( $this->iteratorClass );

return $reflection->newInstanceArgs( $params );
}

/**
* Recupera um Iterator para as linhas do resultado
* @return Iterator
*/
public function getIterator(){
$iterator = $this->fetchAll();

if ( $iterator instanceOf Iterator ){
return $iterator;
} else {
throw new UnexpectedValueException( sprintf( '%s::fetchAll() deve retornar um Iterator.' , get_class( $this ) ) );
}
}

/**
* Define a classe que será utilizada para instanciar o Iterator
* retornado por getIterator() e fetchAll()
* @param string $class A classe que implementa Iterator
* @see IteratorAggregate::getIterator()
*/
public function setIteratorClass( $class ){
if ( in_array( 'Iterator' , class_implements( $class , false ) ) ){
$this->iteratorClass = $class;
} else {
throw new LogicException( sprintf( 'A classe %s deve implementar a interface Iterator.' , $class ) );
}
}
}


Connector.php

<?php
/**
* Interface para definição de um conector com banco de dados
*/
interface Connector {
/**
* Inicia uma transação
* @return boolean
*/
public function beginTransaction();

/**
* Grava a transação
* @return boolean
*/
public function commit();

/**
* Executa uma operação no banco de dados
* @param Statement $statement
* @return boolean
*/
public function execute( Statement $statement );

/**
* Recupera o último ID gerado por uma operação de INSERT
* @return integer
*/
public function lastInsertId();

/**
* Abra a conexão
* @param AbstractConnectorConfig $config
* @return boolean
*/
public function open( AbstractConnectorConfig $config );

/**
* Adiciona aspas em uma string se necessário
* @param string $string
* @param integer $type O tipo de dado
* @return string
*/
public function quote( $string , $type );

/**
* Volta as modificações causadas por uma transação
* @return boolean
*/
public function rollBack();
}


ConnectionFactory.php

<?php
/**
* Interface para uma fábrica de objetos relacionados com banco de dados
*/
interface ConnectionFactory {
/**
* Cria um objeto que representa o operador lógico AND
* @param StatementExpression $lside Lado esquerdo da operação
* @param StatementExpression $rside Lado direito da operação
* @return StatementExpression
*/
public function createAndExpression( StatementExpression $lside , StatementExpression $rside );

/**
* Cria um objeto que representa uma operação de definição de valor
* @param StatementExpression $lside Lado esquerdo da operação
* @param StatementExpression $rside Lado direito da operação
* @return StatementExpression
*/
public function createAssignmentExpression( StatementExpression $lside , StatementExpression $rside );

/**
* Cria um objeto de conexão com banco de dados
* @param string $key Chave de identificação da conexão
* @param AbstractConnectorConfig $config Dados de configuração da conexão
* @return Connector
*/
public function createConnector( $key , AbstractConnectorConfig $config );

/**
* Cria uma operação de comparação de igualdade
* @param StatementExpression $lside Lado esquerdo da operação
* @param StatementExpression $rside Lado direito da operação
* @return StatementExpression
*/
public function createEqualExpression( StatementExpression $lside , StatementExpression $rside );

/**
* Cria um objeto que representa um campo
* @param string $field Nome do campo
* @return StatementExpression
*/
public function createFieldExpression( $field );

/**
* Cria um objeto que representa uma tabela do banco
* @param string $from Nome da tabela
* @return StatementExpression
*/
public function createFromExpression( $from );

/**
* Cria um objeto que representa um valor numérico
* @param float $number
* @return StatementExpression
*/
public function createNumberExpression( $number );

/**
* Cria um objeto que representa uma string
* @param string $string
* @return StatementExpression
*/
public function createStringExpression( $string );

/**
* Cria um objeto para leitura do banco de dados
* @param StatementExpression $field
* @param StatementExpression $_
* @return StatementExpression
*/
public function createReadExpression( StatementExpression $field , StatementExpression $_ );

/**
* Cria objeto que representa uma condição
* @param StatementExpression $where
* @return StatementExpression
*/
public function createWhereExpression( StatementExpression $where );
}



Implementação MySQL:

MySQLConnectorConfig.php

<?php
/**
* Implementação de configuração de conexão para o banco de dados MySQL
*/
class MySQLConnectorConfig extends AbstractConnectorConfig {
/**
* Recupera a string de conexão com o banco de dados
* @return string
*/
public function getDSN(){
return sprintf( 'mysql:host=%s;dbname=%s' , $this->getHost() , $this->getName() );
}
}


MySQLStatement.php

<?php
/**
* Interface para definição de uma operação para banco de dados MySQL
*/
abstract class MySQLStatement extends AbstractStatement {
/**
* @var PDOStatement
*/
protected $pdoStatement;

/**
* Recupera uma linha do resultado
* @return stdClass
*/
public function fetch(){
throw new BadMethodCallException( sprintf( '%s não implementa fetch().' , get_class( $this ) ) );
}

/**
* Recupera um Iterator com todas as linhas do resultado
* @return Iterator
*/
public function fetchAll(){
throw new BadMethodCallException( sprintf( '%s não implementa fetchAll().' , get_class( $this ) ) );
}

/**
* Define o objeto PDOStatement
* @param PDOStatement $statement
*/
public function setPDOStatement( PDOStatement $statement ){
$this->pdoStatement = $statement;
}

/**
* Verifica se já temos um objeto PDOStatement
* @return boolean
* @throws RuntimeException Se ainda não tivermos o objeto
*/
protected function testPDOStatement(){
if ( ( $null = is_null( $this->pdoStatement ) ) == true ) throw new RuntimeException( 'A operação ainda não foi executada.' );

return !$null;
}
}


MySQLFieldExpression.php

<?php
/**
* Implementação para um campo da tabela
*/
class MySQLFieldExpression implements StatementExpression {
/**
* @var string
*/
private $name;

/**
* Constroi um novo objeto que representa um campo de uma tabela MySQL
* @param string $name Nome do campo da tabela.<p>
* Se deixado em branco * será utilizado</p>
*/
public function __construct( $name = null ){
$this->name = empty( $name ) ? '*' : (string) $name;
}

/**
* Interpreta a expressão
* @param Connector $connector
*/
public function interpret( Connector $connector ){
return $this->name == '*' ? '*' : sprintf( '`%s`' , $this->name );
}
}


MySQLFromExpression.php

<?php
/**
* Implementação para uma tabela
*/
class MySQLFromExpression implements StatementExpression {
/**
* @var string
*/
private $name;

/**
* Constroi um novo objeto que representa o nome de uma tabela MySQL
* @param string $name O nome da tabela
*/
public function __construct( $name ){
$this->name = $name;
}

/**
* Interpreta a expressão
* @param Connector $connector
*/
public function interpret( Connector $connector ){
return sprintf( '`%s`' , $this->name );
}
}


MySQLSelectStatement.php

<?php
/**
* Implementação de uma expressão SELECT para um banco de dados MySQL
*/
class MySQLSelectStatement extends MySQLStatement {
/**
* @var array
*/
private $fields;

/**
* @var MySQLFromExpression
*/
private $from;

/**
* @var StatementExpression
*/
private $where;

/**
* Cria um objeto que representa a instrução SELECT para um banco de dados MySQL
* @param MySQLFieldExpression $field Campo que será retornado
* @param MySQLFieldExpression $_
*/
public function __construct( MySQLFieldExpression $field , MySQLFieldExpression $_ = null ){
$fields = func_get_args();
$this->fields = array();

foreach ( $fields as $field ){
if ( $field instanceOf MySQLFieldExpression ){
$this->fields[] = $field;
} else {
throw new InvalidArgumentException( 'Os campos devem ser instâncias de MySQLFieldExpression.' );
}
}
}

/**
* Recupera uma linha do resultado
* @return stdClass
*/
public function fetch(){
if ( $this->testPDOStatement() ){
return $this->pdoStatement->fetch( PDO::FETCH_OBJ );
}
}

/**
* Recupera um Iterator com todas as linhas do resultado
* @return Iterator
*/
public function fetchAll(){
if ( $this->testPDOStatement() ){
return $this->createIteratorInstance( array( $this->pdoStatement->fetchAll( PDO::FETCH_OBJ ) ) );
}
}

/**
* Define a tabela de onde os resultados serão buscados
* @param MySQLFromExpression $from
*/
public function from( MySQLFromExpression $from ){
$this->from = $from;
}

/**
* Interpreta a expressão
* @param Connector $connector
*/
public function interpret( Connector $connector ){
$fields = array();

foreach ( $this->fields as $field ){
$fields[] = $field->interpret( $connector );
}

$select = sprintf( 'SELECT %s FROM %s' , implode( ',' , $fields ) , $this->from->interpret( $connector ) );

if ( !is_null( $this->where ) ){
$select .= sprintf( ' %s' , $this->where->interpret( $connector ) );
}

return $select;
}

/**
* Define uma condição para o SELECT
* @param WhereExpression $where
*/
public function where( WhereExpression $where ){
$this->where = $where;
}
}


LRExpression.php

<?php
/**
* Base para implementação de uma expressão de dois lados
*/
abstract class LRExpression implements StatementExpression {
/**
* @var StatementExpression
*/
protected $lside;

/**
* @var StatementExpression
*/
protected $rside;

/**
* Constroi um objeto para um operador AND
* @param StatementExpression $lside Lado esquerdo da operação
* @param StatementExpression $rside Lado direito da operação
*/
public function __construct( StatementExpression $lside , StatementExpression $rside ){
$this->lside = $lside;
$this->rside = $rside;
}
}


AndExpression.php

<?php
/**
* Implementação de um operador AND
*/
class AndExpression extends LRExpression {
/**
* Interpreta a expressão
* @param Connector $connector
*/
public function interpret( Connector $connector ){
return sprintf( '(%s AND %s)' , $this->lside->interpret( $connector ) , $this->rside->interpret( $connector ) );
}
}


AssignmentExpression.php

<?php
/**
* Implementação de um operador de definição ou igualdade
*/
class AssignmentExpression extends LRExpression {
/**
* Interpreta a expressão
* @param Connector $connector
*/
public function interpret( Connector $connector ){
return sprintf( '(%s = %s)' , $this->lside->interpret( $connector ) , $this->rside->interpret( $connector ) );
}
}


WhereExpression.php

<?php
/**
* Implementação de uma condição WHERE
*/
class WhereExpression implements StatementExpression {
/**
* @var StatementExpression
*/
private $where;

/**
* Constroi um objeto que representa uma condição
* @param StatementExpression $where
*/
public function __construct( StatementExpression $where ){
$this->where = $where;
}

/**
* Interpreta a expressão
* @param Connector $connector
*/
public function interpret( Connector $connector ){
return sprintf( 'WHERE %s' , $this->where->interpret( $connector ) );
}
}


StringExpression.php

<?php
/**
* Implementação de uma string
*/
class StringExpression implements StatementExpression {
/**
* @var string
*/
private $string;

/**
* Constroi uma nova string
* @param string $string
*/
public function __construct( $string ){
$this->string = (string) $string;
}

/**
* Interpreta a expressão
* @param Connector $connector
*/
public function interpret( Connector $connector ){
return $connector->quote( $this->string , PDO::PARAM_STR );
}
}


NumberExpression.php

<?php
/**
* Implementação de um número
*/
class NumberExpression implements StatementExpression {
/**
* @var float
*/
private $number;

/**
* Constroi um novo objeto que representa um número
* @param float $number
*/
public function __construct( $number ){
$float = (float) $number;

if ( (int) $float == (int) $number ){
$this->number = (int) $number;
} else {
$this->number =& $float;
}
}

/**
* Interpreta a expressão
* @param Connector $connector
*/
public function interpret( Connector $connector ){
return (string) $this->number;
}
}


MySQLConnector.php

<?php
/**
* Implementação de um conector com banco de dados MySQL
*/
class MySQLConnector implements Connector {
/**
* @var PDO
*/
private $pdo;

/**
* Inicia uma transação
* @return boolean
*/
public function beginTransaction(){
if ( $this->testPDO() ){
return $this->pdo->beginTransaction();
}
}

/**
* Grava a transação
* @return boolean
*/
public function commit(){
if ( $this->testPDO() ){
return $this->pdo->commit();
}
}

/**
* Executa uma operação no banco de dados
* @param Statement $statement
* @return boolean
* @throws RuntimeException Se não for possível executar a operação
*/
public function execute( Statement $statement ){
if ( $statement instanceOf MySQLStatement ){
if ( $this->testPDO() ){
try {
$stm = $this->pdo->query( $statement->interpret( $this ) );

if ( $stm !== false ){
$statement->setPDOStatement( $stm );
} else {
throw new RuntimeException( 'Não foi possível executar a operação.' );
}
} catch ( PDOException $e ){
throw new RuntimeException( 'Não foi possível executar a operação.' , $e->getCode() , $e );
}
}
} else {
throw new UnexpectedValueException( sprintf( 'Esperamos uma instância de MySQLStatement, %s foi dado.' , get_class( $statement ) ) );
}

return true;
}

/**
* Recupera o último ID gerado por uma operação de INSERT
* @return integer
*/
public function lastInsertId(){
if ( $this->testPDO() ){
return $this->pdo->lastInsertId();
}
}

/**
* Abra a conexão
* @param AbstractConnectorConfig $config
* @return boolean
* @throws RuntimeException Se não for possível estabelecer a conexão
*/
public function open( AbstractConnectorConfig $config ){
try {
$this->pdo = new PDO( $config->getDSN() , $config->getUser() , $config->getPswd() );
$this->pdo->setAttribute( PDO::ATTR_ERRMODE , PDO::ERRMODE_EXCEPTION );
} catch ( PDOException $e ){
throw new RuntimeException( 'Não foi possível estabelecer a conexão com o banco de dados.' , $e->getcode() , $e );
}

return true;
}

/**
* Adiciona aspas em uma string se necessário
* @param string $string
* @param integer $type O tipo de dado
* @return string
*/
public function quote( $string , $type = null ){
if ( $this->testPDO() ){
return $this->pdo->quote( $string , $type );
}
}

/**
* Volta as modificações causadas por uma transação
* @return boolean
*/
public function rollBack(){
if ( $this->testPDO() ){
return $this->pdo->rollBack();
}
}

/**
* Verifica se a conexão já foi aberta
* @return boolean
* @throws RuntimeException Se a conexão ainda não tiver sido aberta
*/
private function testPDO(){
if ( ( $null = is_null( $this->pdo ) ) == true ) throw new RuntimeException( 'A conexão ainda não foi aberta.' );

return !$null;
}
}


MySQL.php

<?php
/**
* Implementação de uma fábrica de objetos relacionados com banco de dados MySQL
*/
class MySQL implements ConnectionFactory {
/**
* Lista de conectores
* @var array
*/
private $connections = array();

/**
* Cria um objeto que representa o operador lógico AND
* @param StatementExpression $lside Lado esquerdo da operação
* @param StatementExpression $rside Lado direito da operação
* @return StatementExpression
*/
public function createAndExpression( StatementExpression $lside , StatementExpression $rside ){
return new AndExpression( $lside , $rside );
}

/**
* Cria um objeto que representa uma operação de definição de valor
* @param StatementExpression $lside Lado esquerdo da operação
* @param StatementExpression $rside Lado direito da operação
* @return StatementExpression
*/
public function createAssignmentExpression( StatementExpression $lside , StatementExpression $rside ){
return new AssignmentExpression( $lside , $rside );
}

/**
* Cria um objeto de configuração de conexão
* @param string $host Servidor de banco de dados
* @param string $name Nome do banco de dados
* @param string $user Usuário de conexão
* @param string $pswd Senha de conexão
*/
public function createConnectionConfig( $host , $name , $user = null , $pswd = null ){
return new MySQLConnectorConfig( $host , $name , $user , $pswd );
}

/**
* Cria um objeto de conexão com banco de dados
* @param string $key Chave de identificação da conexão
* @param AbstractConnectorConfig $config Dados de configuração da conexão
* @return Connector
*/
public function createConnector( $key , AbstractConnectorConfig $config ){
if ( !$this->hasConnector( $key ) ){
$this->connections[ $key ] = new MySQLConnector();
$this->connections[ $key ]->open( $config );
}

return $this->connections[ $key ];
}

/**
* Cria uma operação de comparação de igualdade
* @param StatementExpression $lside Lado esquerdo da operação
* @param StatementExpression $rside Lado direito da operação
* @return StatementExpression
*/
public function createEqualExpression( StatementExpression $lside , StatementExpression $rside ){
return new AssignmentExpression( $lside , $rside );
}

/**
* Cria um objeto que representa um campo
* @param string $field Nome do campo
* @return StatementExpression
*/
public function createFieldExpression( $field ){
return new MySQLFieldExpression( $field );
}

/**
* Cria um objeto que representa uma tabela do banco
* @param string $from Nome da tabela
* @return StatementExpression
*/
public function createFromExpression( $from ){
return new MySQLFromExpression( $from );
}

/**
* Cria um objeto que representa um valor numérico
* @param float $number
* @return StatementExpression
*/
public function createNumberExpression( $number ){
return new NumberExpression( $number );
}

/**
* Cria um objeto que representa uma string
* @param string $string
* @return StatementExpression
*/
public function createStringExpression( $string ){
return new StringExpression( $string );
}

/**
* Cria um objeto para leitura do banco de dados
* @param StatementExpression $field
* @param StatementExpression $_
* @return StatementExpression
*/
public function createReadExpression( StatementExpression $field , StatementExpression $_ = null ){
$reflection = new ReflectionClass( 'MySQLSelectStatement' );

return $reflection->newInstanceArgs( func_get_args() );
}

/**
* Cria objeto que representa uma condição
* @param StatementExpression $where
* @return StatementExpression
*/
public function createWhereExpression( StatementExpression $where ){
return new WhereExpression( $where );
}

/**
* Recupera uma conexão já aberta
* @param string $key Chave de identificação da conexão
* @return Connector
*/
public function getConnection( $key = null ){
if ( is_null( $key ) && count( $this->connections ) ){
return current( $this->connections );
} elseif ( $this->hasConnector( $key ) ){
return $this->connections[ $key ];
} else {
throw new RuntimeException( sprintf( 'Não existe uma conexão para a chave %s.' , $key ) );
}
}

/**
* Verifica se uma conexão já existe para a chave informada
* @param string $key
* @return boolean
*/
public function hasConnector( $key ){
return isset( $this->connections[ $key ] );
}
}


Com isso ai, não importa se você estiver utilizando MySQL, PgSQL, SQL Server, Oracle, Cassandra ou qualquer quer seja o sistema de armazenamento, pode até ser um XML se for o objetivo de sua aplicação, já que todos os objetos foram abstraídos:


<?php
$factory = new MySQL(); //Esse cara pode ser mudado para Oracle ou Cassandra que sua aplicação nem saberá o que aconteceu

/**
* Cria o conector
*/
$connector = $factory->createConnector( 'mydb' , $factory->createConnectionConfig( '127.0.0.1' , 'bancodedados' , 'usuario' , 'senha' ) );

/**
* Cria um SELECT usando a fábrica para criar o objeto e os campos que serão utilizados (id e nome)
*/
$statement = $factory->createReadExpression( $factory->createFieldExpression( 'id' ) , $factory->createFieldExpression( 'nome' ) );

/**
* Adiciona ao SELECT a cláusula FROM para a tabela Usuarios
*/
$statement->from( $factory->createFromExpression( 'Users' ) );

/**
* Adiciona ao SELECT algumas condições
*/
$statement->where( $factory->createWhereExpression( $factory->createEqualExpression( $factory->createFieldExpression( 'id' ) , $factory->createNumberExpression( 20 ) ) ) );

/**
* Executa a consulta
*/
if ( $connector->execute( $statement ) ){
foreach ( $statement as $row ){
var_dump( $row );
}
}


Agora, tudo o que você precisará é passar a fábrica para seus objetos ORM:


<?php
abstract class TableDataGateway {
protected $factory;

public function __construct( ConnectionFactory $factory ) {
$this->factory = $factory;
}

protected function read( array $fields = null ) {
if ( !is_null( $fields ) ) {
foreach ( $fields as $key => $field ) {
$fields[ $key ] = $this->factory->createFieldExpression( $field );
}

$statement = call_user_func_array( array( $this->factory , 'createReadExpression' ) , $fields );
} else {
$statement = $this->factory->createReadExpression( $this->factory->createFieldExpression( '*' ) );
}

$statement->from( $this->factory->createFromExpression( get_class( $this ) ) );

return $statement;
}
}

class Users extends TableDataGateway {
public function getUserList() {
$stm = $this->read();

$this->factory->getConnection()->execute( $stm );

return $stm;
}
}


E para usar:

<?php
$factory = new MySQL();
$factory->createConnector( null , $factory->createConnectionConfig( '127.0.0.1' , 'seubancodedados' , 'usuario' , 'senha' ) );

$users = new Users( $factory );

foreach ( $users->getUserList() as $user ) {
var_dump( $user );
}


;)
  • 13


#1817076 Como pensar em Orientação a Objetos

Postado por João Batista Neto em 07 março 2012 - 08:28

Como que elas (e eu) aprenderão(ei) sobre um Padrão de Projeto se 98% das vezes eles são explicados através desses diagramas?

Se a pessoa não entende um Diagrama, vai simplesmente ignorá-lo e perguntas que para uns que entendem da modelagem poderão parecer estúpidas, servirão apenas para constranger quem quer aprender.


Não entendo como alguém pode se sentir constrangido por querer aprender, ninguém nasce sabendo, EU pelo menos não nasci sabendo.

:seta: Se existe a oportunidade de se perguntar, pergunte!

Os diagramas utilizados nas representações estruturais dos padrões de design, muitas vezes são feitos utilizando os disgramas de classe especificados pela UML. A ideia dos diagramas de classe é mostrar os participantes e seus relacionamentos, veja só:

Imagem Postada

O bloco quadrado ai em cima representa uma classe, ela pode ser concreta ou abstrata. A diferença entre os participantes concretos e abstratos está na forma que o nome do participante está escrito, por exemplo:

Imagem Postada

Como pode ver, BrunoAugusto é um participante concreto, enquanto ForumMember é um participante abstrato e está escrito em itálico. O código que representa esses dois participantes, em PHP, é assim:

BrunoAugusto.php

<?php
class BrunoAugusto {
}


ForumMember.php

<?php
abstract class ForumMember {
}


Além de classes abstratas, podemos representar interfaces no diagrama também:

Imagem Postada

O <<interface>> identifica claramente esse participante. Usamos a notação de classe (o quadrado acima) para representar uma interface em um diagrama, quando o uso de algum dos métodos dela é relevante. Se não for tão relevante, podemos utilizar uma bolinha:

Imagem Postada

O código PHP que representa essas duas interfaces é:

List.php

<?php
interface List {
}


OtherInterface.php

<?php
interface OtherInterface {
}


Classes podem ter membros, como propriedades ou métodos:

Imagem Postada

Os sinais - e # são utilizados para representar a visibilidade de um membro, no caso -propriedadePrivada representa uma propriedade com visibilidade private, veja:

UmaClasse.php

<?php
class UmaClasse {
/**
* @var string
*/
public $propriedadePublica;

/**
* @var string
*/
private $propriedadePrivada;

/**
* @var string
*/
protected $propriedadeProtegida;
}


O mesmo ocorre com os métodos:

Imagem Postada

UmaClasse.php

<?php
class UmaClasse {
/**
* @var string
*/
public $propriedadePublica;

/**
* @var string
*/
private $propriedadePrivada;

/**
* @var string
*/
protected $propriedadeProtegida;

/**
* @return string
*/
public function operacaoPublica() {
return $this->propriedadePublica;
}

/**
* @return string
*/
private function operacaoPrivada() {
return $this->propriedadePrivada;
}

/**
* @return string
*/
protected function operacaoProtegida() {
return $this->propriedadeProtegida;
}
}


Quando precisamos generalizar um determinado participante, utilizamos uma seta com um triângulo na ponta:

Imagem Postada

Esse tipo de relacionamento chama-se IS A, ou É UM, o código que esse diagrama representa é:


<?php
abstract class CrazyPeople {
}

class BrunoAugusto extends CrazyPeople {
}


Podemos utilizar esse relacionamento tanto com classes abstratas (como no exemplo acima), quanto com classes concretas ou interfaces:

Imagem Postada

O código PHP fica assim:


<?php
abstract class ClasseAbstrata {
}

class ClasseConcreta extends ClasseAbstrata {
}

interface UmaInterface {
}

class OutraClasseConcreta extends ClasseConcreta implements UmaInterface {
}


Eu já ilustrei os outros relacionamentos que temos (associação, agregação e composição), então não vou falar de todos eles, mas veja só:

Imagem Postada

Esse diagrama se lê assim:

Empresa está associada com 1 ou vários Profissional. Tanto Diretor quanto Gerente são Profissional, que podem ser contratados pela Empresa e esse relacionamento se dá pela propriedade privada profissionais e pelo método público contrata.

O código do diagrama acima fica assim:


<?php
interface Profissional {
}

class Diretor implements Profissional {
}

class Gerente implements Profissional {
}

class Empresa {
/**
* @var array[Profissional]
*/
private $profissionais = array();

/**
* @param Profissional $profissional
*/
public function contrata( Profissional $profissional ) {
$this->profissionais[] = $profissional;
}
}


Viu, é simples, não tem muita coisa um diagrama de classes.
  • 12


#633076 Script para paginação bem simples

Postado por wolfphw em 05 setembro 2006 - 16:59

Bem como eu vi tem muita gente que pega uns scripts de paginação e acabam penando numas partes...

Entaum eu fiz um script bem simplificado para qualquer um poder utilizar sem problemas...

Ele é dividido em 2 arquivos... um que é o arquivo onde você vai fazer a sua consulta SQL e outro é o que monta a paginação....


pagina.php
<?php//######### INICIO Paginação	$numreg = 40; // Quantos registros por página vai ser mostrado	if (!isset($pg)) {		$pg = 0;	}	$inicial = $pg * $numreg;	//######### FIM dados Paginação		// Faz o Select pegando o registro inicial até a quantidade de registros para página	$sql = mysql_query("SELECT * FROM tabela LIMIT $inicial, $numreg");	// Serve para contar quantos registros você tem na seua tabela para fazer a paginação	$sql_conta = mysql_query("SELECT * FROM tabela");		$quantreg = mysql_num_rows($sql_conta); // Quantidade de registros pra paginação		include("paginacao.php"); // Chama o arquivo que monta a paginação. ex: << anterior 1 2 3 4 5 próximo >>		echo "<br><br>"; // Vai servir só para dar uma linha de espaço entre a paginação e o conteúdo		while ($aux = mysql_fetch_array($sql)) {		/* Ai o resto é com voces em montar como deve parecer o conteúdo */	}?>


paginacao.php
<style type="text/css"><!--.pgoff {font-family: Verdana, Arial, Helvetica; font-size: 11px; color: #FF0000; text-decoration: none}a.pg {font-family: Verdana, Arial, Helvetica; font-size: 11px; color: #003366; text-decoration: none}a:hover.pg {font-family: Verdana, Arial, Helvetica; font-size: 11px; color: #0066cc; text-decoration:underline}--></style><?php	$quant_pg = ceil($quantreg/$numreg);	$quant_pg++;		// Verifica se esta na primeira página, se nao estiver ele libera o link para anterior	if ( $pg > 0) { 		echo "<a href=".$PHP_SELF."?pg=".($pg-1) ."class=pg><b>&laquo; anterior</b></a>";	} else { 		echo "<font color=#CCCCCC>&laquo; anterior</font>";	}		// Faz aparecer os numeros das página entre o ANTERIOR e PROXIMO	for($i_pg=1;$i_pg<$quant_pg;$i_pg++) { 		// Verifica se a página que o navegante esta e retira o link do número para identificar visualmente		if ($pg == ($i_pg-1)) { 			echo "&nbsp;<span class=pgoff>[$i_pg]</span>&nbsp;";		} else {			$i_pg2 = $i_pg-1;			echo "&nbsp;<a href=".$PHP_SELF."?pg=$i_pg2 class=pg><b>$i_pg</b></a>&nbsp;";		}	}		// Verifica se esta na ultima página, se nao estiver ele libera o link para próxima	if (($pg+2) < $quant_pg) { 		echo "<a href=".$PHP_SELF."?pg=".($pg+1)." class=pg><b>próximo &raquo;</b></a>";	} else { 		echo "<font color=#CCCCCC>próximo &raquo;</font>";	}?>

  • 11


#314915 Módulo 01

Postado por Fabyo em 28 fevereiro 2005 - 01:23

Curso de PHP

Módulo 1

Introdução

o O que é PHP?
o Pra que serve o PHP?
o Como funciona o PHP?
o Dicas úteis na hora de programar
o Variáveis
o Operadores
o Exercícios

O que é PHP?

PHP significa Personal Home Page ou Hypertext Preprocessor, é uma linguagem de script Open Source
E ela não precisa ser compilada, o PHP é executado no servidor e é processado na hora que a página for executada.

Pra que serve o PHP?

Para o desenvolvimento de aplicações Web ou sistemas intranet.
E o PHP conecta com diversos bancos de dados
O PHP também faz sistemas de controles statisticos, bate papos, fórum, portais, enquetes, blogs, entre outros sistemas conhecidos.

Como Funciona o PHP?

O PHP funciona sendo executado por um programa servidor web configurado com o PHP como CGI ou filtro isapi e o PHP processa a página e envia apenas o resultado do processo em HTML para o usuário

CGI - Commom Gateway Interface (Interface Comum de Gateway) é uma interface definida de maneira a possibilitar a execução de programas sob um servidor

ISAPI é uma DLL personalizada que está no mesmo espaço de memória que o servidor Web, e é chamado pelo servidor da web em resposta a cada solicitação HTTP.

O PHP só é interpretado dentro das tags simples <? ?> ou <?PHP ?> para suporte a XML ou XHTML
O PHP também funciona com essas tag:

<script language = "php">
Código...   
</script>

O PHP também funciona com tags ASP: <% %>

Uma página em PHP tem que ter a extensão .php
Se não for usar nenhuma tag PHP na página deixa a com .html
Daí o PHP não precisara ficar lendo essa página em busca de tags php

e no final de cada linha você precisa usar um ;( ponto e vírgula ) idêntico à linguagem C

echo() é construtor da linguagem ele serve para exibir algo na tela e não é obrigatório usar parênteses ().

Use ' ( Apóstrofos ) para delimitar a string( textos ) do seu script exemplo:
<?PHP echo 'ola mundo'; ?>
ou modo simples para uma linha:<?= 'ola mundo'; ?>
As " ( aspas ) se a string é delimitada entre " ( aspas ), o PHP entende mais seqüências de escape para caracteres especiais:
\n = nova linha
\r retorno da linha
\t tab
Também da para delimitar as string usando a sintaxe heredoc ("<<<") exemplo:

[quote]$string = <<<EOD
Exemplo de uma string
distribuída em várias linhas
utilizando a sintaxe heredoc.
EOD;[/quote]

Embutido dentro do HTML:

[quote]<html>
<head>
<title>Titulo</title>
</head>
<body>
<?php
echo "ola mundo";
?>
</body>
</html>
</font>[/quote]

Ou você pode dar um echo nas tags HTML dentro do PHP exemplo:

[quote]<?php

echo "<b>PHP</b>";

?>[/quote]

[quote]<?php

echo "<a href=\"link.html\">Link</a>";

?>[/quote]

Dicas uteis na hora de programar

Para desenvolver um script e evitar erros

Programe com essas opções no php.ini:

[quote]display_errors = on => deixa ativado a opção para exibir mensagens de erro ou alertas e avisos sobre alguma coisa que esta errada
display_startup_errors = On => use essa opção em on só na hora que estiver desenvolvendo seus script ,tem erros que são iniciados e o display_errors não mostra
error_reporting = E_ALL => mostra todos possíveis erros
register_globals = off => a partir do PHP 4.2.0 passou a se usar ela em off por motivo de seguranças

exit; serve para a execução do script ,então use o exit sempre que quiser debugar seu script, ou em funções e estruturas de controles
outras dicas nunca esqueça de colocar o ; ( ponto e vírgula ) no final de cada linha[/quote]

e sempre usar as aspas ou apostrofos em string exemplos:

$nome = "Mario"; 
$array['array1'];
$_POST['campo'];
echo "Bom estudo";


Variáveis

As variáveis no PHP são representadas por um cifrão ($) seguido pelo nome da variável. Os nomes de variável no PHP fazem distinção entre maiúsculas e minúsculas.
Um nome de variável válido se inicia com uma letra ou sublinhado

Atribuindo valores a uma variável:

$teste  = "testando";
$numero = 1234;
$teste2 = "testando 1234";

Operadores

Concatenando uma variável

Concatenar significa juntar as variáveis e no PHP usa-se o . ( ponto ) para juntar as variáveis

Exemplo:

$nome = "João "; <= reparem que tem um espaço depois do nome isso é feito para quando juntar as variáveis nome e sobrenome não ficar grudado JoaoSantos

[quote]$nome = "João ";
$sobrenome = "Santos";
$nome_completo = $nome.$sobrenome;
ou
$nome_completo = $nome;
$nome_completo .= $sobrenome;[/quote]

Somando

[quote]$valor = 100;
$valor += 200;

ou

$valor = 200 + 100;[/quote]

Subtraindo

[quote]$valor = 300;
$valor -= 100;

ou

$valor = 300 - 100;[/quote]

Mutiplicando

[quote]$valor = 300;
$valor *= 100;

ou

$valor = 300 * 100;[/quote]


Operadores Aritméticos

[quote]$a + $b Adição Soma de $a e $b.
$a - $b Subtração Diferença entre $a e $b.
$a * $b Multiplicação Produto de $a e $b.
$a / $b Divisão Quociente de $a por $b.
$a % $b Módulo Resto de $a dividido por $b[/quote]

Operadores de comparação

[quote]$a == $b Igual Verdadeiro (TRUE) se $a é igual a $b.
$a === $b Idêntico Verdadeiro (TRUE) se $a é igual a $b, e eles são do mesmo tipo (somente para PHP4).
$a != $b Diferente Verdadeiro se $a não é igual a $b.
$a <> $b Diferente Verdadeiro se $a não é igual a $b.
$a !== $b Não idêntico Verdadeiro de $a não é igual a $b, ou eles não são do mesmo tipo (somente para o PHP4).
$a < $b Menor que Verdadeiro se $a é estritamente menor que $b.
$a > $b Maior que Verdadeiro se $a é estritamente maior que $b.
$a <= $b Menor ou igual Verdadeiro se $a é menor ou igual a $b.
$a >= $b Maior ou igual Verdadeiro se $a é maior ou igual a $b.[/quote]

Operadores Lógicos

[quote]$a and $b E Verdadeiro (TRUE) se tanto $a quanto $b são verdadeiros.
$a or $b OU Verdadeiro se $a ou $b são verdadeiros.
$a xor $b XOR Verdadeiro se $a ou $b são verdadeiros, mas não ambos.
! $a NÃO Verdadeiro se $a não é verdadeiro.
$a && $b E Verdadeiro se tanto $a quanto $b são verdadeiros.
$a || $b OU Verdadeiro se $a ou $b são verdadeiros.[/quote]

Operadores de Incremento/Decremento

[quote]++$a Pré-incremento Incrementa $a em um, e então retorna $a.
$a++ Pós-incremento Retorna $a, e então incrementa $a em um.
--$a Pré-decremento Decrementa $a em um, e então retorna $a.
$a-- Pós-decremento Retorna $a, e então decrementa $a em um[/quote]

Fim do primeiro módulo

Recomendo ir até o fórum de exercícios para você poder praticar o que aprendeu, com 10 perguntas.

Vocês poderão postar a vontade neste tópico, com dúvidas, sugestões ou alguma outra mensagem.
  • 11


#1252041 [Tutorial] system("pause") e fflush(stdin)

Postado por VictorCacciari em 22 março 2009 - 18:22

Boas Pessoal!

Já faz algum tempo que eu vejo pessoas postando códigos sempre com os mesmos errinhos, que acabam por virar vícios lá na frente.
Claro que é a maneira mais fácil de resolver a maioria dos problemas "chatos" que encontramos quando estamos programando em C/C++.
Mas não é a forma mais confiável, não é portável e ainda é deselegante.

Para já, o campeão, é o famoso std::system("pause").

Antes de mais, usem o Code::Blocks, não é preciso usar system("pause") para ver o resultado do seu programa!

O Problema...
system("pause");

Motivo
Eu imagino que é para conseguir ler o resultado do código, ou falar para o usuário: "Pressione qualquer tecla para continuar."
(Não consigo pensar em outros motivos...)

Como contornar?
Eu espero que vocês conheçam a função scanf().
Se vocês conhecem o nosso amigo scanf, então sabem que ele lê uma string que segue uma formatação.
Então chega de "blá blá blá", e vamos ao que interessa!

O uso do operador, " * " (supressão), na string de formatação, diz para o scanf ler e descartar qualquer coisa.
Como funciona?
int numero;

printf("Digite dois números separados por um espaço: ");
scanf("%*d %d", &numero);

O código acima pegará apenas o segundo número digitado, pois nós falamos para o scanf ler e descartar o primeiro.
Nós podemos fazer isso para qualquer tipo de dados.
Vamos então pedir ao scanf ler e descartar um caractére, uma quebra de linha ('\n').

//... tooooodo o seu código aqui
printf("Pressione enter para continuar");
scanf("%*c");

ps.: Não usem as funções da <conio.h>, essa biblioeta também não é portável e está obsoleta, é muito antiga. Para ter mais controle sobre o input/output do console, busque por nCurses (para aqueles que usam Windows, pdCurses).

Aproveitando a onda do scanf, vamos a um outro problema, que tem uma solução muuuuito parecida.

O Problema...
Sujeira no buffer de entrada, limpa com fflush(stdin)

Motivo
Essa é fácil, ninguém quer um código maluco, com '\n' de sobra em todo o lado.
Você nunca passou por esse problema??
Do it yourself! :P
int main()
{
char cont='s';

	while(cont == 's')
	{
		printf("Deseja continuar? (s/n): ");
		scanf("%c", &cont);
	}
	return 0;
}
:o O meu pc ficou louco???
Não, fique calmo!
O que aconteceu aqui foi que quando digitamos 's' e apertamos enter, a string enviada foi "s\n", mas o scanf só leu o 's' e deixou o '\n' no buffer de entrada padrão (stdin), no próximo loop esse '\n' será lido automaticamente e vai sair do loop.

Como contornar?
Por que não devemos usar fflush(stdin) se ele "funciona" direito??
Na documentação da função está escrito: "effect undefined for input streams".
Se nem eles (que escreveram a função) sabem o que acontece, nós, simples mortais ^_^, muito menos!

Para resolver o problema, vamos de novo usar o operador de supressão do scanf.
e vamos falar para ele: "Hey, leia tuudo mas descarte o último caractére" (o último caractére sempre será um '\n').

Usando o mesmo código que gerou o problema:
int main()
{
char cont='s';

	while(cont == 's')
	{
		printf("Deseja continuar? (s/n): ");
		scanf("%c%*c", &cont); //note a mudança aqui!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	}
	return 0;
}

Pois é...
Espero que tenha sanado algumas dúvidas dos iniciantes!
:lol:

Se gostarem eu fixo o tópico.

Até mais!
http://forum.imaster...tyle_emoticons/default/bye1.gif
  • 9


#2012834 Ideia sobre site PHP

Postado por hinom em 22 setembro 2013 - 03:32

#3 péssima atitude sua.. 

 

Primeiramente, se você posta uma questão em público você está sujeito a opinião pública. Se quisesse ler ou ouvir somente o que gosta, que fizesse em particular dentro do seu controle.

 

 

Sobre a questão, a minha resposta é a mesma do post #2. 

Se não caiu a sua ficha, vamos então detalhar,

 

 

Se eu tiver uma boa idéia acha mesmo entregaria para um desconhecido assim, de graça ?

Boas idéias valem grandes negócios $$$.

O seu intuito é obviamente criar um bom negócio e lucrar com isso sem muito esforço. Não há nada de errado nisso. Nada mais conveniente do que obter uma idéia de graça né ?

 

Numa analogia, o que você pediu é:

"Pessoal, quando vcs descobrirem uma mina de diamantes me chamem que ajudo tá? Mas não peguem nada até eu tirar tudo ok?"

 

 

hilário .. sem noção.


  • 8


#1817695 Como pensar em Orientação a Objetos

Postado por João Prado em 08 março 2012 - 15:33

Boa tarde negada, vamos trabalhar?


Pelo o que o João me explicou sobre o projeto eu preparei o layout de visualização do formulário e de edição.

Vou postar apenas os links para não poluir o tópico:

Visualização - http://www.pradoarts...rsform/view.jpg
Edição - http://www.pradoarts...rsform/edit.jpg
Especificações (se faltou alguma coisa me avisem por favor) - http://www.pradoarts...orm/details.png
Arquivo completo editável - http://www.pradoarts...mastersform.png



O layout segue um estilo simples e se encaixa com o padrão do iMasters.

Como o João me disse que a ideia dele é fazer um editor estilo WYSIWYG, eu fiz de uma forma que a visão que o criador do formulário tem ao editar seja praticamente a mesma visão que tem a pessoa que esta respondendo ao formulário.


Tentei não ousar muito nos campos de formulário, deixei bem simples e de fácil entendimento.

No caso de alguém tentar enviar o formulário sem preencher os campos obrigatórios, a página rola até o campo que precisa ser preenchido e o fundo fica neste tom pastel, que volta ao branco após alguns segundos.


A parte de edição será exibida quase igual a visualização, exceto pelas opções de edição que aparecem no hover de cada área de pergunta, e as opções de adicionar/excluir pergunta que estão lá no final.


Espero que tenham gostado, estou aberto a qualquer sugestão para melhoria destes layouts e para a criação do layout da página de resultados.
  • 8


#1817512 Como pensar em Orientação a Objetos

Postado por João Batista Neto em 08 março 2012 - 09:25

Era uma vez, em um grande fórum de tecnologia, um grande número de membros que postavam suas dúvidas e eram ajudados por outros membros. Cada tópico que um membro postava, abria margem para discussões, aprimoramentos, esclarecimentos e, até, mudanças em pontos de vista que, até então, eram, de certa forma, equivocados...

Se você não entendeu onde quero chegar, então você, definitivamente, não entende nada de controle de versão. Porque controle de versão é exatamente isso, uma história, a história do seu código no decorrer do tempo. A grande diferença entre o git e os outros vários controles de versão, é que no git, cada membro possui uma cópia completa da história em seu próprio ambiente de trabalho, exatamente ao contrário do fórum, onde a história dos tópicos ficam armazenados em um servidor do fórum.

Como toda história, ela possui um início:

$ git init
Initialized empty Git repository in /home/neto/umahistoria/.git/

Ao iniciar uma história, ela é completamente vazia, é como se tivéssemos comprado um livro cheio de páginas em branco. Mesmo que façamos o seguinte:

$ echo "Falando sobre git no Fórum iMasters" >README

Nossa história continuará vazia, isso porque o arquivo README ainda não foi adicionada nessa história. Precisamos adicionar o README no índice da história e, então, começar a escrever sua página.

$ git add README

Isso fará com que README vá para o índice da história, mas a página referente ao README ainda estará vazia porque não gravamos essa página.

$ git commit -m "Gravando a primeira página"
[master (root-commit) 452d86e] Gravando a primeira página
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 README

Cada mudança que façamos nas páginas dessa história precisam, então, ser gravadas, se não fizermos commit, não gravaremos nossas mudanças, por exemplo:

$ echo "Mudando o conteúdo" >README 
$ cat README 
Mudando o conteúdo

Agora, vamos ver o status do repositório:

$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   	modified:   README
#
no changes added to commit (use "git add" and/or "git commit -a")

Como esperado, o arquivo está modificado mo meu diretório de trabalho, mas essas mudanças ainda não foram gravadas no repositório local. Isso significa que posso descartar todas as mudanças que fiz, fazendo checkout da versão do repositório, por exemplo:

$ cat README 
Mudando o conteúdo
$ git checkout -- README 
$ cat README 
Falando sobre git no Fórum iMasters

Então, sempre que fazemos mudanças em um diretório de trabalho, precisamos gravar essas mudanças no repositório local:

$ echo "Mudando o conteúdo" >README 
$ cat README 
Mudando o conteúdo
$ git commit README -m "Gravando mudanças do README no repositório local"
[master f108bbd] Gravando mudanças do README no repositório local
 1 files changed, 1 insertions(+), 1 deletions(-)

Até agora, temos o seguinte:

Imagem Postada

1. Um diretório de trabalho.
2. Usamos git add para adicionar o conteúdo desse diretório no índice.
3. Usamos git commit para adicionar ao repositório local.
4. Usamos git checkout para obter uma versão do repositório local para o diretório de trabalho (perdendo modificações que não foram commitadas).

Quando Linus Torvalds começou a desenvolver o git, ele tinha basicamente os seguintes requisitos:

1. Utilizar CVS como modelo do que não se deve ser. Se houvesse dúvidas quando a determinada implementação, fazer exatamente o oposto.
2. Suportar um fluxo de trabalho distribuído, como o BitKeeper (sistema de controle de versão que utilizavam para o núcleo do Linux).
3. Sistema de segurança muito forte, para evitar corrupção, maliciosas ou não.
4. Altíssima performance.

O ponto de vista de Linus sobre CVS e, consequentemente, SVN, era o seguinte:

For the first 10 years of kernel maintenance, we literally used tarballs and patches, which is a much superior source control management system than CVS is, but I did end up using CVS for 7 years at a commercial company and I hate it with a passion. When I say I hate CVS with a passion, I have to also say that if there are any SVN (Subversion) users in the audience, you might want to leave. Because my hatred of CVS has meant that I see Subversion as being the most pointless project ever started. The slogan of Subversion for a while was "CVS done right", or something like that, and if you start with that kind of slogan, there's nowhere you can go. There is no way to do CVS right.


Bom, um dos grandes pontos do git era ser distribuído, ou seja, cada desenvolvedor tem uma cópia de todo o código e todo a história e, com isso, operações de merge seriam muito rápidas, realmente rápidas.

Imagem Postada

Master é a ramificação principal, outros desenvolvedores podem fazer clone dessa ramificação (ou qualquer outra, o correto é não se trabalhar no master) e trabalhar em cima dela, pode também criar sua própria ramificação, enfim. Vimos que para gravar uma modificação no repositório local, utilizamos git commit. Logo após terminarmos nossas modificações em nosso repositório local, podemos querer mandá-las para o repositório remoto e, para isso, usamos git push.

Imagem Postada

Então, basicamente, trabalhar com git é fazer:

1. Criamos um repositório com git init ou clonamos um repositório com git clone.
2. Fazemos nossas mudanças e então usamos git add para adicionar novos arquivos no índice (se tiver novos arquivos) e fazemos git commit para gravar as mudanças.
3. Terminadas as mudanças, fazemos git push para enviar essas mudanças para o remote.
4. Como muitos desenvolvedores podem estar contando suas próprias histórias, devemos estar sempre atualizando a nossa utilizando git pull.

Acho que ficou mais simples de se entender agora, que acham?


  • 8


#1815514 Como pensar em Orientação a Objetos

Postado por João Batista Neto em 03 março 2012 - 11:14

beleza, eu nao tinha prestado atencao ao detalhe de ter q ser do mesmo tipo....como o exemplo dos menus e submenus...


É exatamente isso Igor, poder ignorar as diferenças entre os elementos da composição e poder tratá-los como do mesmo tipo. Um caso onde a situação proposta pelo Juliano caberia Composite, é na exibição. Se tratarmos, tanto "a pesquisa" quanto as perguntas e as alternativas como elementos renderizáveis, então poderemos utilizar Composite para representá-los em uma View.

Juliano, esse fragmento que você nos passou é insuficiente para qualquer sugestão, não há como lhe dizer se é uma boa ou má solução, apenas vendo o esqueleto de três classes, é preciso algo que represente, de fato, o problema.

Vamos analisar seu problema:

Eu estou desenvolvendo um sistema de pesquisa. Este sistema tem perguntas e respostas (doh). Em um determinado momento, o pesquisador terá que digitar as respostas que coletou.


A descrição do seu problema também é insuficiente, teremos:

1. Perguntas e respostas
2. O pesquisador informará as respostas, pelo que entendi, será uma pesquisa de campo, o pesquisador irá até o entrevistado e, depois de coletar as informações de que precisa, preencherá um formulário com os dados.

Coisas que faltaram:

1. Seu sistema terá várias pesquisas acontecendo simultaneamente?
2. Uma determinada pesquisa será restrita ao pesquisador, ou seja, apenas ele terá acesso?
3. As respostas das perguntas serão sempre fixas, A, B, C ou D? Não haverá a possibilidade de uma resposta dissertativa?
4. O pesquisador informou as alternativas, e ai? O que acontece depois disso?

Percebe amigo, não há a menor possibilidade de se "pensar orientado a objetos" se você não "pensar em resolver um problema antes". A base da orientação a objetos é definir o relacionamento entre os participantes e delegar responsabilidades. Coesão e coerência são duas palavras chave da orientação a objetos, e você só alcançará a coesão e coerência quando você compreender o propósito da sua aplicação e como as coisas devem acontecer.

Imagem Postada

Vejamos, uma entrevista é uma conversação entre duas pessoas, um entrevistador e o entrevistado. Entrevistar é a ação do entrevistador de fazer perguntas da entrevista e obter a resposta do entrevistado, que usará uma das alternativas, okay?

Imagem Postada

Um exemplo de código utilizando esse relacionamento fica assim:

People.php

<?php
/**
* Representação básica das pessoas envolvidas em uma entrevista
* @author João Batista Neto <neto.joaobatista@imasters.com.br>
*/
class People {
/**
* @var string
*/
private $name;

/**
* Recupera o nome da pessoa.
* @return string
*/
public function getName() {
return $this->name;
}

/**
* Define o nome da pessoa.
* @param string $name
*/
public function setName( $name ) {
$this->name = $name;
}
}


Interviewer.php

<?php
require_once 'People.php';

/**
* Representação do entrevistador, que fará uma entrevista com um entrevistado
* e coletará suas respostas.
* @author João Batista Neto <neto.joaobatista@imasters.com.br
*/
class Interviewer extends People {
/**
* Faz a entrevista com um entrevistado.
* @param Interview $interview A entrevista que será feita.
* @param Interviewee $interviewee O entrevistado, que responderá a
* entrevista.
*/
public function interview( Interview $interview , Interviewee $interviewee ) {
foreach ( $interview->getQuestions() as $question ) {
$this->ask( $question , $interviewee );
}
}

/**
* Faz uma pergunta ao entrevistado.
* @param Question $question A pergunta que será feita.
* @param Interviewee $to
*/
public function ask( Question $question , Interviewee $to ) {
$interviewerName = $this->getName();
$intervieweeName = $to->getName();

printf( "%s - %s, %s\n" , $interviewerName , $intervieweeName , $question->getQuestion() );
printf( "%s - %s, %s\n" , $intervieweeName , $interviewerName , $to->answer( $question )->getAlternative()->getAlternative() );
}
}


Interviewee.php

<?php
require_once 'People.php';
require_once 'Answer.php';

/**
* Representação de um entrevistado, que responderá perguntas de uma entrevista
* para um entrevistador.
* @author João Batista Neto <neto.joaobatista@imasters.com.br>
*/
class Interviewee extends People {
/**
* Responde uma pergunta utilizando uma das alternativas da pergunta.
* @param Question $question A pergunta que será respondida.
* @return Answer A resposta do entrevistado.
*/
public function answer( Question $question ) {
$alternatives = $question->getAlternatives();
shuffle( $alternatives );

return new Answer( $question , array_shift( $alternatives ) );
}
}


Interview.php

<?php
/**
* Representação de uma entrevista, que contém várias perguntas que serão feitas
* por um entrevistador para um entrevistado.
* @author João Batista Neto <neto.joaobatista@imasters.com.br>
*/
class Interview {
/**
* @var array[Question]
*/
private $questions = array();

/**
* Adiciona uma pergunta na entrevista.
* @param Question $question A pergunta que será adicionada na entrevista.
*/
public function addQuestion( Question $question ) {
$this->questions[] = $question;
}

/**
* Recupera a lista de perguntas da entrevista.
* @return array[Question]
*/
public function getQuestions() {
return $this->questions;
}
}


Question.php

<?php
/**
* Representação de uma pergunta da entrevista.
* @author João Batista Neto <neto.joaobatista@imasters.com.br>
*/
class Question {
/**
* @var string
*/
private $question;

/**
* @var array[Alternative]
*/
private $alternatives = array();

/**
* Constroi uma instância de Question definindo o texto da pergunta.
* @param string $question O texto da pergunta.
*/
public function __construct( $question ) {
$this->question = $question;
}

/**
* Adiciona uma alternativa para a pergunta.
* @param Alternative $alternative A alternativa que será adicionada.
*/
public function addAlternative( Alternative $alternative ) {
$this->alternatives[] = $alternative;
}

/**
* Recupera a lista de alternativas da pergunta.
* @return array[Alternative]
*/
public function getAlternatives() {
return $this->alternatives;
}

/**
* Recupera o texto da pergunta;
* @return string
*/
public function getQuestion() {
return $this->question;
}
}


Alternative.php

<?php
/**
* Representação de uma alternativa para uma pergunta.
* @author João Batista Neto <neto.joaobatista@imasters.com.br>
*/
class Alternative {
/**
* @var string
*/
private $alternative;

/**
* Cria uma instância de Alternative definindo o texto da alternativa.
* @param string $alternative Texto da alternativa.
*/
public function __construct( $alternative ) {
$this->alternative = $alternative;
}

/**
* Recupera o texto da alternativa.
* @return string
*/
public function getAlternative() {
return $this->alternative;
}
}


Answer.php

<?php
/**
* Representação de uma resposta para uma pergunta.
* @author João Batista Neto <neto.joaobatista@imasters.com.br>
*/
class Answer {
/**
* @var Question
*/
private $question;

/**
* @var Alternative
*/
private $alternative;

/**
* Constroi uma instância de Answer definindo a pergunta e a alternativa
* escolhida pelo entrevistado.
* @param Question $question A pergunta feita pelo entrevistador.
* @param Alternative $alternative A alternativa escolhida pelo entrevistado.
*/
public function __construct( Question $question , Alternative $alternative ) {
$this->question = $question;
$this->alternative = $alternative;
}

/**
* Recupera a pergunta da resposta.
* @return Question
*/
public function getQuestion() {
return $this->question;
}

/**
* Recupera a alternativa escolhida.
* @return Alternative
*/
public function getAlternative() {
return $this->alternative;
}
}


Usando isso ai, teríamos:


<?php
require_once 'Question.php';
require_once 'Alternative.php';
require_once 'Interview.php';
require_once 'Interviewee.php';
require_once 'Interviewer.php';

$question1 = new Question( 'Você gosta de OOP?' );
$question1->addAlternative( new Alternative( 'Sim!' ) );
$question1->addAlternative( new Alternative( 'Não!' ) );
$question1->addAlternative( new Alternative( 'Isso é de comer?' ) );

$question2 = new Question( 'O que é mais legal em OOP?' );
$question2->addAlternative( new Alternative( 'O relacionamento entre objetos.' ) );
$question2->addAlternative( new Alternative( 'A delegação de responsabilidades.' ) );
$question2->addAlternative( new Alternative( 'Já perguntei se isso é de comer?' ) );

$interview = new Interview();
$interview->addQuestion( $question1 );
$interview->addQuestion( $question2 );

$interviewer = new Interviewer();
$interviewer->setName( 'João Batista Neto' );

$interviewee = new Interviewee();
$interviewee->setName( 'Juliano Amadeu' );

$interviewer->interview( $interview , $interviewee );


A saída do exemplo é aleatória, mas vai se parecer com alguma coisa assim:

João Batista Neto - Juliano Amadeu, Você gosta de OOP?
Juliano Amadeu - João Batista Neto, Isso é de comer?
João Batista Neto - Juliano Amadeu, O que é mais legal em OOP?
Juliano Amadeu - João Batista Neto, Já perguntei se isso é de comer?

;)

PS: Para os loucos por padrões de design, existe um problema nesse modelo que postei que pode ser resolvido com um padrão GoF. Imaginem que a próxima pergunta seja condicionada pela resposta dada pelo entrevistado, como podemos fazer nesse caso? Alguém sabe responder?
  • 8


#1815087 Como pensar em Orientação a Objetos

Postado por João Batista Neto em 01 março 2012 - 20:56

com no exemplo da biblioteca, um livro pertence a a tal estante, tal estante tem tantos livros, e uma biblioteca tem tantas estantes....a nao ser q o composite so aceite objetos do mesmo tipo...


Você lê uma estante?
Você armazena estantes em um livro?
Você pode tratar uma estante como um livro, ou um livro como uma estante?

Se a resposta para qualquer uma das perguntas acima for positiva, significa que você pode ignorar as diferenças entre esses objetos e, assim, dizer que uma estante É UM livro e que um livro É UMa estante e, dessa forma, utilizar uma composição recursiva como Composite.

Se a resposta for negativa e você achar que uma estante TEM livros, então trata-se de uma associação 1..*, assim como uma empresa está associada com 1..* funcionários, uma estante possui livros que não dependem da estante para existir, bem como a estante não depende do livro para existir.
  • 8


#1532694 1.3 - Visibilidade e Encapsulamento

Postado por João Batista Neto em 30 abril 2010 - 07:33

Anteriormente falamos sobre como construir um objeto e sobre herança de classes, falamos também que usamos herança de classes para compartilhar código entre os herdeiros, mostrei que uma classe é composta por propriedades (características) e métodos (comportamento) e ilustrei que tanto as propriedades quando os métodos possuem um modificador de visibilidade.

O fato é que em programação orientada a objetos, a ocultação de informações é um dos aspectos mais importantes, imagine a seguinte situação:

"Fulano: Destranque a porta, abra-a e vá para o outro lado"

Quando Fulano for destrancar a porta ele simplesmente enfiará a chave correta no orifício específico, girará e terá a porta destrancada.

Fulano não precisa saber como a porta será destrancada, na verdade, ele não quer sequer saber que dentro da fechadura possui todo um mecanismo que somente destrancará se a chave possuir o segredo correto.

Em orientação a objetos, podemos chamar a fechadura de objeto que possui uma operação destrancar que somente aceita um objeto do tipo chave com o segredo correto, a lógica do mecanismo de tranca é oculto e nem o participante Fulano nem o participante chave precisam saber como o mecanismo funciona. Essa ocultação de informação chama-se encapsulamento.

Para se conseguir ocultar informações, usamos os modificadores de visibilidade, tanto para os métodos quanto para as propriedades, esses modificadores são três:

public:

A visibilidade pública (public) fará com que não haja ocultação nenhuma, toda propriedade ou método declarado com public serão acessíveis por todos que quiserem acessá-los, utiliza-se public para os métodos de interface, isso é, as operações que queremos que outros possam executar em nossos objetos.

private:

 

Ao contrário do public, esse modificador faz com que qualquer método ou propriedade seja visível só e somente só pela classe que a declarou, ninguém terá acesso a essas propriedades ou métodos diretamente, o acesso será possível somente através de métodos de interface.

protected:

 

 

A visibilidade protegida é como um mix da pública com a privada. Quando falamos sobre herança de classes e como os descendentes herdam características e comportamento de seus pais, a visibilidade protected faz com que todos os herdeiros vejam as propriedades ou métodos protegidos como se fossem públicos porém, do lado de fora, um outro objeto não conseguirá acessar diretamente essas informações já que, do lado de fora é como se fosse privada. Então, dentro da classes que declarante e todos seus herdeiros, um método ou propriedade é visível e fora da classes não.


Voltando a nossa fechadura, imaginem se o segredo para abrir a tranca fosse public, a fechadura simplesmente perderia o sentido de existir já que qualquer bandido viria, copiaria o segredo, confeccionaria uma chave e abriria nossas portas e também não tem sentido do segredo ser protected porque a fechadura é uma classe final, já que você não criará outras coisas com ela.

Vamos ver como ficaria essa situação em PHP:


class Chave {
public $segredo;
}


Nesse caso específico, vamos deixar o segredo da chave público, por uma mera questão de ilustração, já que, basta pegar uma chave qualquer para vermos o segredo dela.


final class Fechadura {
private $segredo = 123456;

public function destranca( Chave $chave ){
if ( $chave->segredo == $this->segredo ){
echo 'Destrancado';
} else {
echo 'Chave inválida';
}
}
}


Já no caso da fechadura, o segredo é privado, só a Fechadura poderá acessar essa propriedade através da variável especial $this. De fato, essa variável é muitíssimo utilizada em orientação a objetos no PHP, ela faz referência ao próprio objeto. Usar $this é o mesmo que o objeto dizer Eu Mesmo, então, quando queremos acessar um método ou propriedade do lado de dentro do objeto usaremos essa variável especial.

Dois detalhes novos aparecem na nossa classe Fechadura, o primeiro e a palavra chave final antes de class, ao utilizar final estamos dizendo que não será possível utilizar herança de classes com essa classe específica e que qualquer ocorrência de Fechadura tratar-se-a dessa Fechadura específica.
O segundo detalhe é o uso do Chave antes do parâmetro $chave do método destranca, isso fará com que essa operação aceite só e somente só parâmetros do tipo Chave, isso chama-se type hinting ou dica de tipo e instruirá o método destranca a rejeitar qualquer coisa que não for uma Chave.

Agora, vamos tentar destrancar nossa fechadura com duas chaves diferentes:


$chave1 = new Chave();
$chave1->segredo = 789;

$fechadura = new Fechadura();
$fechadura->destranca( $chave1 );


Perceba que, como a propriedade segredo da Chave é pública, modificamos seu valor do lado de fora da classe e o definimos com 789, o resultado será:

 

 

Chave inválida


Claro, o segredo está errado, vamos tentar com outra chave:


$chave2 = new Chave();
$chave2->segredo = 123456;

$fechadura = new Fechadura();
$fechadura->destranca( $chave2);


A saída será:

 

 

Destrancado


O segredo estava correto, Fulano pode abrir a porta e entrar agora.

Bom, por hora é só, no próximo artigo da série PHP Orientado a Objetos, falaremos sobre métodos de interface e polimorfismo.

Imagem Postada

 

 

 

Próximo Imagem Postada
Índice Imagem Postada

 

 


  • 8


#2066934 Destruir o mundo com PHP | Desconectar o mundo com PHP

Postado por Keven Jesus_164006 em 17 abril 2014 - 13:10

HAHAHAHAH nao resistir cara 

TczJ0hm.jpg


  • 7


#2018262 teoria das classes estaticas?

Postado por Enrico Pereira em 11 outubro 2013 - 23:37

Em orientação a objetos, estáticos têm duas funções: criar objetos e ter estado global (evil evil evil). Em linguagens que não contêm suporte para funções, como Java, eles também são usados para fazer pure functions (funções sem efeitos colaterais e sem estado, apenas com input => output).

 

- Criação de objetos:

 

Vamos supor que nós temos um componente para fazer comparações matemáticas (>, <, >=, etc.).

interface Operator
{
    public function matches($x, $y);
}

class GreaterThan implements Operator
{
    public function matches($x, $y)
    {
        return $x > $y;
    }
}

class LessThan implements Operator
{
    public function matches($x, $y)
    {
        return $x < $y;
    }
}

class Comparison
{
    private $operator;
    private $x;
    private $y;

    public function __construct(Operator $operator, $x, $y)
    {
        $this->operator = $operator;
        $this->x = $x;
        $this->y = $y;
    }

    public function matches()
    {
        return $this->operator->matches($this->x, $this->y);
    }
}

E para utilizar esse componente, perceba que temos um pouco de burocracia:

$comparison1 = new Comparison(new GreaterThan(), 5, 10);
$comparison1->matches(); // false

$comparison2 = new Comparison(new LessThan(), 5, 10);
$comparison2->matches(); // true

Para isso, poderíamos criar métodos estáticos na nossa classe Comparison para facilitar a criação:

public static function greaterThan($x, $y)
{
    return new self(new GreaterThan(), $x, $y);
}

public static function lessThan($x, $y)
{
    return new self(new LessThan(), $x, $y);
}

E o uso fica mais fácil:

$comparison1 = Comparison::greaterThan(5, 10);
$comparison1->matches(); // false

$comparison2 = Comparison::lessThan(5, 10);
$comparison2->matches(); // true

Esse tipo de técnica é conhecida como "Static Factory". Não digo que seja bom ou ruim, depende muito do caso e deve-se tomar cuidado com o Open/Closed Principle.

 

- Estado global:

 

Durante muito tempo isso foi muito aplicado e falado (positivamente) na comunidade PHP, mas atualmente, com o começo da maturidade da linguagem e do ecossistema, hoje isso é evitado. Porém, vamos ver de qualquer forma.

 

Antes de tudo, é necessário compreender o estado em OOP, que é armazenado nas propriedades:

class Rectangle
{
    public $height = 0;
    public $weight = 0;
}

$rectangle1 = new Rectangle();

var_dump($rectangle1->height); // 0
var_dump($rectangle1->weight); // 0

$rectangle1->height = 5.75;
$rectangle1->weight = 9.40;

var_dump($rectangle1->height); // 5.75
var_dump($rectangle1->weight); // 9.40

Os objetos têm estado independente, ou seja, se eu mudar o estado de algum objeto, ele não muda o do outro:

$rectangle1 = new Rectangle();
$rectangle1->height = 5.75;
$rectangle1->weight = 9.40;

$rectangle2 = new Rectangle();
$rectangle2->height = 2.15;
$rectangle2->weight = 2.80;

var_dump($rectangle1->height); // 5.75
var_dump($rectangle1->weight); // 9.40
var_dump($rectangle2->height); // 2.15
var_dump($rectangle2->weight); // 2.80

No caso de estáticos, o estado é da classe e não do objeto, até porque não há um objeto (instância):

class StaticRectangle
{
    public static $height = 0;
    public static $weight = 0;
}

StaticRectangle::$height = 5.75;
StaticRectangle::$weight = 9.40;

StaticRectangle::$height = 2.15;
StaticRectangle::$weight = 2.80;

var_dump(StaticRectangle::$height); // 2.15
var_dump(StaticRectangle::$weight); // 2.80

No caso acima, não temos um objeto e acessamos a classe diretamente. Se eu mudo o estado, eu mudo globalmente e não somente no objeto.

 

Na prática, isso é usado para manter um estado de algo, como um banco de dados, logger, sistema de cache e afins, surgindo dois padrões: Singleton e Registry. Contudo, evite fazer isso, não é uma boa prática.

 

- Pure functions:

 

Elas não são nada mais do que funções que recebem alguns parâmetros e retornam algum valor, sem nenhum efeito colateral, sem acessar estado externo.

 

Na maioria das linguagens, é possível criar funções, mas em algumas não é porque elas obrigam você a trabalhar com classes. Em PHP, costuma-se fazer pure functions com métodos estáticos porque não existe autoloading para funções.

class Inflector
{
    public static function camelCase($string)
    {
        return lcfirst(self::studlyCaps($string));
    }

    public static function studlyCaps($string)
    {
        return str_replace(
            ' ',
            '',
            ucwords(str_replace(['-', '_'], ' ', $string))
        );
    }
}

echo Inflector::camelCase('Alguma frase grande'); // algumaFraseGrande
echo Inflector::studlyCaps('Alguma frase estranha'); // AlgumaFraseEstranha

Mas nada nos impediria de fazer isso de forma orientada a objetos:

class Inflector
{
    private $string;

    public function __construct($string)
    {
        $this->string = $string;
    }

    public function camelCase()
    {
        return lcfirst($this->studlyCaps());
    }

    public function studlyCaps()
    {
        return str_replace(
            ' ',
            '',
            ucwords(str_replace(['-', '_'], ' ', $this->string))
        );
    }
}

echo (new Inflector('Alguma frase grande'))->camelCase(); // algumaFraseGrande
echo (new Inflector('Alguma frase estranha'))->studlyCaps(); // AlgumaFraseEstranha

--------------------------------------------------

 

Teoricamente de dentro dos escopo da classe o correto é usar self::$variavel ou self::funcao  mas acredito que o $this-> funcione da mesma maneira. 

 

Para acessar métodos e propriedades estáticas, usa-se self:: ou static::, $this-> é apenas para não-estáticos. Se rodar em E_STRICT dará erro.

 

Public -> Todos as variaveis ou funções que virem com este metodo podem ser acessados tanto de dentro como de fora da classe exemplo:

 

Banheiros quimicos, calçadas, protitutas sao publicas e podem ser ultilizados tanto pelo governo como o povo

Falar, olhar, correr é publico pois todos nos temos estas caracteristicas

 

 

Private -> sao exclusivamente da classe e nao podem ser herdadas, exemplo:

 

Gosto (musical,alimento, etc..) nao se descute assim como as caracteristicas de uma pessoa, ela nao podem ser herdadas pois nen sempre um pai que gosta de rock o filho gostará de rock.O pai que seja super engraçado o filho sera, o pai tem conhecimento de fisica e quando o beber nascer ja sabendo fisica...

 

Protected -> so podem ser acessadas dentro da classe e podem ser herdadas, Exemplo:

 

A cor dos olhos, da pele entre outras caracteristicas geneticas, Fortuna... podem ser herdadas e usada pelos membros da familia, mas outra pessoa que nao seje da familia nao tem acesso a esse tipo de coisa.

 

Static ->  não pode acessar qualquer outro atributo ou método da classe que também não seja estático. A vantagem é que se não se precisa instanciar um objeto para acessar-los. Exemplo:

 

Public, protected e private são tipos de visibilidade. Estáticos e não-estáticos tem a ver com escopo. Não misture ambas e não tente pensar no mundo real para entender orientação a objetos.

 

Se a classe não fosse estática precisaríamos instanciar um objeto Valida, o que consumiria mais recursos e  daria um código mais longo e menos legível.

 

A OO é verbosa por natureza. No caso de validação, não criaríamos um método para uma validação, pois iria violar o Open/Closed Principle e o Single Responsibility Principle, que são relevantes para um bom design.

interface Rule
{
    public function isValid();
}

class Email implements Rule
{
    private $email;

    public function __construct($email)
    {
        $this->email = $email;
    }

    public function isValid()
    {
        return filter_var($this->email, FILTER_VALIDATE_EMAIL) !== false;
    }
}

class CPF implements Rule
{
    private $cpf;

    public function __construct($cpf)
    {
        $this->cpf = $cpf;
    }

    public function isValid()
    {
        $c = preg_replace('/\D/', '', $this->cpf);

        if (strlen($c) != 11 || preg_match("/^{$c[0]}{11}$/", $c)) {
            return false;
        }

        for ($s = 10, $n = 0, $i = 0; $s >= 2; $n += $c[$i++] * $s--);

        if ($c[9] != ((($n %= 11) < 2) ? 0 : 11 - $n)) {
            return false;
        }   

        for ($s = 11, $n = 0, $i = 0; $s >= 2; $n += $c[$i++] * $s--);

        if ($c[10] != ((($n %= 11) < 2) ? 0 : 11 - $n)) {
            return false;
        }

        return true;
    }
}

class Validator
{
    private $rules = [];

    public function addRule(Rule $rule)
    {
        $this->rules[] = $rule;
        return $this;
    }

    public function validate()
    {
        foreach ($this->rules as $rule) {
            if (! $rule->isValid()) {
                // Procedimentos quando há uma falha
            } else {
                // Procedimentos quando dá certo
            }
        }
    }
}

$validator = new Validator();
$validator->addRule(new Email($_POST['email']))
          ->addRule(new CPF($_POST['cpf']))
          ->validate();

Espero ter contribuído :).


  • 7


Publicidade