MIEEC SIEM ano letivo 2014/15 Boas práticas em programação PHP José A. Faria (jfaria@fe.up.pt) FEUP, DEGI Setembro 2014
Tópicos Estilos de codificação Eliminar duplicações de código Estruturar a aplicação em camadas Variáveis de sessão Organizar os ficheiros da aplicação Diagramas de desenho da aplicação
Estilos de codificação
Estilos de codificação Como complemento a esta aula e a propósito dos estilos de codificação, recomenda-se a leitura do livro: Advanced PHP Programming George Schlossnagle O livro está disponível na biblioteca. Um extrato do livro está também disponível na página da disciplina.
Estilos de codificação É muito importante adotar um estilo de codificação coerente relativamente a, pelo menos: Designação dos vários elementos do programa (variáveis, funções, classes, ) Indentação do código Comentários
Designação dos elementos do programa Acima de tudo, deve ser utilizado um critério consistente na designação dos vários elementos do programa, podendo ser seguidas as orientações seguintes:
Designação dos elementos do programa utilização de nomes extensos. as várias palavras que constituem um nome devem estar claramente separadas (nomecliente, nome_cliente ou nome-cliente) utilização de um prefixo conforme o tipo de objeto (por exemplo, c para classe, g para variável global, l para variável local auxiliar, s para variável de sessão, )
Indentação É também muito importante para a legibilidade do código adotar um estilo de indentação consistente. Há vários estilos, conforme ilustrado pelos exemplos seguintes. Contudo, mais importante do que o estilo particular adotado é que seja adotar um estilo e que esse estilo seja aplicado de forma consistente.
Indentação: Exemplo 1 Utilizar: If ($month = january and $week = 4 and $ day = 25) em vez de: If ($month = january and $week = 4 and $ day = 25) ou mesmo de: If ($month = january and $week = 4 and $ day = 25)
Indentação: Exemplo 2 If função () { Instrução1 Instrução1 } else { Instrução1 Instrução1 } If função () { Instrução1 Instrução1 } else { Instrução1 Instrução1 }
Indentação: Exemplo 3 Utilizar: Select campo From tabela Where campo1 = valor1 and campo2 = valor2 em vez de: Select campo From tabela Where campo1 = valor1 and campo2 = valor2
Comentários Os comentários desempenham um papel fundamental e podem servir dois propósitos principais: explicar passagens do código e delimitar as várias secções do código.
Comentários explicativos do código Apenas devem ser incluídos comentários com valor, i.e., que contenham informação que não seja evidente da análise do próprio código. Ter presente também que a utilização de boas designações das variáveis reduz muito a necessidade de comentários adicionais.
Delimitação das zonas de código Exemplos de secções do código de um script que devem ser claramente delimitadas são as seguintes: tratamento dos parâmetros de entrada, tratamento de erros, lógica do negócio, acesso a dados, preparação dos dados para a apresentação
Eliminar duplicações de código
Eliminar duplicação de código O mesmo código não deve aparecer em vários pontos da aplicação. Para o evitar, o código comum deve ser deslocado para ficheiros externos que, depois, serão incluídos onde necessário. Um exemplo típico de inclusão de código é a parametrização da conexão à base de dados, utilizada em todos os scripts com acesso a dados.
Eliminar duplicações do código A este respeito, consultar o ponto: Includes do tutorial PHP disponível em: http://paginas.fe.up.pt/~arestivo/wiki/?p=aulas/tutoriais/php
Estruturar a aplicação em camadas
Estruturação em camadas: Conceito Fonte: http://www.codeproject.com/kb/cs/three_layer_architecture.aspx
Estruturação em camadas: Conceito apenas esta camada contém código html esta camada não contém código html nem SQL apenas esta camada contém código SQL
Estruturação em camadas: Implementação As 3 camadas podem ser implementadas em ficheiros separados (sendo esta a solução mais recomendável) ou no mesmo ficheiro. Em qualquer dos casos, o fundamental é existir uma separação clara do código correspondente às 3 camadas.
Estruturação em camadas: Implementação De notar que o php é uma linguagem cuja sintaxe não é muito eficiente para gerar diretamente código html. Por isso, é importante que as instruções que geram o html não sejam misturadas com as instruções contendo a lógica da aplicação.
Camada Apresentação Exemplos típicos de funções da camada de apresentação são as seguintes: geração do html do header, footer e menu geração do html contendo os resultados de uma pesquisa (por exemplo uma tabela contendo uma lista de instâncias) geração do html dos detalhes de uma instância (por exemplo um form contendo os vários atributos dessa instância) geração parametrizável de tabelas, formulários,
Camada Apresentação Relativamente à camada, consultar o ponto: Separação da camada de Apresentação do tutorial Organização do Código disponível em: http://paginas.fe.up.pt/~arestivo/wiki.old/doku.php? id=tutorial:organizacao
Camada Acesso a dados O código SQL deve estar isolado em classes ou bibliotecas de funções reutilizáveis para evitar que eventuais alterações: no servidor de base de dados no modelo de dados impliquem várias alterações distribuídas por todo o código da aplicação.
Camada Acesso a dados Relativamente à camada de acesso a dados, consultar o ponto: Separação da camada de Acesso à Base de Dados do tutorial Organização do Código disponível em: http://paginas.fe.up.pt/~arestivo/wiki.old/doku.php? id=tutorial:organizacao:bd
Camada Acesso a dados <?php function get_empregados() { global $conn; $result = pg_query($conn, "SELECT * FROM empregado"); if (!$result) { echo "An error occured.\n"; exit; } $empregados = pg_fetch_all($result); return $empregados; }
Camada Acesso a dados function get_empregado_byid($id) { global $conn; $query = "SELECT * FROM empregado WHERE id =. $id. ; ; $result = pg_query($conn, $query); if (!$result) { echo "An error occured.\n"; exit; } $empregados = pg_fetch_all($result); return $empregados[0]; }
Camada Acesso a dados <?php include_once ("common/database.php"); include_once ("apresentacao/header.php"); include_once ("apresentacao/footer.php"); include_once ("apresentacao/empregado.php"); include_once ("database/empregado.php"); $empregados = get_empregados(); display_header("listar Empregados"); display_listaempregados($empregados); display_footer();?>
Camada Lógica de negócio Tal como foi já referido a propósito dos comentários, as várias seções de código devem ser facilmente identificáveis e estar claramente delimitadas.
Variáveis de sessão
Variáveis de sessão As variáveis de sessão são um mecanismo muito útil para obter uma boa usabilidade das aplicações, mas que devem ser utilizadas com moderação e disciplina. Como o valor de uma variável de sessão pode ser atribuído em qualquer página, é muito fácil surgirem comportamentos errôneos e difíceis de corrigir, sobretudo quando vários programadores trabalham sobre a mesma aplicação.
Variáveis de sessão Para evitar este tipo de problemas, sempre que possível, devem ser utilizadas variáveis de sessão standard em toda a aplicação, por exemplo: serro, spostdata, sgetdata, sback Qualquer variável de sessão não standard deve sempre ser acompanhada de um comentário.
Variáveis de sessão Um exemplo típico de aplicação de variáveis standard é o tratamentos dos erros: vários scripts de ação podem re-encaminhar para o mesmo script de apresentação; qualquer script de ação onde ocorra um erro, escreve a mensagem a apresentar ao utilizador numa variável de sessão standard msg_erro;
Variáveis de sessão Por seu lado, todas as páginas html: têm uma divisão para apresentação de eventuais mensagens de erro; os scripts que geram as páginas html testam o valor da variável de sessão smsgerro; se o seu valor não for nulo, apresentam-no na divisão das mensagens de erro; no caso contrário, esta divisão permanece escondida.
Organizar os ficheiros da aplicação
Organizar os ficheiros da aplicação O código de uma aplicação php bem desenhada, normalmente, está distribuído por muitos pequenos ficheiros, cada um dos quais com uma função bem definida. Sendo assim, torna-se ainda mais importante adotar critérios consistentes para a designação dos ficheiros e a sua arrumação em pastas. De seguida são apresentadas algumas regras e sugestões a este respeito.
Designação dos ficheiros Os ficheiros da aplicação podem ser designados de acordo com a entidade que manipulam e a operação que efetuam, por exemplo: form_pesquisacliente.php ver_listaclientes.php ver_cliente.php form_inserircliente.php form_eliminarcliente.php
Designação dos ficheiros Claro que haverá sempre exceções. Por exemplo, no caso de algumas entidades, a mesma página pode incluir o form de pesquisa e os resultados da pesquisa. Que designação adotar nestes casos: form ou ver? Desde que as exceções não sejam muitas, será relativamente simples manter o controlo da situação. O problema é quando as exceções passam a ser a regra
Organizar os ficheiros da aplicação A título de exemplo, analisar o Sifeup, onde existem páginas distintas para os forms de pesquisa, listagem das entidades, visualização dos detalhes de uma instância, criação, alteração e eliminação de instâncias. Regra geral, as páginas de listagem não contém dados de mais do que uma entidade, nem as páginas de detalhe contém dados de mais do que uma instância.
Ficheiros de apresentação e de ação Deve haver scripts separados: para a geração das páginas html de apresentação (scripts ver, form_inserir, form_criar, ) e para a execução das ações (scripts eliminar, atualizar, criar).
Arquivo dos ficheiros de apresentação e de ação O ficheiro de apresentação e o ficheiro de ação relativos a uma dada entidade e operação podem: ser arquivados na mesma pasta com designações diferentes, por exemplo: form_inserircliente.php acao_inserircliente.php ou terem ambos a mesma designação (neste caso, a designação comum seria inserircliente.php), mas serem arquivados em pastas distintas.
Arquivo dos ficheiros de apresentação e de ação Por exemplo, pode ser criada um pasta para cada entidade contendo a subpasta ações: na pasta raiz ficam os ficheiros de apresentação (listar, ver, pesquisar, ) na subpasta os scripts correspondentes às várias ações sobre as instâncias dessa entidade (atualizar, inserir e eliminar).
Organização global dos ficheiros Na organização global dos ficheiros de uma aplicação podem ser criadas as seguintes pastas: pasta para ficheiros includes / configuração pasta para figuras pasta para CSS pasta para JavaScript pasta por entidade contendo os respetivos ficheiros de apresentação, ação e acesso a dados
Organização global dos ficheiros Como anteriormente, mais importante do que a organização particular adotada, é haver critérios lógicos de organização e aplicados de forma consistente.
Diagramas de desenho da aplicação
Diagramas de desenho da aplicação Uma vez definidas as especificações da aplicação a desenvolver e antes de se iniciar a escrita do código, é muito útil elaborar um diagrama da aplicação representando as várias páginas e o esquema de navegação entre elas. Um exemplo deste tipo de diagrama é apresentado em: http://paginas.fe.up.pt/~arestivo/wiki.old/doku.php? id=tutorial:arquitectura
Diagramas de desenho da aplicação Por vezes, os diagramas não são tão simples pois o mesmo script pode gerar várias apresentações. Por exemplo, considere-se uma página de entrada que lista as instâncias de uma da entidade pode conter links para criar, alterar, eliminar, modificar as instâncias. Pode haver um par de scripts para cada uma destas operações (um dos scripts gera o form e o outro executa a ação).
Diagramas de desenho da aplicação No entanto, como os forms para criar, ver, alterar e eliminar são semelhantes, pode ser preferível ter um script único que recebe um parâmetro de entrada com a operação a executar e que gera as várias apresentações Por exemplo: gerircliente.php?operacao=modificar&idcliente=34
Diagramas de desenho da aplicação Neste tipo de situações, é necessário distinguir no diagrama entre as páginas html no browser e os scripts php que geram essas páginas. A elaboração do diagrama completo de uma aplicação, mesmo para aplicações simples, rapidamente se pode tornar muito complexo, difícil de elaborar e de interpretar.
Diagramas de desenho da aplicação Felizmente, na maioria dos casos não é preciso desenhar o diagrama de toda a aplicação. Numa aplicação bem concebida, normalmente, é possível identificar um padrão para os vários casos de uso associados a cada entidade da aplicação: listar, ver, inserir, atualizar e eliminar.
Diagramas de desenho da aplicação Quando é assim, será suficiente analisar em detalhe e elaborar o diagrama para um conjunto limitado de casos de uso, desde que sejam representativos do conjunto da aplicação. Uma vez analisado e documentada a situação padrão, apenas será necessário analisar as exceções que não respeitam o padrão e que, claro, devem ser em número tão reduzido quanto possível.