Está en la página 1de 18

Acesso a Dados No Delphi for PHP

delphi for php


desvendando os segredos dos componentes data access

Olha a primeira coisa e configurar ou verificar se ja esta configurado:


va o diretorio "C:\WINDOWS\system32\drivers\etc" no meu caso o windows xp....
abra o arquivo com 2 cliques "services" e verifica se existe uma linha ou add a mesma..

gds_db 3050/tcp

sem dúvida nenhuma o tempo sempre foi um fator decisivo no desenvolvimento que
agregado à qualidade torna esta tarefa um desafio. como produzir sistemas com
qualidade em tempo hábil? como obter produtividade no desenvolvimento de meus
projetos?

nos últimos anos a indústria de ti tem investido fortemente em ferramentas que


aumentem a produtividade, prova disso foi o lançamento pela codegear do delphi for
php. uma ferramenta rad para php que une uma linguagem de scripts multiplataforma,
multi-bancos e free com o poder e a versatilidade da vcl. isso tudo somado a filosofia da
orientação a objetos, segmento onde a borland possui uma larga experiência, torna o
delphi for php uma ferramenta bem completa que vem preencher uma lacuna que havia
entre o desenvolvimento web em php e a produtividade.

para provar o que estou falando vamos neste artigo desenvolver uma pequena aplicação
e você verá como os componentes da vcl nos proporcionam esta produtividade,
principalmente no que diz respeito a persistência em banco de dados, mas antes gostaria
de deixar aqui algumas observações importantes.

como este veículo tem em seus leitores maioria de programadores delphi e que para
muitos a linguagem php é uma novidade, acho por bem expor aqui algumas das
particularidades desta linguagem, pois apesar da ide ser bem parecida com a do bds2006
a linguagem de desenvolvimento é a php, e sendo assim devemos respeitar a sintaxe
desta linguagem.

em primeiro lugar o php é case sensitive por tanto muita atenção na hora de declarar e
de referenciar suas variáveis, métodos e classes, pois diferente do delphi uma letra
maiúscula aqui faz toda diferença e na verdade declarar não seria o termo ideal a ser
empregado nos casos das variáveis. isto porque em php não precisamos declarar as
variáveis e explicitar o seu tipo, essa linguagem não é tipada como o delphi. os
operadores lógicos e de atribuição também são diferentes e isso pode se tornar uma dor
de cabeça para muitos iniciantes que vem do delphi e se deparam com o php, isso
porque podemos por um lapso escrevermos a seguinte sentença:

