• Olá Visitante, se gosta do forum e pretende contribuir com um donativo para auxiliar nos encargos financeiros inerentes ao alojamento desta plataforma, pode encontrar mais informações sobre os várias formas disponíveis para o fazer no seguinte tópico: leia mais... O seu contributo é importante! Obrigado.

Trabalhar com ficheiros - Leitura

helldanger1

GForum VIP
Entrou
Ago 1, 2007
Mensagens
29,631
Gostos Recebidos
1
Introdução


De vez em quando é necessário ler, alterar ou criar ficheiros no servidor de Internet, como por exemplo, para criar contadores de acesso, estatísticas de visitas ou guardar algumas informações para visualizações posteriores que são demoradas para serem criadas pelo servidor, e que não seria muito bom gerá-las sempre que um visitante as quisesse ver.

O PHP fornece um conjunto de funções muito boas para isto, e com alguns cuidados, os scripts funcionarão tanto em Windows como em Linux sem nenhuma alteração. Todas essas funções podem ser encontradas no manual do php, em "Filesystem functions".

Abrir ficheiros


A primeira função que se deve conhecer para trabalhar com ficheiros é a que cria uma ligação entre o script e o ficheiro propriamente dito:

int fopen( string ficheiro, string modo [, int usa_include_path] );

Esta função devolve um ponteiro para um ficheiro, que é utilizado noutras funções para lidar com ficheiros. O primeiro parâmetro, ficheiro, é uma string que indica o local do ficheiro a ser aberto, aqui vai a primeira dica: não utilize o modo de referência do windows, como c:\www\ficheiro.txt, pois não irá funcionar num servidor linux! Evite também ler e gravar ficheiros fora do directório onde o teu site está hospedado, às vezes torna-se difícil criar um directório fora do directório do site, e, se um dia quiseres transferir o teu site para uma outra máquina, pode acontecer que te esqueças daquele directório isolado. Vamos supor que o site tem um subdirectório "tmp" e que tem dentro um ficheiro novidades.txt. Para abrir o ficheiro usamos:

<?php
$fd = fopen( "tmp/novidades.txt", "r" );
...
?>

Note que mesmo que este script seja executado em windows ele irá funcionar. Excelente! Nada melhor que programar com uma linguagem que funciona em vários sistemas operativos sem alterações!
O segundo parâmetro informa o PHP que o ficheiro deve ser aberto so para leitura, os modos possíveis podem ser:

r - so leitura, coloca o ponteiro no início do ficheiro
r+ - leitura e gravação, coloca o ponteiro no início do ficheiro
w - so gravação, limpa o ficheiro (deixa-o com 0 bytes) e coloca o ponteiro no início do ficheiro. Se o ficheiro não existir, tenta criá-lo.
w+ - leitura e gravação, limpa o ficheiro (deixa-o com 0 bytes) e coloca o ponteiro no início do ficheiro. Se o ficheiro não existir, tenta criá-lo
a - so gravação, coloca o ponteiro no final do ficheiro. Se o ficheiro não existir, tenta criá-lo.
a+ - leitura e gravação, limpa o ficheiro (deixa-o com 0 bytes) e coloca o ponteiro no final do ficheiro. Se o ficheiro não existir, tenta criá-lo

Existe ainda a opção "b" que pode ser utilizada com os modos (sozinha não funciona!), esta opção indica que o ficheiro deve ser tratado como binário em vez de texto, ou seja, se o programa for lidar com imagens em vez de um ficheiro de texto comum. É de vital importância no windows para ler imagens, ou caso contrário o programa não irá funcionar. Como o Linux e Unix não fazem diferença entre um ficheiro de texto e um binário, essa opção não terá nenhum efeito, portanto, se o seu programa for trabalhar com imagens, não custa nada adicionar esta opção. (programas multiplataforma são excelentes!)

