Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Saudações a todos.
Esta semana estou recorrendo bastante ao fórum.
Tenho uma aplicação em desenvolvimento no seguinte esquema:
-
Conexão
/**
* Conexão com MySQL utilizando o MYSQLI
*
* As constantes SERVIDOR_DB, USUARIO_DB, SENHA_DB, BANCO_DB são definidas na configuração geral
*/
$mysqli = new mysqli(SERVIDOR_DB, USUARIO_DB, SENHA_DB, BANCO_DB);
/ check connection /
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
/ check if server is alive /
if ($mysqli->ping()) {
// printf ("Our connection is ok!\n");
} else {
printf ("Error: %s\n", $mysqli->error);
}
Validar e evitar roubo Sessão:
/**
* Verfica se o usuário está logado
* estas páginas são restritas aos usuário logados no sistema
*/
/** SE PROTEGENDO CONTRA ROUBOS DE SESSÃO
*
* Caso o servidor não aceite ini_set, os erros serão ocultos pelo @
*/
/** Configurar o tempo de sessão para 1 hora (Padrão do php: 3 horas) */
@ini_set('session.cache_expire', 60);
/** Configurar os cookies de sessão para não serem acessados via JS (Ataques XSS) */
@ini_set('session.cookie_httponly', true);
/** Configurar o php para não recuperar sessões via URL */
@ini_set('session.use_only_cookie', true);
/** INICIALIZA A SESSÃO */
session_start();
/**
* EVITANDO ROUBO DE SESSÃO - SESSION REGENERATE ID
*
* Atualiza o id da sessão atual com um novo gerado
* Irá substituiro id da seção atual com um novo, e mantém a informação da sessão atual.
* proteger contra session fixation. Gerar novo identificador ao logar no sistema.
*
* verifica se foi digitada uma id de sessão na URL
* Se tiver, nós destruímos a sessão e geramos outra id para a seção
*/
if(strpos(strtolower($_SERVER['REQUEST_URI']), 'phpsessid') !== false)
{
session_destroy();
session_start();
session_regenerate_id();
}
/**
* EVITANDO ATAQUES XSS (Cross-Site Scripting)
*
* Anti Session Hijacking
* checar algum dos headers da requisição
* Um header sugerido é o User-Agent,
* principalmente porquê ele não muda entre as requisições de uma sessão
* guardar os dados deste header em uma varíáveis de sessão no primeiro acesso do usuário
* e depois checá-lo nos acessos subsequentes
* gravar um hash md5 do valor do header User-Agent
*/
if (array_key_exists('HTTP_USER_AGENT', $_SESSION))
{
if ($_SESSION['HTTP_USER_AGENT'] != md5($_SERVER['HTTP_USER_AGENT']))
{
/* Acesso inválido. O header User-Agent mudou
* durante a mesma sessão.
*/
/**
* REDIRECIONA
* como estou usando url amigáveis pela função RewriteEngine,
* passo apenas o nome da página para url sem informar a extensão
*/
Header("Location: home");
}
} $_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']);
}
/**
* verifica se as variáveis foram gravadas na sessão
*/
if((!isset($_SESSION['LG_Usuario'])) && (!isset($_SESSION['LG_Tipo']))) {
/**
* REDIRECIONA
* como estou usando url amigáveis pela função RewriteEngine,
* passo apenas o nome da página para url sem informar a extensão
*/
Header("Location: home");
}else{
/** Verifica se o status do usuário é 'S' (Sim - Ativo) ou 'N' (Não - Inativo),
* se não, encerra a sessão e redireciona para o login
*/
if($_SESSION['LG_Situacao'] != "Ativo"){
/** Limpando o array session */
$_SESSION = array();
/** Finalmente, destruição da sessão. */
session_destroy();
/**
* REDIRECIONA PARA A TELA DE LOGIN
* como estou usando url amigáveis pela função RewriteEngine,
* passo apenas o nome da página para url sem informar a extensão
*/
Header("Location: home");
}
}
proteção contar múltiplos submits
/**
* Se protegendo contra submits múltiplos (Brute-force)
*
* Evitando parada bruta do PHP(e um possível DDoS) pela "chuva" de submits
* um (ou mais) formulário é preenchido e enviado várias vezes consecutivas
* na tentativa de derrubar o servidor ou só descobrir uma senha.
*
* Verificar se existe um valor salvo na sessão
* que nos informará a hora exata do último submit aceito pelo sistema (em UNIX TIMESTAMP)
* Faz uma verificação que compara esse horario buscado na sessão (caso ele exista) com o horário atual
*/
/** Verifica se $_POST não está vazio */
if (!empty($_POST)) {
/** Tempo mínimo entre dois submits (em segundos) */
$segundos = 3;
/** "Agora" em UNIXTIMESTAMP */
$agora = time();
/** Verifica se a variável da sessão existe E verifica a diferença de tempo */
if (isset($_SESSION['ultimoSubmit']) AND ($_SESSION['ultimoSubmit'] > ($agora - $segundos))) {
/** O submit será bloqueado */
echo "<center><br>Aguarde mais de {$segundos} segundos para enviar o formulário!<br>
<br>
<a href=\"javascript:history.go(-1);\">voltar</a></center>";
exit;
}$_SESSION['ultimoSubmit'] = $agora;
}
.htacces
RewriteEngine On
RewriteBase /royalpark/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule !\.(gif|jpg|png|css|swf)$ /royalpark/index.php
pagina inicial
/**
* URL amigaveis
*
* Acessos a URLs longas demais também devem ser prevenidos
*/
if(strlen($_SERVER["REQUEST_URI"])>200){
header("HTTP/1.1 404 Not Found");
include("aplccs/404.php");
exit();
}
/**
* recolhendo informação do local acessado.
*/
$url = $_SERVER['REQUEST_URI'];
/**
* dividir a URL em pedaços separados por "/"
*/
$gets = explode("/",str_replace(strrchr($url, "?"), "", $url));
/**
* array_shift()
* retira o primeiro elemento de array e o retorna,
* diminuindo array em um elemento e movendo todos os outros elementos para trás.
* Esta função irá resetar() o ponteiro do array depois do uso.
* o primeiro índice sempre será vazio
*/
array_shift($gets);
/** Verifica se a página existe */
if(file_exists("aplccs/".$gets[1].".php")){
/** Se a página existe inclui o .php referente a mesma */
include("aplccs/".$gets[1].".php");
}else{
/** Se a página não existe redireciona para a home */
include("aplccs/home.php");
}
Configuração Smarty
/**
* Define a pasta onde está o Smarty
* esta constante pode ficar em arquivo separado por exemplo
*
*/
require_once ('lbs/Smarty.class.php');
/**
* Instancia Smarty e seta propriedades
*
* compile_check = avisa ao Smarty para mostrar erros de compilação
* debugging = em fase de desenvolvimento é bom deixar como true,
* uma vez que abre um popup com todas as informações da página gerada
*
*/
function retornaSmarty() {
$smarty = new Smarty();
// $smarty->compile_check = true;
// $smarty->debugging = false;
$smarty->template_dir = "tmplts";
$smarty->compile_dir = "tmplts_c";
$smarty->cache_dir = "cach";
$smarty->config_dir = "cnfgs";
$smarty->plugins_dir = "lbs/plugins";
return $smarty;
}
Uma página de exemplo
/**
* Inclui a verficação se o usuário está logado
* Inclui classe principal do Smarty
* Inclui funções gerais
* Inclui a protegendo contra submits múltiplos (Brute-force)
* Inclui as variáveis gerais do sistema
* Inclui classe de conexão com o banco de dados
* Inclui classe de criptografia
* apl -> Aplicação
*/
require_once('inclds/vld-usr.inc.php');
require_once('inclds/retrn-smarty-apl.inc.php');
require_once('inclds/fnc-apl.inc.php');
require_once('inclds/antibrt-forc-apl.inc.php');
require_once('inclds/cnfg-grl-apl.inc.php');
require_once('clsss/Cnx-apl.class.php');
require_once('clsss/Crpt-apl.class.php');
/** Inicia as variáveis */
$DataHoje = date('Y-m-d H:i:s');
$DataHojeFormat = date('d/m/Y');
$ip = $_SERVER['REMOTE_ADDR'];
$Paginacao = '';
$ResultadoInfo = '';
$Resultado = '';
/**
* Variável $gets[]
*
* Array retornado do explode() da URL no /index.php
* O índice [2] é o parâmetro referente ao rótulo "pagina"
* O índice [3] é o parâmetro referente ao número da página
*/
if (isset($gets[2]) && ($gets[2] == "pagina") ) {
/** strip_tags(); para remover qualquer tag, seja ela javascript, HTML ou PHP. */
$pagina = strip_tags($gets[3]);
/** Salva o parâmetro da URL numa variável obrigando-o a ser um valor inteiro */
$pagina = (int)$pagina;
}else{
$pagina = 0;
}
/** Máximo de registros por página */
$max = 15;
/** Verifica a variável página, se for "0" a página é a primeira = "1" */
if ($pagina == 0) {
$pagina = 1;
}
$inicio = $pagina - 1;
$inicio = $max * $inicio;
/** contagem inical da pagainação */
$contagemInicial = $inicio + 1;
$contagemFinal = $max + $inicio;
/**
* Faz a primeira busca
*/
$sqlCli = "
SELECT rp_clnt.*, rp_sit.ST_Nom AS Situacao, rp_sit_cad.SC_Nom AS SituacaoCad
FROM rp_clnt
LEFT JOIN rp_sit ON rp_sit.ST_IdSit=rp_clnt.CC_SitPg
LEFT JOIN rp_sit_cad ON rp_sit_cad.SC_IdSitCad=rp_clnt.CC_SitCad
";
$resultCli = $mysqli->query($sqlCli);
$linhasCli = $resultCli->num_rows;
/** Calculando pagina anterior */
$menos = $pagina - 1;
/** Calculando pagina posterior */
$mais = $pagina + 1;
$pgs = ceil($linhasCli / $max);
/** inicia a tag para centralizar a paginação */
$Paginacao .= '<table height="23" border="1" bordercolor="#E4E4D3" align="right" cellpadding="0" cellspacing="2">
<tr>';
/** MÁXIMO DE LINKS ANTES E DEPOIS DA PÁGINA ATUAL */
$maxlnk = 6;
if (($pagina-$maxlnk) < 1 ) {
$anterior = 1;
} else {
$anterior = $pagina-$maxlnk;
}
if (($pagina+$maxlnk) > $pgs ) {
$posterior = $pgs;
} else {
$posterior = $pagina + $maxlnk;
}
/** faz o loop como s números de página */
for($i=$anterior;$i <= $posterior;$i++){
if($i != $pagina){
$Paginacao .= " <td width=\"23\" bgcolor=\"#CCCCAC\"><div align=\"center\"><a href=\"rstrt-cli/pagina/".$i."\" class=\"Link-Medio\" >$i</a></div></td>";
}else{
$Paginacao .= " <td width=\"23\" bgcolor=\"#9B9B60\"><div class=\"font-branca\" align=\"center\"><strong>".$i."</strong></div></td>";
}
}
/** finaliza a tag para centralizar a paginação */
$Paginacao .= '</tr>
</table>';
/** verifica se o total de registros é maior que o número de registros por página */
if($contagemFinal > $linhasCli){
$TotalRegistros = $linhasCli;$TotalRegistros = $contagemFinal;
}
/** Mostra os números do resultado */
$PaginacaoInfo = "<table border=\"0\" align=\"center\" cellpadding=\"10\" cellspacing=\"0\" width=\"95%\">
<tr>
<td align=\"left\"><div class=\"fonte-media\">Resultados: <strong>[ ".$contagemInicial." a ".$TotalRegistros." ] de [ ".$linhasCli." ]</strong></div></td>
<td>".$Paginacao."</td>
</tr>
</table>";
/** verifica se retornou algo */
if($linhasCli == 0){
$Resultado = '<center><br><br>Não há registros.</center>';
}else{
/**
* Busca novamente
*/
$sql = $sqlCli." ORDER BY CC_Novo DESC,CC_Nom ASC LIMIT $inicio,$max";
$result = $mysqli->query($sql);
$linhas = $result->num_rows;
/** verifica se retornou algo */
if($linhas > 0){
$Resultado .= '<table id="hor-minimalist-b" width="95%" align="center">
<thead>
<tr>
<th scope="col">Nome</th>
<th scope="col">Tipo</th>
<th scope="col">Status</th>
<th scope="col">Situação</th>
<th width="60" scope="col">Controle</th>
</tr>
</thead>';
/**
* percorre o objeto mysqli_result retornado (array associativo)
* associative array
*/
while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)){
$CC_IdCli = $row['CC_IdCli'];
$CC_Nom = $row['CC_Nom'];
$CC_End = $row['CC_End'];
$CC_Num = $row['CC_Num'];
$CC_Cmpl = $row['CC_Cmpl'];
$CC_Brr = $row['CC_Brr'];
$CC_Cid = $row['CC_Cid'];
$CC_Cep = $row['CC_Cep'];
$CC_Uf = $row['CC_Uf'];
$CC_Tel1 = $row['CC_Tel1'];
$CC_Tel2 = $row['CC_Tel2'];
$CC_Cel = $row['CC_Cel'];
$CC_Mail = $row['CC_Mail'];
$CC_SitCad = $row['SituacaoCad'];
$CC_DiaVenc = $row['CC_DiaVenc'];
$CC_SitPg = $row['Situacao'];
$CC_Empr = $row['CC_Empr'];
$CC_TelEmpr = $row['CC_TelEmpr'];
$CC_TipCad = $row['CC_TipCad'];
$CC_CPF = $row['CC_CPF'];
$CC_CNPJ = $row['CC_CNPJ'];
$CC_RG = $row['CC_RG'];
$CC_IE = $row['CC_IE'];
$CC_DtNasc = $row['CC_DtNasc'];
$CC_DtCad = $row['CC_DtCad'];
$CC_DtVal = $row['CC_DtVal'];
$CC_DtUltPgto = $row['CC_DtUltPgto'];
$CC_DtPxVenc = $row['CC_DtPxVenc'];
$CC_Novo = $row['CC_Novo'];
/** Criação de uma nova instância da classe Encryption ($encrypt) */
$encrypt = new Encryption;
/** Chamamos a função decode, que descriptografa os os dados */
$cpfDecrypt = $encrypt->decode($CC_CPF);
$rgDecrypt = $encrypt->decode($CC_RG);
$cnpjDecrypt = $encrypt->decode($CC_CNPJ);
$ieDecrypt = $encrypt->decode($CC_IE);
if($CC_Novo == "Sim"){
$BtNovo = '<img src="img-apl/ico-novo.png" border="0" />';
}else{
$BtNovo = '';
}
$Resultado .= '<tr>
<td>'.$BtNovo.' '.$CC_Nom.'</td>
<td>'.$CC_TipCad.'</td>
<td>'.$CC_SitPg.'</td>
<td>'.$CC_SitCad.'</td>
<td><a href="rstrt-altr-cli/'.$CC_IdCli.'/pagina/'.$pagina.'" class="link" title="Editar"><img src="img-apl/icones/lapis.png" border="0" /></a><a href="rstrt-del-cli/'.$CC_IdCli.'/pagina/'.$pagina.'" class="link" title="Apagar"><img src="img-apl/icones/menos.png" border="0" /></a></td>
</tr>';
}
/** Coloca a paginação */
$Resultado .= '</table>'.$PaginacaoInfo;
}
}
/**
* Busca Situação do cadastro
*/
$sql = "
SELECT *
FROM rp_sit_cad
ORDER BY SC_Nom ASC
";
$result = $mysqli->query($sql);
$linhas = $result->num_rows;
/** inicia a formação do select */
$SelectSitCad = "<select name=\"frm_SitCad\" class=\"input\" id=\"frm_SitCad\">
<option value=\"\"> Situação </option>";
/** verifica se retornou algo */
if($linhas > 0){
/**
* percorre o objeto mysqli_result retornado (array associativo)
* associative array
*/
while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)){
$codigoSitCad = $row['SC_IdSitCad'];
$nomeSitCad = $row['SC_Nom'];
$SelectSitCad .= '<option value="'.$codigoSitCad.'">'.$nomeSitCad.'</option>';
}
}else{
$SelectSitCad .= '<option value="0">Não há status Cadastrados.</option>';
}
$SelectSitCad .= '</select>';
/**
* Busca Sitação do usuário
*/
$sql = "
SELECT *
FROM rp_sit
WHERE ST_Tip = 'Cliente'
OR ST_Tip = 'Ambos'
ORDER BY ST_Nom ASC
";
$result = $mysqli->query($sql);
$linhas = $result->num_rows;
/** inicia a formação do select */
$SelectSit = "<select name=\"frm_SitPg\" class=\"input\" id=\"frm_SitPg\">
<option value=\"\"> Status </option>";
/** verifica se retornou algo */
if($linhas > 0){
/**
* percorre o objeto mysqli_result retornado (array associativo)
* associative array
*/
while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)){
$codigoSit = $row['ST_IdSit'];
$nomeSit = $row['ST_Nom'];
$SelectSit .= '<option value="'.$codigoSit.'">'.$nomeSit.'</option>';
}
}else{
$SelectSit .= '<option value="0">Não há status Cadastrados.</option>';
}
$SelectSit .= '</select>';
/** verifica se o formulário foi postado */
if (isset($_POST['cadastrar']) && $_POST['cadastrar'] == "cadastrar") {
/**
* RECEBE OS DADOS DO FORMULÁRIO
* EVITANDO O SQL INJECTION
* Com a utilização da função MysqlEscape() será adicionada uma barra invertida antes de cada aspa simples e aspa dupla encontrada,
* processo conhecido como escape.
*/
$CC_Nom = MysqlEscape($_POST['frm_Nom']);
$CC_End = MysqlEscape($_POST['frm_End']);
$CC_Num = MysqlEscape($_POST['frm_Num']);
$CC_Cmpl = MysqlEscape($_POST['frm_Cmpl']);
$CC_Brr = MysqlEscape($_POST['frm_Brr']);
$CC_Cid = MysqlEscape($_POST['frm_Cid']);
$CC_Cep = MysqlEscape($_POST['frm_Cep']);
$CC_Uf = MysqlEscape($_POST['frm_Uf']);
$CC_Tel1 = MysqlEscape($_POST['frm_Tel1']);
$CC_Tel2 = MysqlEscape($_POST['frm_Tel2']);
$CC_Cel = MysqlEscape($_POST['frm_Cel']);
$CC_Mail = MysqlEscape($_POST['frm_Mail']);
$CC_SitCad = MysqlEscape($_POST['frm_SitCad']);
$CC_Sit = MysqlEscape($_POST['frm_Sit']);
$CC_CPF = MysqlEscape($_POST['frm_CPF']);
$CC_RG = MysqlEscape($_POST['frm_RG']);
$CC_SitPg = MysqlEscape($_POST['frm_SitPg']);
$CC_DiaVenc = MysqlEscape($_POST['frm_DiaVenc']);
$CC_Empr = MysqlEscape($_POST['frm_Empr']);
$CC_TelEmpr = MysqlEscape($_POST['frm_TelEmpr']);
$CC_DtNasc = MysqlEscape($_POST['frm_DtNasc']);
$CC_DtNasc = DataMysql($CC_DtNasc);
$CC_Sex = MysqlEscape($_POST['frm_Sex']);
$DtVal = MysqlEscape($_POST['frm_DtVal']);
$DtVal = DataMysql($DtVal);
$HrVal = MysqlEscape($_POST['frm_HrVal']);
$CC_DtVal = $DtVal.' '.$HrVal.':00';
/**
* verifica se é pessoa física ou juridica
*/
if(isset($_POST['frm_PessoaJuridica'])){
$CC_CNPJ = MysqlEscape($_POST['frm_CNPJ']);
$CC_IE = MysqlEscape($_POST['frm_IE']);
/**
* CRIPTOGRAFANDO CNPJ e IE
* Criação de uma nova instância da classe Encryption ($encrypt)
*/
$encrypt = new Encryption;
/** Chamamos a função encode, que criptografa os os dados */
$cnpjCript = $encrypt->encode($CC_CNPJ);
$ieCript = $encrypt->encode($CC_IE);
$CC_TipCad = 'PJ';
}else{
$cnpjCript = '';
$ieCript = '';
$CC_TipCad = 'PF';
}
/**
* CRIPTOGRAFANDO CPF e RG
* Criação de uma nova instância da classe Encryption ($encrypt)
*/
$encrypt = new Encryption;
/** Chamamos a função encode, que criptografa os os dados */
$cpfCript = $encrypt->encode($CC_CPF);
$rgCript = $encrypt->encode($CC_RG);
/**
* GRAVA OS DADOS NO BANCO DE DADOS
*/
$resultINSERT = $mysqli->query("
INSERT
INTO rp_clnt (CC_Nom, CC_End, CC_Num, CC_Cmpl, CC_Brr, CC_Cid, CC_Cep, CC_Uf, CC_Tel1, CC_Tel2, CC_Cel, CC_Mail, CC_SitCad, CC_DiaVenc, CC_SitPg, CC_Empr, CC_TelEmpr, CC_TipCad, CC_CPF, CC_CNPJ, CC_RG, CC_IE, CC_DtNasc, CC_Sex, CC_DtCad, CC_DtVal)
VALUES ('$CC_Nom', '$CC_End', '$CC_Num', '$CC_Cmpl', '$CC_Brr', '$CC_Cid', '$CC_Cep', '$CC_Uf', '$CC_Tel1', '$CC_Tel2', '$CC_Cel', '$CC_Mail', '$CC_SitCad', '$CC_DiaVenc', '$CC_SitPg', '$CC_Empr', '$CC_TelEmpr', '$CC_TipCad', '$cpfCript', '$cnpjCript', '$rgCript', '$ieCript', '$CC_DtNasc', '$CC_Sex', '$DataHoje', '$CC_DtVal');
");
/**
* REDIRECIONA
* como estou usando url amigáveis pela função RewriteEngine,
* passo apenas o nome da página para url sem informar a extensão
* URL_PADRAO - definida nas configurações gerais para o caminho absoluto do redirecionamento
*/
Header("Location: ".URL_PADRAO."rstrt-cli");
}
/**
* Instancia o Smarty e seta propriedades
*/
$smarty = retornaSmarty();
/**
* Assign é um metodo do Smarty para criar uma
* nova variável que será usada no Template
*
* sintaxe: assign->('nome_variavel', 'valor');
*/
/** Título das paginas nas tags <title></title> */
$smarty->assign('TituloPagina', TITULO_PAGINA);
/** URL padrão para os links das páginas */
$smarty->assign('DiretorioBase', DIRETORIO_BASE);
$smarty->assign('Resultado', $Resultado);
$smarty->assign('pagina', $pagina);
$smarty->assign('DataHojeFormat', $DataHojeFormat);
$smarty->assign('SelectSitCad', $SelectSitCad);
$smarty->assign('SelectSit', $SelectSit);
/**
* Mostra o Template na tela
* observe que até aqui nada foi exibido, só processado
*/
$smarty->display("rstrt-cli.tpl");
/ fecha a conexão /
$mysqli->close();
Na verdade está tudo funcionando bem, porém de tempos em tempos tudo fica lento, a mesma página que inicialmente carregou rápido se torna morosa e o processamento demora bastante.
Gostaria de saber se há como otimizar uma aplicação, quais os macetes e se existe alguma forma de medir sua performance, enfim, como fazer uma aplicação grande ser mais rápida?
Desde já agradeço.
Abraço a todos.
Mauro Lúcio
Carregando comentários...