if (!($id = null) )
{

echo (‘variável não é nula);

há um erro de sintaxe na instrução acima, mas pode acreditar será muito comum se você
é iniciante em php, pois é quase que automático, está no sangue compararmos valores
com o símbolo "=", porém operador de igualdade no php é "= =" e o de atribuição sim
que é "=".

outro ponto importante é quanto ao escopo das variáveis dentro do script. quando
queremos fazer referência a uma variável global dentro de um método, precisamos de
dentro do mesmo informar que esta variável é global, pois de outra forma será criada
uma nova variável local. um exemplo claro disso é quando adicionamos um data
module ao nosso projeto. não basta clicarmos em file -> use unit ou ctrl+f11 precisamos
em cada método informarmos o objeto que representa o nosso data module com a
palavra global e a partir daí utilizarmos nossos componentes de acesso a dados. ex:

function button1click ($sender, $params)

global $dm;

$dm->tbcliente1->close ();

digo isto pois tenho visto inúmeras dúvidas em diversos fóruns devido a este problema.
nosso objetivo neste artigo não é a linguagem em si e sim a utilização da ferramenta,
para mais informações quanto à sintaxe e funções do php aconselho a leitura do manual
php disponível em http://www.php.net/manual/pt_br/index.php .

chega de papo e mãos a obra!

nosso projeto consiste em criar um exemplo onde manipularemos dados utilizando os


componentes data access da vcl. veremos alguns recursos importantes da ide e algumas
técnicas do php, como passagem de parâmetros via url com método get e como nos
prevenirmos de sql injection.

inicie uma nova aplicação no delphi for php clicando em file->new -> application:
salve esta página como index.php e o projeto com o nome que melhor lhe convir. neste
ponto é importante salientar que o nome do arquivo aqui faz toda a diferença pois nós
faremos referência a eles em nossos links, eles serão as nossas páginas. já a propriedade
name referencia a página, ou melhor a classe dentro do script, é criada também uma
variável global $name que nada mais é do que um objeto do tipo desta classe. ainda
neste ponto adicione ao projeto um data module. file -> new -> data module, salve como
datamodule.php. altere a propriedade name do nosso data module para dm, a partir de
agora devemos utilizar variável global $dm se quisermos acessar os recursos desta
classe. observe:
configurar a conexão com o banco de dados é bem simples. nesse exemplo utilizaremos
o interbase mais especificamente o banco dbdemos.gdb. a ide trás um recurso interno
que nos possibilita registrar bases de dados sem a necessidade de ferramentas externas
tudo isso através do data explorer, uma aba que se encontra no project manager. nesta
aba temos a opção de registrarmos bancos interbase e mysql e com isso visualizarmos as
tabelas e os campos contidos em nosso banco, mas isso não nos impede de fazermos
conexão com outros servidores de banco de dados, pois os componentes database
possuem uma propriedades chamada drivername onde podemos selecionar o driver de
acesso ao banco de dados desejado.
clique com o botão direito do mouse sobre interbase e clique em register database para
registrar seu banco de dados:

a tela de registro pede os parâmetros de configuração padrão os mesmo que estamos


acostumados no delphi tradicional. basta informar o host, path do arquivo de dados,
username e password além de um nome para identificar esta conexão.

se você possui alguma versão do delphi instalada em seu computador facilmente


encontrará o banco dbdemos.gdb em c:\arquivos de programas\arquivos
comuns\borland shared\data\dbdemos.gdb. eu lhe aconselho a criar uma pasta chamada
data dentro da pasta do seu projeto e então colocar nela uma cópia do banco, faça a
mesma coisa para as imagens usadas no projeto, crie uma pasta imagens e coloque nela
as imagens utilizadas no projeto. o username e password são os padrões do interbase:
sysdba e masterkey respectivamente.
a conexão está feita e configurada, a partir de agora temos acesso a todas as tabelas do
banco bem como todos os campos dessas tabelas através da própria ide utilizando a
treeview do data explorer.

valendo-se do bom e velho drag and drop vamos adicionar ao nosso data module os
componentes que necessitamos para realizar o acesso às tabelas do nosso banco de
dados. note que na parte superior esquerda do data explorer há quatro botões. eles
servem para determinar qual componente data controls você quer que seja adicionado
quando arrastarmos uma tabela ou um campo para um form. no caso do data modulo só
serão adicionados os componentes data acess. os dois primeiros botões estão
relacionados às tabelas e os dois últimos aos campos, são eles: dbgrid, dbrepeater, label
e edit. com isso você pode escolher qual componente quer que seja adicionado ao form
quando arrastar para o mesmo um campo ou tabela.

neste exemplo vamos utilizar a tabela customer. clique sobre ela e arraste-a para dentro
do nosso data module. observe que são colocado três componentes em nosso data
module devidamente conectados entre si: um database, uma table e um datasource. eu
irei manter os nomes default mas o ideal é renomeá-los para algo mais sugestivo através
de sua propriedade name. o componente database tem a função de realizar a conexão
com o banco de dados e através dele que podemos criar nosso dicionário de dados, onde
podemos configurar diversas propriedades dos campos de nossas tabelas.

o processo e bem simples, vá ate a propriedades dictionary e insira um nome para o


nosso dicionário, por exemplo dicartigophp. agora clique com o botão direito sobre o
componente database e no menu popup clique em create dictionary, uma mensagem
aparecerá confirmando a criação do dicionário de dados e está pronto, simples assim.
uma nova tabela foi criada em nosso banco de dados para ser o nosso dicionário.
observe:
através dele podemos por exemplo substituir os captions que aparecem nos dbgrid
através da propriedade display label. basta incluirmos um registro informando o nome
da tabela, o campo, qual propriedade queremos alterar, o valor que queremos que
apareça no label da grid, ex:

1 – customer – country – displaylabel – pais

desta forma as grids linkadas a esta tabela mostrarão para este campo seus caption
alterados automaticamente conforme as configurações do nosso dicionário de dados.

vamos agora ao desenvolvimento do nosso form ou melhor da nossa página. em nossa


página index.php vamos adicionar um componente image, um panel, e um dbgrid.
dentro deste panel adicione três labels sendo que dois deles serão nossos links.

para localizar mais rapidamente os componentes na tool palette a ide também oferece
um recurso, basta pressionar o atalho ctrl+alt+p e digitar o nome de um componente,
dbgrid por exemplo. um filtro irá selecionar o componente bastando pressionar enter
para que o componente seja adicionando a página. os usuários do dbs2006 já estão
habituados com esse recurso. disponha os componentes na página da maneira que achar
melhor.

precisamos acessar os componentes do nosso data module. para isso vamos declarar que
esta página utilizará recursos que estão em outra página. menu file-> use unit ou
simplesmente alt+f11, selecione datamodule.php e pressione ok. agora basta apontar a
propriedade datasource do dbgrid para dm.dscustomer1, executar a aplicação e ver o
resultado:
observe que de uma forma simples e rápida disponibilizamos em nossa página uma grid
com os dados de nossa tabela e sem escrever uma única linha sequer, isso é rad. este
componente dbgrid ainda nos permite mais, por exemplo: os dados exibidos na tela
podem ser editados diretamente na grid sem a necessidade de nenhum comando. basta
dar um duplo clique sobre ao campo, editar os dados e pressionar enter para que seja
gravado no banco. simples assim !!

podemos ainda ocultar colunas, mudá-las de posição e redimensioná-las tudo isso


através do componente da vcl com seus métodos e esse é apenas um dos mais de 50
componentes existentes na vcl.

vamos adicionar um pouco mais de emoção ao nosso projeto. nossa aplicação terá um
menu que será montado dinamicamente para apresentar todos os países onde possuímos
clientes e ao clicarmos em um país vamos mostrar em uma página, também montada
dinamicamente, os clientes do país selecionado.

dentro do panel, abaixo do label "by country", vamos adicionar um componente


chamado dbrepeater e dentro dele adicionar mais um label. apague o caption deste
componente, coloque uma cor no fundo e altere seu nome para lbcountry.
esses são os componentes que precisamos para nosso menu: um dbrepeater e um label. o
dbrepeater é mostrado na tela para cada registro do dataset ao qual está conectado, desta
forma todos os componentes que estiverem contidos nele também serão "repetidos".
com isso podemos fazer com que esses componentes se comportem ou assumam valores
de acordo com o registro corrente do dataset. realizaremos uma consulta ao banco que
nos retornará os países onde possuímos clientes e passaremos o resultado ao dbrepeater
para que ele se encarregue do resto. quando digo passar o resultado quero dizer "linkar"
o dbrepeater ao dataset em questão através da propriedade datasource. faça isto:

adicione um componente query ao nosso datamodule e altere as seguintes propriedades:

database dbdbdemos1
limit count -1
limitstart -1
active true
sql select distinct country from customer

o database dispensa comentários, é através dele que a nossa query se conecta ao banco.
limitcount -1 indica que a query irá mostrar todos os registros que forem retornados pela
consulta, se colocarmos por exemplo limitcount 10 nossa query mostraria somente 10
registros.

limitstart configura a partir de que posição os registro serão mostrados, -1 indica que
não há um start configurado. como em limitcount, se colocarmos limitstart 10, nossa
query retornaria os registros a partir da décima posição. active abre a nossa query e
executa o comando contido em sql no nosso caso "select distinct country from
customer".

insira também um datasource altere seu nome para dsmenu e aponte-o para a query que
acabamos de configurar. volte ao dbrepeater e aponte a propriedade datasource para
dm.dsmenu. os componentes que irão formar o nosso menu já estão configurados. como
falei, o dbrepeater será "renderizado" tantas vezes quantos registros forem retornados
em nossa query, e com isso nosso label também será, sendo assim, vamos fazer com que
o label mostre em seu caption o nome do país corrente no momento em que for
mostrado na tela. faremos isso através do evento beforeshow do label.

selecione o label lbcountry clique na aba events do object inspector e dê um duplo -


clique no evento onbeforeshow, no evento criado digite o código abaixo:

global $dm;
$sender->caption = $dm->query1->country;

$sender->link = "search.php?id=". $dm->query1->country;

como o php não é compilado, pode-se digitar praticamente qualquer coisa e mandar
executar a página no servidor e lá um erro será gerado. porém antes de executarmos um
script podemos verificar a integridade da sintaxe, para isso a ide disponibiliza um
recurso chamado syntax check, podemos então verificar se há erros em nosso código
antes de executá-lo.

caso haja algum erro uma mensagem é exibida no panel message na parte inferior da ide
mostrando a linha, o arquivo onde o erro ocorreu e a mensagem de erro. também
podemos acessá-lo através do menu view -> message.
sintaxe verificada e ok, resta executar a aplicação para vermos o resultado:
repare que temos uma página pronta, acessando uma base de dados, estamos realizando
consultas e criando um menu dinamicamente e com quantas linhas de código? apenas
três. esta é a produtividade que eu falava no início do artigo, isto é possível pois os
componentes possuem propriedades e encapsulam métodos que proporcionam essa
versatilidade. foi o que fizemos no evento beforeshow, antes de mostrá-lo ao usuário
configuramos as propriedades caption e link com os dados da query linkada ao
dbrepeater:

$sender->caption = $dm->query1->country;
na instrução seguinte chamamos a página search.php que criaremos em seqüência e
passamos para ela, via url, um valor através da variável "id":

$sender->link = "search.php?id=". $dm->query1->country;

essa prática é muito comum quando desenvolvemos um site dinâmico, pois temos a
necessidade de passar alguns valores de uma página para a outra, para podermos, então,
realizar operações como consultas, filtros e inserções no banco, autenticação de
usuários, etc. no php os dois métodos mais utilizados para isso são o get e post. neste
exemplo utilizaremos o método get onde os valores e seus respectivos identificadores
são transmitidos pela url, não sendo preciso a abertura de uma nova conexão.

como os valores são passados pela url, há um limite para o número de bytes que serão
enviados, que neste método é de no máximo 1024 caracteres, o que nos limita bastante.
para casos onde haja necessidade de se passar valores mais extensos utilizamos o
método post, mas isso fica para uma outra oportunidade, nos resta agora criar a página
search.php que irá receber nosso parâmetro e montar nossa página dinamicamente.

adicione um novo form ao projeto. file-> new-> form. salve-o como search.php.
adicione à página um dbrepeater, e dentro dele seis labels. altere a propriedade name de
cada label para lbcompany, lbadd, lbcity, lbcountry, lbphone e lbcontact. disponha-os na
tela de maneira organizada, coloque o font.size do lbcompany para 15px, font.weight
para bold e font.style para fsitalic. no dbrepeater altere a propriedade borderwidth para
1. abaixo uma idéia :

como dito anteriormente todo dbrepeater precisa estar conectado a um dataset, neste
caso vamos conectá-lo a tabela tbcustomer1 que será filtrada mais a frente para exibir os
clientes de acordo com o país selecionado. vá até a propriedade datasource do
dbrepeater e aponte-a para dm.dscustomer1. agora configure o evento beforeshow de
cada label para mostrar o valor dos seus respectivos campos na tela. os códigos são bem
parecidos mudando apenas o nome do campo que será exibido. configure os eventos
onbeforeshow de cada label seguindo o exemplo abaixo:

para lbcompany:

global $dm;

$sender->caption = $dm->tbcustomer1->company;
para lbadd:

global $dm;

$sender->caption = $dm->tbcustomer1->addr1;

para lbcity:

global $dm;

$sender->caption = $dm->tbcustomer1->city;

para lbcountry:

global $dm;

$sender->caption = $dm->tbcustomer1->country;

para lbphone:

global $dm;

$sender->caption = $dm->tbcustomer1->phone;

para lbcontact :

global $dm;

$sender->caption = $dm->tbcustomer1->contact;

nosso dbrepeater e nossos labels já estão prontos para mostrar os dados, falta apenas
filtrar a tabela mediante o parâmetro que será passado pelo método get e é nesse ponto
que devemos nos habituar a tratar possíveis sql injection’s. claro que aqui não estamos
lidando com dados críticos porém esta é uma prática saudável que deve ser exercitada.
devemos ter em mente que se os valores são passados via url, e desta forma são visíveis
ao usuário, por isso devemos nos precaver que um usuário mal intencionado não irá
passar uma outra instrução que não aquela que estamos esperando. nada impede que ele
digite "search.php?id=qualquer coisa", no nosso caso isso não nos afetaria, a página
apenas não exibiria dados pois não há cliente com este país.

agora imagine o cenário onde temos uma página de login que recebe um usuário e senha
e consulta no banco para verificar a existência do usuário:

$usu = $_post[‘usuario’];

$pwd = $_post[‘senha’];

$query_string = "select * from user


where username = ‘ ".$usu." ‘and password = ‘ ".$pwd." ‘ ";

este é um script perfeito para ser vitima de sql injection, veja a instrução gerada se
passarmos a sentença abaixo como senha.

‘ or ‘a’ = ‘a

a instrução gerada seria:

select * from user

where username = ‘ a ‘and password = ‘‘ or ‘a’ = ‘a ‘

não há usuário com o nome a e com senha em branco porem a é igual a a, esta sentença
retornaria verdadeira e o acesso seria liberado.

este tipo de vulnerabilidade e facilmente tratada no php através da função addslashes (),
que insere uma barra invertida antes de cada aspa simples ou aspa dupla, veja:

$usu = addslashes( $_post[‘usuario’] );

$pwd = addslashes( $_post[‘senha’] );

$query_string = "select * from user

where username = ‘ ".$usu." ‘and password = ‘ ".$pwd." ‘ ";

desta vez a instrução gerada com a mesma senha passada acima seria:

select * from user

where username = ‘ a ‘and password = ‘\‘ or \‘a\’ = \‘a ‘

este é um comando simples mas de extrema importância e nós faremos uso dele.

no carregamento da página search.php vamos verificar o parâmetro passado e de posse


dele filtramos os dados da nossa tabela para exibirmos os clientes do país selecionado.
como nosso dbrepeater já esta linkado a tabela ele se encarregará de montar a página
com os dados.

com o form selecionado vá até a aba events do object inspector e localize o evento
onshow, dê um duplo clique neste evento e digite o código abaixo:

$id = addslashes( $_get[id] );

//se o parâmetro não é nulo

if (!($id = = null))
{

global $dm;

$dm->tbcustomer1->close();

$dm->tbcustomer1->filter = "country = " . $id . " ";

$dm->tbcustomer1->open();

o código é bem simples, utilizamos a "super global" $_get para capturar o valor passado
via url e entre os [ ] colocamos o nome do parâmetro que queremos capturar, pois
poderíamos passar mais de um parâmetro como por exemplo pagina.php?
action=deletar&id=125 ou produto.php?cat=25&fab=125&cód=256. utilizamos a
função addslashes() para previnir possíveis sql injection e passamos o parâmetro para
uma variável local $id.

após fazer uma verificação quanto ao conteúdo da variável, fechamos nossa tabela,
passamos um comando para a propriedade filter, concatenando o campo country com o
país passado como parâmetro:

$dm->tbcustomer1->filter = "country = brasil ";

feito isso abrimos a tabela e voila, temos uma página contendo os clientes do país
selecionado:
conclusão

este artigo não teve a pretensão de abordar todos os aspectos dos componentes de acesso
a dados do delphi php, porém ele demonstra de uma forma simples como realizar
operações no banco de dados utilizando os principais componentes. com as informações
aqui expostas, é possível adicionar mais recursos ao nosso projeto como por exemplo,
colocar um link na página acima para cada cliente que ao ser acessado nos remeteria
para uma página que mostraria informações detalhadas deste cliente, como últimos
pedidos, média de compras, produtos mais comprados, etc.

questões como layout, tratamentos de erros e desempenho não são abordados neste
artigo, mas devem ser levadas em consideração. o exemplo disponível para download
possui algumas páginas a mais onde trabalho com frames entre outras coisas.

sem dúvida nenhuma produtividade é a palavra chave, e espero que isso tenha ficado
claro com o projeto acima. esta é uma ferramenta nova e há muito ainda que se aprender
sobre ela, e não há feedback melhor do que aquele vindo de que quem está à frente da
batalha, então não deixe de entrar em contato, envie suas dúvidas e sugestões pois terei
prazer em respondê-los.

um grande abraço a todos e até a próxima.