AVISO: Como no windows (95/98/CE/ME) não existe permissão de acesso a ficheiros os programas funcionarão como desejado, podemos criar ficheiros, acede-los, excluí-los e muito mais. No Linux começam a surgir alguns problemas, normalmente os ficheiros e directórios de um servidor de Internet são de um utilizador e o servidor http (apache, por exemplo) corre como um outro utilizador, o php corre com o mesmo utilizador do servidor http, portanto se este utilizador não tiver permissão para gravar num directório, não será possível criar os ficheiros pelo php, nem alterá-los.

O terceiro parâmetro é opcional, e se seu valor for 1, o php irá procurar nos directórios informados na configuração "include_path" do php.ini.

Se a função fopen falhar ao abrir ou ao criar o ficheiro, ela retorna false. Note que se for utilizado o parâmetro "r"(somente leitura) ou "r+" e o ficheiro não existir, a função fopen não irá tentar criá-lo, simplesmente retornará um erro, e mostrará um aviso no browser do utilizador.
Caso não seja muito bom mostrar esse tipo de erro para o utilizador (toda a gente que vir essa mensagem vai querer ler esse ficheiro directamente no browser), utilize o @ antes da função e confira o resultado:

<?php
$fd = @fopen( "tmp/novidades.txt", "r" ) or die( "ops, avise o webmaster, que está a faltar um ficheiro no servidor");
...
?>

Mesmo que tenhas a certeza que este ficheiro está por lá, usa este método, pois nem sempre as coisas são como esperamos.

Fechar ficheiros


Depois de aberto ou criado o ficheiro, é sempre bom deixar a mesa arrumada após o serviço, portanto devemos fechar o ficheiro. É muito fácil:

int fclose( int fp );

O parâmetro fp é o ponteiro de ficheiro que foi retornado pela função fopen(), no nosso caso $fd. Esta função retorna true se o ficheiro foi fechado e false se não foi possível fechar o ficheiro. O ficheiro precisa ser fechado no mesmo script que o abriu.
 

helldanger1

GForum VIP
Entrou
Ago 1, 2007
Mensagens
29,631
Gostos Recebidos
1
O que fazer com os ficheiros


Nem só de abrir e fechar ficheiros vive um script php, é necessário fazer alguma coisa com eles. A "coisa" mais fácil é mostrar o conteúdo do ficheiro no browser do utilizador, para isso utilizamos a função "int fpassthru( int fp )". Então, para mostrar o ficheiro novidades.txt, que contém as últimas notícias da semana directamente para o browser do utilizador, o script fica assim:

<?php
$fd = @fopen( "tmp/novidades.txt", "r" ) or die( "ops, avise o webmaster, tem ficheiro faltando no servidor");
fpassthru( $fd );
?>

A função fpassthru lê a partir da posição actual do ponteiro até ao final do ficheiro e fecha o ficheiro, portanto, neste caso não é necessário utilizar a função fclose() (podes tentar, mas vai provocar um erro). Se estás a correr este script, notarás que o ficheiro novidades.txt saiu com as linhas juntas, para resolver isto coloca um <br> no final de cada linha do ficheiro ou deixa o script entre as tags <pre>. Se tentares colocar alguns scripts php dentro do ficheiro novidades.txt notarás que eles serão mostrados no browser do utilizador e não serão processados pelo php. Se quiseres adicionar um script php á página, utilza include ou require. Se só for necessário mostrar o ficheiro novidades directamente no browser sem precisar de posicionar o ponteiro, utiliza a função readfile, que abre o ficheiro, mostra e fecha o mesmo:

<?php
if( !@readfile( "tmp/novidades.txt") ) die ("ops, chame o webmaster!");
?>

Claro, existem muitas funções para ler o ficheiro: (todas elas dependem do ponteiro do ficheiro, e não do facto de fechar o ficheiro)

- string fread( int fp, int tamanho )

Lê o ficheiro apartir da posição actual do ponteiro no ficheiro até ao tamanho em bytes ou até o final do ficheiro, o que acontecer primeiro, e devolve como uma string.

<?php
// este script faz a mesma coisa que o anterior
if( $fd = @fopen( "tmp/novidades.txt", "r" ) ) {
while( !feof( $fd ) ) {
$novidades = fread( $fd, 1024 );
print $novidades;
}
fclose($fd);
}
?>

