Mais sobre Url Amigável com PHP

Eu tenho uma videoaula falando sobre esse assunto, mas vejo que algumas pessoas ainda tem dificuldade de aplicar em seus projetos. Eu recebi um e-mail do Junior Eberhardt pedido se poderia falar mais ou exemplificar sobre como implementar a paginação, no caso seria recuperar o valor da URL. Eu respondi a ele, e resolvi compartilhar também para ajudar quem tem a mesma duvida.

A grande dificuldade de todos com a URL Amigável é que não conseguem ver q a URL amigável é igual a query string. A diferença de trabalho, que é você precisa mapear a URL, onde que antes você teria variáveis para valores separados, agora você precisa pega a URL, e separá-la, e recuperar o valor que você precisa.

Então, se você fosse usar query string pra ver um conteúdo especifico, provavelmente você faria isso:

www.seusite.com.br/?pg=noticia&id=1

Vou pegar exemplo minha vídeoaula, então a URL amigável ficaria assim:

www.seusite.com.br/noticia/1

Mas só que o servidor está vendo , seria isso :

www.seusite.com.br/?pg=noticia/1

Obs.: Vou postar a mesmo .htaccess da videoaula para saber porque o servidor entenderia a url da maneira acima.

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?pg=$1

O que precisa ser decidido antes é o que cada posição da url, separada pela barra, será responsável. Continuando o nosso exemplo:

Então no meu projeto , quero que a primeira parte seja sempre um arquivo, e segunda parte quero seja uma busca no banco de dados, ou uma paginação.

Então podemos criar uma função pra retorne um array já separado, se existir a variável pg, ele coloca um explode, caso não existe será um array com nome home:

<?php

function getPage(){
   return (isset($_GET['pg'])) ? explode('/', $_GET['pg']) : array('home');
}

?>

Mas podemos ter um problema, quando for uma URL assim :

www.seusite.com.br/noticia/1/

O último item ficará vazio, mas podemos tratar isso usando o array_filter, percorrendo o array, e mostrando só os estão preenchidos :

<?php
function getPage(){
   return (isset($_GET['pg'])) ? array_filter(explode('/', $_GET['pg']), 'noEmpty') : array('home');
}

function noEmpty($item){
   return !(empty($item));
}

?>

Já temos agora os itens da URL em um array, então dizemos que o primeiro item será sempre a página :

<?php
function getPage(){
   return (isset($_GET['pg'])) ? array_filter(explode('/', $_GET['pg']), 'noEmpty') : array('home');
}

function noEmpty($item){
   return !(empty($item));
}

/*Inclui a pagina*/

function getIncludePage(){
   $page = getPage();
   $file = $page[0];
   if(file_exists("arquivos/$file.php")){
       $path = "arquivos/$file.php";
    }else{
      $path =  "arquivos/error.php";
    }
   include_once($path);
}

?>

Agora vamos definir os parâmetros. Então quero que o segundo parâmetro seja o valor que posso pesquisar no banco de dados.

<?php
function getPage(){
   return (isset($_GET['pg'])) ? array_filter(explode('/', $_GET['pg']), 'noEmpty') : array('home');
}

function noEmpty($item){
   return !(empty($item));
}

/*Retorna a pagina q será incluida*/

function getIncludePage(){
   $page = getPage();
   $file = $page[0];
   if(file_exists("arquivos/$file.php")){
       $path = "arquivos/$file.php";
    }else{
      $path =  "arquivos/error.php";
    }
   include_once($path);
}
/*Retorna o primeiro parâmetro depois da pagina*/
 function getFirstParam(){
     $page = getPage();
     return (isset($page[1])) ? $page[1] : 0;
}

?>

Mas quero que se tiver no segundo parâmetro a palavra page, quero que pegue o valor depois dela, como fosse nessa URL:

www.seusite.com.br/noticia/page/2

Pegando o valor da paginação:

<?php
function getPage(){
   return (isset($_GET['pg'])) ? array_filter(explode('/', $_GET['pg']), 'noEmpty') : array('home');
}

function noEmpty($item){
   return !(empty($item));
}

/*Retorna a pagina q será incluida*/

function getIncludePage(){
   $page = getPage();
   $file = $page[0];
   if(file_exists("arquivos/$file.php")){
       $path = "arquivos/$file.php";
    }else{
      $path =  "arquivos/error.php";
    }
   include_once($path);
}

/*Retorna o primeiro parâmetro depois da pagina*/
 function getFirstParam(){
     $page = getPage();
     return (isset($page[1])) ? $page[1] : 0;
}

/*Retorna número de paginação*/
 function getNumberPagination(){
     $page = getPage();
     return (isset($page[1]) && $page == 'page' && isset($page[2])) ? (int)$page[2] : 1;
 }

?>

