1) O documento discute três métodos para acessar bancos de dados MySQL no PHP: a extensão MySQL, mysqli e PDO, explicando as diferenças entre eles.
2) Apresenta exemplos de como listar dados de múltiplas tabelas relacionadas usando joins e múltiplos queries.
3) Explica o padrão master-detail para organizar informações em páginas separadas, passando parâmetros via URL.
1. PHP + MySQL: diferentes métodos de acesso ao
MySQL + master-detail
Carlos Santos
LabMM 4 - NTC - DeCA - UA
Aula 17, 02-05-2013
2. Diferentes métodos de acesso ao MySQL
Em PHP existem pelo 3 métodos principais de acesso ao MySQL:
• PHP’s MySQL Extension: é o método “histórico” e só permite acesso
procedimental. Já não é atualizado e vai deixar de ser suportado em
futuras versões do PHP (v5.5);
• PHP’s mysqli Extension: é uma versão para substituir a versão “histórica”
e disponibiliza versões procedimental e orientada a objetos. Tem uma
melhor performance e mais métodos;
• PDO (PHP Data Objects): é uma camada de abstração para bases de
dados com suporte para MySQL e muitos outros SGBDR. Só tem versão
orientada a objetos. Em teoria, permite mudar de SGBDR sem ser
necessário alterar o código...
http://www.php.net/manual/en/mysqli.overview.php
3. Diferenças entre as APIs
http://www.php.net/manual/en/mysqlinfo.api.choosing.php
5. Visualizar dados de várias tabelas
Quando queremos visualizar dados que estão distribuídos por duas
tabelas ligadas entre si, podemos:
• criar uma query baseado num JOIN que permita obter todos os dados;
• criar vários recordsets de acordo com a informação necessária a mostrar
na página
A solução adequada depende da situação a que se aplica!
7. Listar os mariachis
$query = "SELECT idMariachi, nome FROM Mariachi";
$rsMari = mysql_query($query , $connection);
while ($row_rsMari = mysql_fetch_assoc($rsMari)){
echo $row_rsMari[“nome"];
}
8. Listar os mariachis com a respetiva família
$query = "SELECT Mariachi.idMariachi, Mariachi.nome,
Familia.nomeFamilia FROM Mariachi INNER JOIN Familia ON
Mariachi.Familia_idFamilia = Familia.idFamilia";
$rsMari = mysql_query($query , $connection);
while ($row_rsMari = mysql_fetch_assoc($rsMari)){
echo $row_rsMari[“nome"].” - “.
$row_rsMari[“nomeFamilia”].”<br/>”;
}
9. Listar os mariachis com família (not so good)
$query = "SELECT idMariachi, nome, Familia_idFamilia FROM
Mariachi";
$rsMari = mysql_query($query , $connection);
while ($row_rsMari = mysql_fetch_assoc($rsMari)){
$qFami = "SELECT nomeFamilia FROM Familia WHERE
idFamilia = ".$row_rsMari[“Familia_idFamilia”];
$rsFami = mysql_query($qFami , $connection);
$row_rsFami = mysql_fetch_assoc($rsFami);
echo $row_rsMari[“nome"].” - “.
$row_rsFami[“nomeFamilia].”<br/>”;
}
10. Observações
Uma página pode ter muitos recordsets
Os valores obtidos num recordset podem ser utilizados para filtrar
resultados a obter noutro recordset
Soluções com múltiplos acessos há BD são, normalmente, mais lentas
No entanto, existem circunstâncias em que a quantidade de informação
resultante de um INNER JOIN pode justificar a opção por múltiplos
queries!
11. master - detail
Nesta estrutuura de informação temos:
• uma página master que lista vários tópicos de um modo genérico;
• uma página detail que permite ver os detalhes do tópico escolhido na
página master
Que informação é necessário transferir entre as páginas?
master
item1
item2
item3
detail
detalhes do item
escolhido na página
master
voltar
querystring: id_item
.../page.php?a=5
13. Exemplo: master > familias.php
$qFami = "SELECT * FROM Familia";
$rsFami = mysql_query($qFami , $connection);
while ($row_rsFami = mysql_fetch_assoc($rsFami)){
$line = ‘<p><a href=”mariachisFamilia.php?id=’.
$row_rsFami[“idFamilia”].
’”>’.
$row_rsFami[“nomeFamilia"].
‘</a></p>’;
echo $line;
}
os URLs na página ficam com o formato: “mariachisFamilia.php?id=3”
14. Exemplo: detail > mariachisFamilia.php
$idValue = intval($_GET['id']);
$qMari = "SELECT * FROM Mariachi
WHERE Familia_idFamilia = ".$idValue;
$rsMari = mysql_query($qMari , $connection);
while ($row_rsMari = mysql_fetch_assoc($rsMari)){
$line = ‘<p>$row_rsMari[“nome”]</p>’;
echo $line;
}
Como mostrar nesta página o nome da família?
• um recordset baseado numa query com join ou dois recordsets?
15. Exemplo: master-detail (parte 2)
master: listar todas as famílias
detail: listar os mariachis dessa família
e incluir o número de relacionamentos com chicas
16. Exemplo: master-detail (parte 2)
Soluções a discutir:
• um query único baseado num INNER JOIN entre Mariachis e
Mariachi_has_chica com operação de COUNT e filtragem pelo Mariachi?
• um query para o nome do Mariachi e um query para contar o número de
registos do Mariachi em Mariachi_has_Chica?
17. Exemplo: master-detail (parte 2)
Problema com query único, típico destas situações:
• se um Mariachi não tiver uma ocorrência em Mariachi_has_Chica o
resultado será um recordset vazio! Porquê?
• logo, não será possível mostrar os dados da informação pessoal do
Mariachi
Neste cenário, a solução a adotar deve ser a segunda!
... ou ainda melhor... uma solução com OUTER JOIN
• TPC -> implementar esta solução :)
18. Exemplo: master-detail (parte 2)
Por vezes é necessário ter partes do código que só são executadas se um
determinado recordset está ou não vazio. Essas zonas são designadas
por zonas condicionais.
Por exemplo:
• se o mariachi nunca teve relacionamentos devemos apresentar uma
mensagem adequada: “este mariachi não é um bom exemplo :(”
• nos outros casos mostrar o número de relacionamentos
como implementar este tipo de condição?
• if ($rsName) ... // se existirem resultados ...