Enquanto não chegar ao final do ficheiro ( feof() ), lê até 1024 bytes do ficheiro para a variável $novidades e imprime seu conteúdo.

- string fgetc( int fp )

Lê so um caractére do ficheiro. Não utilize esta função para ler mais do que um caractere de um mesmo ficheiro, não é eficiente, é mais eficiente ler o ficheiro em blocos para a memória e fazer o processamento na memória, pois o acesso ao disco é extremamente lento se comparado com o acesso à memória, e aceder ao disco para ler um só caractere para processar é um enorme disperdício de recursos do servidor. Tenta trocar a função fread pela fgetc no script acima e usa um ficheiro novidades.txt com alguns kbytes para perceberes a ideia. Imagina 10.000 hits/hora com um script desses!

- string fgets( int fp, int tamanho )

Se precisas de ler o ficheiro linha á linha, utiliza esta função. Ela lê até que 1 byte seja lido, que encontre o final de uma linha (que é incluída no resultado), ou final do ficheiro e devolve como uma string. Para ler até 10 bytes de um ficheiro, utilize:

$texto = fgets( $fd, 11 );

- string fgetss( int fp, int tamanho [, string tagspermitidas] )

Idêntica à função fgets, só que os tags html e php serão ignoradas. Se for necessário deixar alguns tags passarem pela função, utiliza o parâmetro opcional tagspermitidas, por exemplo, para ler um ficheiro novamente, mas deixar so as tags <br>, <b></b> e <p></p> serem exibidas, use:

$texto = fgetss( $fd, 1024, "<br><b><p>" );

Mesmo podendo selecionar quais tags que podem passar pela função, se este ficheiro vier de fora, ou seja, é um ficheiro que uma pessoa manda pela internet para mostra no site, alguém pode mandar algum código javascript malicioso dentro de uma tag, e executar comandos indevidos na máquina do visitante do seu site. Cuidado!

array file( string ficheiro [, int usa_include_path ] )

Lê o ficheiro inteiro e coloca cada linha do ficheiro numa tabela. Esta função utiliza como parâmetro o nome do ficheiro, portanto não é necessário abrir nem fechar o ficheiro para usar esta função. Vamos ao exemplo:

Supondo que o ficheiro novidades.txt tem uma novidade por linha, similar a este: novidade.txt

Nova versão do php acaba de ser lançada!
Linux eleito melhor sistema operativo do mundo!
*Encontrado mais um furo de segurança no dind.
O número de servidores linux cresce a cada dia!

Queremos mostrar cada linha do ficheiro novidades com um fundo diferente, e ainda por cima as linhas que contém um * no início devem ser exibidas em negrito

<html>
<head><title>Novidades</title></head>
<body>
<?php
$txt = @file("tmp/novidades.txt");
if(!$txt) {
print "Sem novidades por hoje, só o webmaster é que vai receber um responso";
exit;
}
// count retorna o número de índices da tabela
$tot = count($txt);
?>
<table width="500" align="center" bgcolor="white" cellpadding="1" cellspacing="0">
<?php
for($i=0;$i<$tot;$i++) {
// ct vai ler o primeiro caractere da linha
$ct=$txt[$i][0];
// Chop elimina espaços do final da string e finais de linha também
$linha = Chop($txt[$i]);
// Seleciona a cor de fundo para a linha
if( $cor == "#DCDCDC" ) $cor = "#DCDCFF";
else $cor = "#DCDCDC";
print "<tr><td bgcolor='$cor'>";
// strip_tags elimina todas as tags html e php, como fgetss
// se a linha começa com um *, le a partir do próximo caractere
// o ponto serve para concatenar as strings
if( $ct == "*" ) print "<b>".strip_tags(substr($linha,1))."</b>";
else print strip_tags($linha);
print "</td></tr>";
}
?>
</table>
</body>
</html>

Por hoje aprendemos várias funções de leitura de dados apartir de ficheiros, em breve falaremos de funções de escrita.
 
Topo