Então já decidimos a página que será incluída, o parâmetro passado, e valor da paginação, vamos inclui isso na prática. Vou dá o nome desse arquivo com todas essas regras de router.php.

A nossa index.php ficaria assim:

<?php
   //inclui as funções criadas
   include_once('lib/router.php');

  //aqui de conexão
  include_once('lib/conexao.php');

?>
<!DOCTYPE HTML>
<html lang="en-US">
<head>
	<meta charset="UTF-8">
	<title></title>
</head>
<body>
	<?php getIncludePage();?>
</body>
</html>

Vamos então ver pegando um valor de uma paginação na URL, onde o arquivo chama noticias.php

www.seusite.com.br/noticias/page/3

noticias.php

<?php
    //Resgatar o número da paginação
     $page = getNumberPagination();
     //A quantidade a ser exibida
     $qtd = 5;
    //o valor inicial
     $inicio = ($page * $qtd) - $qtd;
     //SQL
     $sql = "SELECT * FROM noticias LIMIT $qtd, $inicio";

    //**Continuação do código normal*//
?>

O que fizemos até agora foi definir a maneira que queremos que url amigável trabalhe, isso vai depender do nosso projeto. Mas importante pensar antes como você quer que ele trabalhe, porque fica mais fácil para implementar depois. Espero que tenha ajudado a clarear um pouco o assunto de url amigáveis.

96 thoughts on “Mais sobre Url Amigável com PHP

    1. Romulo, o array_filter, ele filtrar elementos de um array, utilizando uma função como callback. Veja que a função que criei para adicionar no array_filter verifica se os valores não estão vazios. Isso poderia ser feito por foreach, mas é interessante mostrar outras formas de fazer apenas com funções do php.

      Vc pode trabalhar de qualquer maneira, mas isso preciso ser decidido antes. No tutorial informo isso, que vc decido como trabalhar, e depois começa a desenvolver. Veja que o primeiro parametro sempre será um arquivo, mas isso foi um opção minha, mas se vc quiser colocar vários parâmetro, não tem problema, basta adaptar o código a sua necessidade.

  1. David te perguntar
    Tem um site http://www.teste/pr1/pr2/pr3…../valor
    eu tava tentando usar o for para colocar o ultimo parametro como valor e os de traz como parametros. so que eu não to conseguindo apagar os demais e deixar o ultimo como valor.
    No site da g1 tem isso o que eu estou falando.
    Porem isso e mt complicado.
    O que eu posso fazer ? depois que eu tranformei a variavel pg para array eu queria fazer um for que separa-se o ultimo para o valor e o os primeiros para parametros de forma dinamica nao de forma statica como dizer qual sem colocar o indice q vai ser o valor [5].
    Desculpa pelo incomodo ate mais

    1. Romulo, não é tão complicado, basta saber trabalhar com array, e funções do php q estão ai pra facilitar. Vou recuperar o último item, e depois removê-lo.o

      <?php 
      	$url = 'pr1/pr2/pr3/pr4/pr5';
      	$items = explode('/', $url);
      	$ultimo = end($items); //pega o ultimo item (pr5)
      	$param = array_pop($items); //remove o último item. (pr1, pr2, pr3, pr4)
      	
      ?>
      
      1. Muito bom com isso aprendir 2 funções novas que no momento eu não conhecia array_pop e end.
        Brigado por ter me ajudado.Fica com Deus cara

  2. faz uma video aula utilizando o lastInsertId() do PDO
    ou alguma outra maneira de pegar o id de um insert
    eu só como o mysql_insert_id(),

    1. Sobre lastInsertId, ele é um método da classe PDO, e não da PDOStatement , como execute, bindValue,fetch, etc. Um exemplo:

      //instancia a classe PDO
      $pdo = new PDO("mysql:host=localhost;dbname=_banco_de_dados", "root", '');
      
      //Cria o SQL
      $strSQL = "INSERT INTO produtos (nome, valor) VALUES (:nome, :valor)";
      
      //Prepara a SQL
      $stmt = $pdo->prepare($strSQL);
      
      //atribui os valores
      $stmt->bindValue(':nome', 'Computador');
      $stmt->bindValue(':valor', 1000);
      
      //executa
      $stmt->execute();
      
      //Recupera o ID
      $ultimo_id = $pdo->lastInsertId();
      

      Viu q para recuperar, utilizo o objeto que está na variável $pdo, e não da $stmt. Seria basicamente isso.

      1. Deu certo!
        Muito obrigado pela ateção, eu já tinha tentado de tudo pra pegar o ultimo id e nao tinha conseguido, dessa vez foi bem facinho.

        Valeu mesmo!

  3. Olá David,sei que não tem nada haver com o assunto, mais estou aqui precisando novamente da sua ajuda, cara ta difícil aqui, tipo queria fazer uma busca no banco de dados, no qual tenho os dados e data, ex:
    Produto: Filtro Cod: 1R 0751 data troca: 17/05/2012 sendo que eu queria fazer uma busca mais ou menos assim:
    17/05/2012 –
    Filtro 1R 0751 17/05/2012
    Filtro 1R 0753 17/05/2012

    16/06/2012 –
    Filtro 1R 0753 16/06/2012
    Elemento 151 2409 16/06/2012

    exibir os resultados pela data de cada um, mais não tenho a miníma idéia de como fazer isso dentro do While. Seria possível me ajudar?

    1. Totti, no caso vc não sabe como exibi essas informações. Vc precisa ordenar pelo campo de data, e depois utilizar uma variável para mostrar a data uma única vez para o usuário, exemplo:

      <?php 
      
      $query = "SELECT * FROM relatorios ORDER BY data DESC";
      $data = 0;
      while($row = mysql_fetch_assoc($query)){}
               if($data <> $row['data']){
                  printf('<h2>%s</h2>', $row['data']);
                   $data =  $row['data'];
              }
             echo 'Filtro '.$row['filtro'];
      ?> 
      
      1. Pohh David Valeu mesmo, consegui aqui, cara muito agradecido mesmo, você não tem idéia do tanto que já tentei fazer isso e não tinha conseguido, e você meu deu a rota certa, muito obrigado mesmo, cara você é o melhor! um grande abraço.

  4. Olá David blz tenho uma dúvida eu fiz uns teste assim:

    BD:
    tabela: noticias

    campo: noticia -> ex: firefox-11

    se eu na hora de buscar essa notícia assim:

    eu teria o link ex: http://www.meu-site.com.br/firefox-11

    aí mostrava a notícia na pagina.php

    $url = $_GET[‘pagina’];// vai pegar a url: firefox-11

    SELECT noticia FROM noticias WHERE noticia in(\”$url\”);

    dessa forma aparece certinho, e mostra tudo relacionado a notícia ou seja na hora de cadastrar a notícia eu já defino o título como url, tudo minúsculo retirando acentos e espaços.

    Agora fazer dessa forma tem algum problema com relação a desempenho com banco de dados ou demorar pra mostrar o resultado ?

    abraços

    1. Não regis, não terá problema de desempenho, talvez o que vc pode tentar para melhorar o desempenho é atribuir ao campo URL no banco de dados um índice. Lembre-se sempre de filtrar os valores q vem para o banco.

      Outra dica, vc pode limitar o retorno de valor. Se vc pensar bem, vc utiliza o nome como valor único, ele terá que retornar apenas um valor:

      $sql = "SELECT * FROM noticias WHERE url = '$slug_url' LIMIT 1";
      
  5. Salve, David CHC!
    Estou tendo dificuldades de criar o meu .htaccess…
    No caso tenho 3 URL diferentes para transformar em AMIGÁVEL:
    # Páginas simples
    …/index.php?pg=contato

    # Página podendo passar X, Y e Z parametros juntos ou separados
    …/index.php?pg=busca&imo=X&fin=Y&tip=Z

    # Página onde se passa apenas um parametro
    …/index.php?pg=detalhes&id=X

      1. Eduardo, pode trabalhar diretamente com as regras, ou como mostrei no tutorial, todas as informações váo para pg, e depois tratar no php.

        Criando 3 regras no próprio Htaccess, depois apenas recuperar normalmente como querystring

        RewriteRule ^contato$ index.php?pg=contato
        RewriteRule ^busca\/(.*)\/(.*)$ index.php?pg=busca&imo=$1&fin=Y&tip=$2
        RewriteRule ^detalhes\/(.*)# index.php?pg=detalhes&id=$1
        
        1. Não tá funcionando assim, Qual problema?

          – eu quero que se for contato o GET seja CONTATO mas qndo nao for seja VER/”VALOR DO GET”

          RewriteEngine On
          RewriteCond %{SCRIPT_FILENAME} !-f
          RewriteCond %{SCRIPT_FILENAME} !-d
          RewriteRule ^contato$ index.php?p=contato
          RewriteRule ^(.*)$ index.php?p=ver/$1

  6. estou aqui para agradecer ao David mais uma vez, já que graças a ele, hoje consigo criar urls amigáveis facilmente, na verdade não é tão difícil mesmo, nós que complicamos. David, mais uma vez, meu muito obrigado, você é nota 1000…

    1. Q bom Junior , mas realmente no começo é complicado mesmo, depois que começar entender o q seria mapear a URL, as coisas ficam mais fáceis. abrs

  7. Ola David, sou novo, entao se eu usar esta funcao, nao preciso utilizar a que foi criada na outra aula o é necessario ter ela implementada tambem?

  8. Bom dia David eu não trabalho com query_string trabalho com várias entradas como funciona nesse caso a url amigável vi na sua vídeo aula mas não deu certo sera que tenho que definir no htaccess todas as minhas entradas um abraço.

    1. Fabio, vc precisa defini como como deseja trabalhar com parametros. Um forma é definir o nome da variável, o que vem depois é o valor, exemplo:

      www.seusite.com.br/pagina/noticias/categoria/2/id/5
      

      Veja que estou definido:

      pagina => noticias
      categoria => 2
      id = 5

      Dai com PHP, vc pode mapear, q o item seguinte é o valor que vc procura, exemplo

      <?php 
      		function getParam($key){
      			$url = explode('/', $_GET['pg']);
      			$value = null;
      			foreach($url as $i => $v){
      				if($key == $v){
      					$next = $i+1;
      					$value = $url[$next];
      					break;
      				}
      			}
      			return $value;
      		}
      ?>
      

      E utilizando:

      echo 'Página :'.getParam('pagina') .' <br />';
      echo 'Categoria :'.getParam('categoria') .' <br />';
      echo 'ID :'.getParam('id') .' <br />';
      
  9. Esse cara é d++++++++++++ sabe tudo, e tem mais poderia ser um grande comunicador nos veiculos de comunicação..Barabnes davidchc vc é realmente o cara..abraço

    1. Carlos, é possivel, vc pode até definir isso no htaccess

      RewriteRule ^montadora\/(.*) pagina.php?opcao=$1
      

      O q começar montadora, ele vai redirecionar para pagina.php, colocando valor adicionado depois montadora na variavel opcao

      1. Eu não entendi como vou colocar os links de paginação. Exemplo:

        Pagina 1 | 2 | 3 Ultima Pagina

        Eu fiz o que você ensinou, mas no meu caso os links não funcionam. Fica assim
        noticia/page/1 daí eu clico no link 2 e apenas a url altera para alugar/page/2, mas os dados da página continuam o mesmo.

        Pode me ajudar?

          1. David, eu já tinha assistido essa aula, o problema é que estou trabalhando com php oo e url amigáveis, por isso estou tendo problemas.

            Eu vi uma class de paginacao que vc deixou de exemplo, mas não consegui entender direito

          2. Primeira coisa, é vc verificar se está conseguindo recuperar o valor da URL. Tente imprimi o valor da tela :

            <?php 
              echo getNumberPagination();
            ?>
            
          3. David, o

            estava retornando o valor 1, mas os links não funcionavam. Então eu coloquei assim:
            $page = (isset($_GET[‘page’])) ? (int)htmlentities($_GET[‘page’]) : ‘1’;

            e funcionou, agora fala consertar a url. Onde está noticia/&page=2
            para ficar noticia/page/2

            pode me ajudar

          4. Marcos, mesmo trocando o valor na URL pra noticia/page/2, ele não está recuperando o valor 2? Troque a função por essa:

            function getNumberPagination(){
             $page = getPage();
             $target = 'page';
             $result = 1;
             if($key = array_search($target, $page)){
            	$key += 1;
            	$result = isset($page[$key]) ? (int)$page[$key] : 1; 
             }
             return $result;
            	 
             }
            
          5. Boa tarde, David

            Descobri onde eu estava errando.
            Como eu já tinha uma função de inclusão de página eu não estava usando a sua :
            function getIncludePage(). Só que eu não tinha visto que os parâmetros passados pela era utilizado na
            function getNumberPagination().
            Então eu substitui a minha pela sua, fiz as alterações necessárias e agora está funcionando correto.

            Obrigado pela ajuda. Foi sua insistência em me fazer ler seu código que me fez ver meu erro.

            Abraços

          6. Marcos, é importante vc tbm tentar fazer a sua versão, dessa forma vc consegue entender a lógica de utilizar URL amigável, e adaptar melhor ao seu projeto.

          7. Marcos, vc pode fazer verificações, como falei, a logica aplica no tutorial foi baseada numa forma pre-estabelecida, onde o primeiro parametro sempre será um arquivo. Mas no caso, vc pode fazer uma verificação antes, vendo se é uma categoria, e atribuindo a pagina de categoria. Exemplo

            //Verifica se o item é um categoria
            function isCategory($category){
            	$sql = "SELECT categoriaId FROM tbcategoria WHERE categoriaSlug = '".$category."' LIMIT 1";
            	$query = mysql_query($sql);
            	return mysql_num_rows($query) > 0 ? true :  false;
            }
            
            function getIncludePage(){
               $page = getPage();
               /*Verifica se é um categoria, se for, informa nome do arquivo para as categorias, 
                senão, informa q seria uma pagina  */
               $file = isCategory($page[0]) ? 'categoria' : $page[0];
               
               if(file_exists("arquivos/$file.php")){
                   $path = "arquivos/$file.php";
                }else{
                  $path =  "arquivos/error.php";
                }
               include_once($path);
            }
            
          8. Não funcionou. A query não pega o slug. Todas as minhas sql estão dentro de classes, todas usando PDO e Orientada a objetos. Então dessa maneira eu não consigo criar uma query fora. Eu criei essa query que você passou de acordo com os padrões que estou seguindo e depois a instanciei, mas não funcionou. Tem outra dica para me dar?

          9. Marcos, veja te passei apenas um exemplo, vc pode trabalhar de outras formas. A ideia é vc pesquisar no banco de dados se aquele slug existiria, usar em procedural, mas poderia ser orientado a objeto, criando um método chamado iscategory

            function getIncludePage(){
               $page = getPage();
               $categoria = new Categoria();
               
               $file = $categoria->isCategory($page[0]) ? 'categoria' : $page[0];
               
               if(file_exists("arquivos/$file.php")){
                   $path = "arquivos/$file.php";
                }else{
                  $path =  "arquivos/error.php";
                }
               include_once($path);
            }
            
            
          10. David, eu modifiquei a ultima instrução que você me passou por essa linha:
            $file = ($page[0]) ? $page[0] : ‘categoria’ ;

            E funcionou, ao invés de eu fazer uma consulta eu já verifico se é uma page ou categoria.

            Me corrija se eu estiver errado. Comecei a trabalhar com OO a poucos dias, por isso estou meio perdido. Mas agora acho que vai fluir.

          11. Marcos, vc pode fazer dessa forma. Só terá q mudar se vc tiver outro tipo de informação vindo do banco de dados. No começo é confuso trabalhar com OOP, depois fica mais facil

          12. Será que este o problema que estou tendo agora numa página de pesquisa.

            Criei 4 combos de pesquisas para filtrar informações. Ele filtra e faz a paginação correta, mas quando clico no link da paginação ele faz um reload na página e perde o filtro, listando todas as informações cadastradas, perdendo assim o critério de consulta. Tem Alguma dica, para isso?

        1. Bom dia,

          cara fiz todo direitinho mas está retornando estes erro:

          Warning: include_once(arquivos/error.php): failed to open stream: No such file or directory in C:\Apache24\htdocs\paginar_url01\lib\router.php on line 20

          Warning: include_once(): Failed opening ‘arquivos/error.php’ for inclusion (include_path=’.;C:\php\pear’) in C:\Apache24\htdocs\paginar_url01\lib\router.php on line 20

          1. Manoel, não está encontrando o arquivo, que no caso é error.php que estaria na pasta arquivos, é só conferir o caminho

  10. Boa noite, David!

    Estou com um problema nesta função.

    public function listarAll() {
    parent::$tabela = “tbcategoria”;
    parent::$existeParametros = true;
    $this->setParametros(” INNER JOIN tbimovel i INNER JOIN tbtiponegocio n
    ON i.imovelTipo = tbcategoria.categoriaId
    AND i.imovelNegocio = n.negocioId
    WHERE i.imovelStatus = ‘ativo’
    AND categoriaSlug = ” . $this->getSlug() . ” GROUP BY imovelCodigo”);
    return parent::listar();
    }

    ——
    Aqui eu invoco a função

    $n = new Categoria();
    $n->setSlug($slug);
    $x = $n->listarAll();

    —–
    Mas ela retorna o seguinte erro:

    Erro: SQLSTATE[42S22]: Column not found: 1054 Unknown column ‘sitios’ in ‘where clause’

    —-
    Só que se eu usar a mesma query diretamente num gerenciador de bd, ou na aplicação e subistituir o $this->getSlug por um valor fixo, ela funciona corretamente.

    Sabe me explicar o que pode estar acontecendo

    1. marcos, aparentemente está sem aspas simples quando você declara o filtro Where para pegar o slug. Deveria ser assim:

      public function listarAll() {
       parent::$tabela = "tbcategoria";
       parent::$existeParametros = true;
       $this->setParametros(" INNER JOIN tbimovel i INNER JOIN tbtiponegocio n
       ON i.imovelTipo = tbcategoria.categoriaId
       AND i.imovelNegocio = n.negocioId
       WHERE i.imovelStatus = 'ativo'
       AND categoriaSlug = '". $this->getSlug() . "' GROUP BY imovelCodigo");
       return parent::listar();
      }
      
      1. Agora funcionou. Eu tinha resolvido trocando o slug pelo id e deu certo também, mas era pelo slug que eu queria mesmo, assim eu economizo uma função.

        Obrigado

  11. David, poderia dar uma olhada nesse código e me dizer onde estou errando. Porque ele está recuperando e fazendo a paginação correta, mas quando eu clico no link da paginação ele perde os parâmetros e lista todos os dados.

    if (isset($_GET[‘p’])):
    $explodeUrl = explode(‘/’, $_GET[‘p’]);
    $slug = $explodeUrl[0];

    global $urlBase;

    $page = getNumberPagination();

    $qtd = 6;
    $inicio = ($page * $qtd) – $qtd;

    try {
    $negocio = $_POST[‘negocio’];
    $cidade = $_POST[‘cidade’];
    $tipo = $_POST[‘tipo’];
    $codigo = $_POST[‘codigo’];
    $listar = $pdo->prepare(“SELECT * FROM tbimovel i INNER JOIN tbtiponegocio n INNER JOIN tbcategoria c
    ON i.imovelNegocio = n.negocioId
    WHERE imovelStatus = ‘ativo’
    AND imovelNegocio LIKE :negocio
    AND imovelCidade LIKE :cidade
    AND imovelTipo LIKE :tipo
    AND imovelCodigo LIKE :codigo
    GROUP BY imovelCodigo LIMIT ” . $inicio . ‘,’ . $qtd);

    $listar->bindValue(‘:negocio’, ‘%’ . $negocio . ‘%’);
    $listar->bindValue(‘:cidade’, ‘%’ . $cidade . ‘%’);
    $listar->bindValue(‘:tipo’, ‘%’ . $tipo . ‘%’);
    $listar->bindValue(‘:codigo’, ‘%’ . $codigo . ‘%’);
    $listar->execute();

    $dados = $listar->fetchAll(PDO::FETCH_OBJ);
    } catch (PDOException $e) {
    echo “Erro: ” . $e->getMessage();
    }
    endif;

    1. Marcos, como falei anteriormente, vc precisa passar essas informações para outra página. Vc tá usando POST, para pesquisa, usamos GET, porque dessa forma podemos trabalhar com a paginação.

      pesquisas.php?p=2&negocio=valor&cidade=valor&tipo=valor&codigo=valor

      Veja q no link acima, informo além q será passado o valor 2 da paginação, informo as outras variáveis, assim continuo a fazer a restrição usando a paginação

      1. Então, David. Eu já tinha visto isso, mas quando eu troco no formulário para method get ele não chama a página de pesquisa. E quando uso o POST ele chama e faz todo processo correto “em parte”, porque quando a página recarrega ao clicar no link de paginação ela perde o parâmetro que foi passado, pelo fato de ter sido passado por post né. Tá complicado, já refiz o código várias vezes, já usei a classe de paginação do pear e acontece a mesma coisa. Aqui fica complicado de te mostrar o que to dizendo. Como ficaria o código no action do formulário?

        1. Marcos, é quando trabalha com form em get, ele vai enviar as informações pela URL, sendo que ele sempre vai adicionar um sinal de interrogação na URL, pq é dessa forma q dizemos que vamos passar alguma informação. Só que o problema é que o htaccess já adicionamos um sinal de interrogação, exemplo do tutorial:

          index.php?pg=$1

          Uma forma de resolver isso, é adicionando um flag a mais na regra do htaccess, para informa que se tiver mais 1 sinal de interrogação, ele interprete como &. A flag para isso é [QSA]

          Ficando assim o código:

          RewriteRule ^(.*)$ index.php?pg=$1 [QSA]
          

          Depois da modificação teste o formulário via GET, e não esqueça de adicionar os paramêtro no link da paginação, para funcionar da maneira que vc quer.

          1. Não deu para mostrar a linha do link, porque seu sistema limpou as tags.

            Vamos ver se assim você entende

            ahref = urlBase/slug/page/i > i <

          2. De onde vc tirou o Lucas, eu não sei.rs

            Usar URL ficará assim, passando o parâmetro da pesquisa:

            urlBase/slug/page/i?negocio=2

            Ou assim

            urlBase/slug/page/i&negocio=2

          3. David, me desculpa a confusão. Estava falando com um amigo na mesma hora que estava solicitando sua ajuda. Por isso me confundi.

            Agora está funcionando perfeito. Seu suporte foi de grande valor. Obrigado mesmo.

  12. Aproveitando a ocasião, tenho outra dúvida.
    Eu hospedei o site que estou desenvolvendo, para testar, dentro de um subdomínio, mas não aparece nada das informações vindas do banco. Detalhe, essas páginas estão funcionando normalmente aqui em localhost. Daí eu criei uma página de teste usando php procedural com conexão e código, e esta retorna as informações. O que será que pode estar ocorrendo?

    1. Marcos, vc precisa verificar se está tendo uma mensagem de erro, vc pode definir para usar exceptions

      <?php 
      
      $host = 'localhost';
      $user = 'root';
      $pass = '';
      $dbname = 'nome_banco_de_dados';
      
      try{
        $pdo = new PDO("mysql:host=$host;dbname=$dbname", $root, $pass);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
      }catch(PDOException $e){
        echo $e->getMessage();
      }
      
      1. David, a conexão que eu fiz está igual a sua, veja:

        define(‘HOST’, ‘microtechsuport.com.br’);
        define(‘DB’, ‘microtec_db’);
        define(‘USER’, ‘microtec_admin’);
        define(‘PASS’, ‘microtech2012’);
        $conexao = ‘mysql:host=’ . HOST . ‘;dbname=’ . DB;
        try {
        $pdo = new PDO($conexao, USER, PASS);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch (PDOexception $e) {
        echo ‘Erro: ‘ . $e->getMessage();
        }

        Esta funciona perfeitamente.

        Esta aqui é a que estou usando em php Orientado:

        abstract class Conexao {

        const USER = “microtec_admin”;
        const PASS = “microtech2012”;

        private static $instance = null;

        private static function conectar() {
        try {
        if (self::$instance == null):
        $dsn = “mysql:host=microtechsuport.com.br;dbname=microtec_db”;

        self::$instance = new PDO($dsn, self::USER, self::PASS);
        self::$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        endif;
        } catch (PDOException $e) {
        echo “Erro: ” . $e->getMessage();
        }
        return self::$instance;
        }

        protected static function getDB() {
        return self::conectar();
        }
        }

        e em localhost está funcionando também, mas hospedado a página não mostra nada e não da erro também. Veja o link

        http://imobi.microtechsuport.com.br/

        Então se você clicar no botão buscar, ou clicar neste link:
        http://imobi.microtechsuport.com.br/busca-por-negocio

        irá mostrar uma página de teste que fiz utilizando a primeira conexão mostrada acima como também toda a página feita em php procedural, mas o site foi feito por completo orientado, e estas página não retorna nada, e nem da erro, porque eu já fiz o teste alterando uma instrução para causar erro, e mostrou erro de sql.

        1. Provavelmente o servidor de hospedagem desabilitou as mensagens de erro. No começo do código adicione o trecho baixo pra poder mostrar as mensagens de erro:

          ini_set('display_errors', 'On');
          error_reporting(E_ALL|E_STRICT);
          
          1. David, o único erro que está mostrando é o de inclusão de uma página chamada categoria. Mas ela não tem nada a ver com a página home ou outras páginas.

            Eu estou refazendo os códigos para php procedural, porque preciso entregar esse trabalho e não consigo terminar.

            E agora apareceu esse outro erro de include da página categoria.

  13. David, será que você pode fazer um exemplo de uma função de inclusão de paginas, diferente do que você fez acima no início deste post. Uma função que faz inclusão verificando se é pagina home, ou pagina categoria que é chamada quando não existe um arquivo correspondente ao link ou uma single.

    Esse aqui é o que estou usando agora:

    if (isset($_GET[‘p’])) {
    $url = $_GET[‘p’];
    $urlE = explode(‘/’, $url);
    $arquivo = $urlE[‘0’];
    $post = $urlE[‘1’];

    $paginas = array(‘quem-somos’, ‘alugar’, ‘vender’, ‘procura’, ‘central-do-cliente’, ‘contato’);
    if (isset($post) && $post != ”) {
    include “inc/detalhes.php”;
    } elseif (isset($arquivo) && in_array($arquivo, $paginas)) {
    include “inc/$arquivo.php”;
    } else {
    include “inc/categoria.php”;
    }
    }else {
    include “inc/home.php”;
    }

    Mas a pagina categoria está perdendo os dados ao clicar na paginação.

    Já a classe que eu estava usando antes, estava funcionando tudo normal em localhost mas quando eu hospedei, ela não da include da página categoria.

    Essa aqui:
    public static function carregaUrlAmigavel($url) {

    $pasta = ‘inc/’;

    if (substr_count($url, “/”) > 0):

    $explodeUrl = explode(“/”, $url);

    if (is_file($pasta . $explodeUrl[0] . ‘.php’)):
    include_once $explodeUrl[0] . “.php”;
    else:
    include_once “inc/categoria.php”;
    endif;

    else:

    if (is_file($pasta . $url . ‘.php’)):
    include_once $url . “.php”;
    else:
    include_once “inc/categoria.php”;
    endif;

    endif;
    }

    1. David, consegui fazer funcionar. Depois de horas tentando.. rsrs.

      Mas tive que refazer todas as páginas para php procedural. Orientado não quer aparecer nada msm.

        1. Então, David, depois de fazer vários testes encontrei outro bug, mas este dá pra deixar passar. Em relação aos códigos em Orientado Objetos, descobri que é a função autoload que não está carregando as classes. Não sei o porquê. Então estou fazendo algumas alterações no admin

  14. Tipo assim david, eu fiz e deu tudo certo, porem minha url ta assim:
    localhost/buscasfs/

    ai clico numa categoria pra add 2 parametros na url no caso uma categoria, ai ela fica assim:

    localhost/buscasfs/categoria/restaurante/

    ok, perfeito, logo dps eu clico em otra categoria, ai a url fica assim:

    localhost/buscasfs/categoria/categoria/restaurante/

    da errado, ele n apaga oq tinha antes na url, ai fica 2 categoria ali, como resolvo?

    Como faço pra apagar os parametros q tinha na url e add 2 novos?

    1. rony, tenta colocar a url completa nos links, ao invés das referentes

      <a href="/categoria/1">Categoria</a>
      
      para 
      
      <a href="http:///seusite.com.br/categoria/1">Categoria</a>
      
      
  15. Opa, tudo bem ? Adorei seu blog, várias dicas super interessantes, esse tutorial mesmo estou implementando em um novo projeto porém, queria saber como posso montar a URL sem que apareça a ID, já troquei os valores da ID por URL, assim o script checaria a linha do banco pela URL e não ID (sim, tenho o valor inserido no Banco) porém, fazendo desse método não consigo puxar os valores daquela linha, como por exemplo, o titulo, descrição e etc, algum luz ? Obrigado 😀

    1. Rhuan ,no caso vc vai ter q gravar a forma amigavel no banco de dados, acho q vc já fez isso. Essa forma amigavel, alguns dão nome de slug, ela será um identificador unico, como o ID, assim vc vai consegui recuperar o valor do banco:

      SELECT * FROM posts WHERE slug = ‘$slug’

  16. ola daivid, eu assisti seu tutorial que é muito bom,
    mais gostaria de trabalhar com as duas maneiras de urls

    ex: noticias.php, noticias.php?id=90 e assim por diante,
    como ficaria meu .htaccess e meus links

    obrigado e te mais

  17. amigo eu preciso muito de tua ajuda..,tou com uma loja virtual quase pronta no meu localhost,com varios produtos inseridos,só que eu queria saber como eu faço para colocar URLs amigáveis nesses produtos…pode me dar uma ajuda?desde ja agradeço..

  18. Oi David, tudo bem?

    Muito boa a Vídeo Aula, parabéns!
    Gostaria só de retirar duas dúvidas.

    1 – Existe algum modo de criar um url amigável sem o auxilio do .htaccess ?

    2 – Quando envio a url (meusite.com/post/1) os .css, .js e todos os outros arquivos incluídos no html do site, mesmo com o endereço correto, não são incluídos.
    Já tentei de todas as formas, mas ele não incluí, então vim aqui pedir um auxílio.

    Comecei a estudar php pela internet, já que não tenho condições financeiras para pagar um bom curso, e suas vídeo aulas assim como as vídeo aulas do VAB estão me ajudando muito.

    Estou utilizando uma estrutura semelhante ao do WordPress para tentar criar meu primeiro blog de notícias:
    meusite . com/content/theme/meutema/home.php

    O CSS fica na pasta “meutema”.

    Se puder me auxiliar em um modo de recuperar os arquivos incluídos da maneira correta, ficarei muito agradecido.

    Desde já, obrigado pelo conhecimento compartilhado e pelas vídeo aulas.

    Abraço.

    1. @Victor, vou tentar responder as questões:

      1 – É possível, mas terá q ter index.php, exemplo: seusite.com.br/index.php/urlamigavel . Lembrando que o htaccess seria quando vc utilizar o servidor Apache, o IIS, o arquivo web.config, pra informar pra servidor como deve interpretar a requisição

      2 – No caso vc precisa colocar o endereço completo até o css, js, imagens : seusite.com.br/content/theme/meutema/css/styles.css

      abrs

  19. Como seria o .htaccess para que ele oculta as extensões e ao mesmo tempo passe parâmetros, tentei isso mais as duas não funcionam juntas:

    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d

    RewriteRule ^(.*)\/?$ index.php?url=$1 [NC,L]
    RewriteRule ^([a-z,0-9,A-Z,_-]+)$ /$1.php

  20. Olá David ótima documentação, parabéns!
    Estou com a seguinte situação:
    Realizei o tratamento da minha url e está rodando corretamente, até para as validações para url que não correspondem ao meu site está rodando liso, mas enfim.
    tenho http://www.meusite.com.br/contato; http://www.meusite.com.br/noticias etc… quando acesso a página principal do site index.php o servidor retorna essa url => http://www.meusite.com.br/index
    Qual o tratamento para remover o /index deixando somente http://www.meusite.com.br como se apresenta no primeiro acesso ao mesmo? Lembrando que a regra do meu .htaccess está igual a da documentação apresentada nessa página.

    Abs.

    1. Fernando, se no caso a ultima a parte da URL q seria a página, então basta sempre resgatar o final

      $page = getPage();
      $end  = end($page); //aqui vc pega o elemento de um array
      
    1. Bruno, vai ser bem complicado fazer video aula, até tutorial tá complicado de fazer, mas se consegui um tempo de folga, vou ver se volta a fazer videoaulas.

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *