3. Noções básicas do PHP
3.1. Um primeiro exemplo
Abaixo, encontra-se um programa que apresenta as primeiras características do PHP.
3.1.1. O programa (exemple_01)
<?php
// isto é um comentário
// variável utilizada sem ter sido declarada
$nom = "dupont";
// uma saída para o ecrã
print "nom=$nom\n";
// um array com elementos de tipos diferentes
$tableau = array("un", "deux", 3, 4);
// o seu número de elementos
$n = count($tableau);
// um ciclo
for ($i = 0; $i < $n; $i++)
print "tableau[$i]=$tableau[$i]\n";
// inicialização de duas variáveis com o conteúdo de um tabuleiro
list($chaine1, $chaine2) = array("chaine1", "chaine2");
// concatenação das duas cadeias
$chaine3 = $chaine1 . $chaine2;
// exibição do resultado
print "[$chaine1,$chaine2,$chaine3]\n";
// utilização de uma função
affiche($chaine1);
// o tipo de uma variável pode ser conhecido
afficheType($n);
afficheType($chaine1);
afficheType($tableau);
// o tipo de uma variável pode mudar durante a execução
$n = "a changé";
afficheType($n);
// uma função pode devolver um resultado
$res1 = f1(4);
print "res1=$res1\n";
// uma função pode devolver um tabuleiro de valores
list($res1, $res2, $res3) = f2();
print "(res1,res2,res3)=[$res1,$res2,$res3]\n";
// esses valores poderiam ter sido recuperados numa matriz
$t = f2();
for ($i = 0; $i < count($t); $i++)
print "t[$i]=$t[$i]\n";
// testes
for ($i = 0; $i < count($t); $i++)
// apenas exibe os canais
if (getType($t[$i]) == "string")
print "t[$i]=$t[$i]\n";
// outros testes
for ($i = 0; $i < count($t); $i++){
// apenas apresenta os números inteiros >10
if (getType($t[$i]) == "integer" and $t[$i] > 10)
print "t[$i]=$t[$i]\n";
}
// um ciclo «while»
$t = array(8, 5, 0, -2, 3, 4);
$i = 0;
$somme = 0;
while ($i < count($t) and $t[$i] > 0) {
print "t[$i]=$t[$i]\n";
$somme+=$t[$i]; //$somme=$somme+$t[$i]
$i++; //$i=$i+1
}
print "somme=$somme\n";
// fim do programa
exit;
//----------------------------------
function affiche($chaine) {
// exibe $chaine
print "chaine=$chaine\n";
}
//----------------------------------
function afficheType($variable) {
// exibe o tipo de $variable
print "type[$variable]=" . getType($variable) . "\n";
}
//----------------------------------
function f1($param) {
// soma 10 a $param
return $param + 10;
}
//----------------------------------
function f2() {
// retorna 3 valores
return array("un", 0, 100);
}
?>
Os resultados:
Comentários
- linha 5: em PHP, não se declara o tipo das variáveis. Estas têm um tipo dinâmico que pode variar ao longo do tempo
- $nom representa a variável com o identificador nom
- linha 8: para escrever no ecrã, pode utilizar-se a instrução print ou a instrução echo
- linha 11: a palavra-chave array permite definir um tabuláro. A variável $nom[$i] representa o elemento $i da matriz $tableau.
- linha 14: a função count($tableau) devolve o número de elementos da matriz $tableau
- linha 18: as cadeias de caracteres estão entre aspas " ou apóstrofos '. Dentro das aspas, as variáveis $variable são avaliadas, mas não dentro dos apóstrofos.
- linha 21: a função list permite reunir variáveis numa lista e atribuir-lhes um valor com uma única operação de atribuição. Aqui, $chaine1="cadeia1" e $chaine2="cadeia2".
- linha 24: o operador . é o operador de concatenação de cadeias de caracteres.
- linha 88: a palavra-chave function define uma função. Uma função pode ou não devolver valores através da instrução return. O código chamador pode ignorar ou recuperar os resultados de uma função. Uma função pode ser definida em qualquer parte do código.
- linha 90: a função predefinida getType($variable) devolve uma cadeia de caracteres que representa o tipo de $variable. Este tipo pode mudar ao longo do tempo.
- linha 79: a função predefinida exit interrompe o script.
3.2. O âmbito das variáveis
3.2.1. Programa 1 (exemple_02)
<?php
// âmbito das variáveis
function f1() {
// utiliza-se a variável global $i
$i = &$GLOBALS["i"];
$i++;
$j = 10;
print "f1[i,j]=[$i,$j]\n";
}
function f2() {
// utiliza-se a variável global $i
$i = &$GLOBALS["i"];
$i++;
$j = 20;
print "f2[i,j]=[$i,$j]\n";
}
function f3() {
// utiliza-se uma variável local $i
$i = 4;
$j = 30;
print "f3[i,j]=[$i,$j]\n";
}
// testes
$i = 0;
$j = 0; // estas duas variáveis são conhecidas por uma função f através da tabela $GLOBALS
f1();
f2();
f3();
print "test[i,j]=[$i,$j]\n";
?>
Resultados:
Comentários
- linhas 29-30: definem duas variáveis, $i e $j, do programa principal. Estas variáveis não são reconhecidas no interior das funções. Assim, na linha 9, a variável $j da função f1 é uma variável local da função f1 e é diferente da variável $j do programa principal. Uma função pode aceder a uma variável $variable do programa principal através de uma tabela de variáveis globais denominada $GLOBALS. Na linha 7, a notação $GLOBALS["i"] refere-se à variável global $i do programa principal. Se escrevermos
à variável local $i é atribuído o valor da variável global $i. Trata-se de duas variáveis diferentes e a alteração da variável local $i não alterará a variável global $i. A notação
faz com que a variável local $i tenha a mesma morada de memória que a variável global $i. Manipular a variável local $i equivale, portanto, a manipular a variável global $i.
3.2.2. Programa 2 (exemple_03)
<?php
// o âmbito de uma variável é global aos blocos de código
$i = 0; {
$i = 4;
$i++;
}
print "i=$i\n";
?>
Os resultados:
Comentários
Em algumas linguagens, uma variável definida entre chaves tem o âmbito destas: não é reconhecida fora delas. Os resultados acima mostram que isso não acontece em PHP. A variável $i definida na linha 5 dentro das chaves é a mesma que a utilizada nas linhas 4 e 8 fora delas.
3.3. As tabelas
3.3.1. Tabelas clássicas unidimensionais (exemple_04)
<?php
// matrizes clássicas
// inicialização
$tab1 = array(0, 1, 2, 3, 4, 5);
// iteração - 1
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
print "tab1[$i]=$tab1[$i]\n";
// iteração - 2
print "tab1 a " . count($tab1) . " éléments\n";
reset($tab1);
while (list($clé, $valeur) = each($tab1))
print "tab1[$clé]=$valeur\n";
// adição de elementos
$tab1[] = $i++;
$tab1[] = $i++;
// navegação - 3
print "tab1 a " . count($tab1) . " éléments\n";
$i = 0;
foreach ($tab1 as $élément) {
print "tab1[$i]=$élément\n";
$i++;
}
// eliminação do último elemento
array_pop($tab1);
// percurso - 4
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
print "tab1[$i]=$tab1[$i]\n";
// remoção do primeiro elemento
array_shift($tab1);
// percurso - 5
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
print "tab1[$i]=$tab1[$i]\n";
// adição ao final da tabela
array_push($tab1, -2);
// percurso - 6
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
print "tab1[$i]=$tab1[$i]\n";
// adição no início da tabela
array_unshift($tab1, -1);
// percurso - 7
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
print "tab1[$i]=$tab1[$i]\n";
?>
Os resultados:
Comentários
O programa acima mostra operações de manipulação de uma matriz de valores. Existem duas formas de notação para as matrizes em PHP:
A tabela 1 é designada por «tabela» e a tabela 2 por «dicionário», onde os elementos são representados pela forma chave => valor. A notação $contraires["beau"] designa o valor associado à chave «belo». Neste caso, trata-se da cadeia «feio». A tabela 1 é apenas uma variante do dicionário e poderia ser representada da seguinte forma:
Assim, temos $tableau[2] = «três». No final de contas, trata-se apenas de dicionários. No caso de uma tabela clássica com n elementos, as chaves são os números inteiros do intervalo [0,n-1].
- linha 15: a função each($tableau) permite percorrer um dicionário. A cada chamada, devolve um par (chave, valor) do mesmo.
- linha 14: a função reset($dictionnaire) posiciona a função each no primeiro par (chave, valor) do dicionário.
- linha 15: o ciclo while termina quando a função each devolve um par vazio no final do dicionário.
- linha 19: a notação $tableau[]=valor adiciona o elemento valeur como último elemento de $tableau.
- linha 25: o tabuleiro é percorrido com um foreach. Este elemento sintático permite percorrer um dicionário, ou seja, um tabuleiro, de acordo com duas sintaxes:
A primeira sintaxe devolve um par (clé,valeur) em cada iteração, enquanto a segunda sintaxe devolve apenas o elemento valeur do dicionário.
- linha 31: a função array_pop($tableau) remove o último elemento de $tableau
- linha 39: a função array_shift($tableau) elimina o primeiro elemento de $tableau
- linha 47: a função array_push($tableau,valor) adiciona valeur como último elemento de $tableau
- linha 39: a função array_unshift($tableau,valor) adiciona valeur como primeiro elemento de $tableau
3.3.2. O dicionário (exemple_05)
<?php
// dicionários
$conjoints = array("Pierre" => "Gisèle", "Paul" => "Virginie", "Jacques" => "Lucette", "Jean" => "");
// percurso - 1
print "Nombre d'éléments du dictionnaire : " . count($conjoints) . "\n";
reset($conjoints);
while (list($clé, $valeur) = each($conjoints))
print "conjoints[$clé]=$valeur\n";
// ordenação do dicionário pela chave
ksort($conjoints);
// percurso - 2
reset($conjoints);
while (list($clé, $valeur) = each($conjoints))
print "conjoints[$clé]=$valeur\n";
// lista de chaves do dicionário
$clés = array_keys($conjoints);
for ($i = 0; $i < count($clés); $i++)
print "clés[$i]=$clés[$i]\n";
// lista de valores do dicionário
$valeurs = array_values($conjoints);
for ($i = 0; $i < count($valeurs); $i++)
print "valeurs[$i]=$valeurs[$i]\n";
// pesquisa de uma chave
existe($conjoints, "Jacques");
existe($conjoints, "Lucette");
existe($conjoints, "Jean");
// eliminação de uma chave-valor
unset($conjoints["Jean"]);
print "Nombre d'éléments du dictionnaire : " . count($conjoints) . "\n";
foreach ($conjoints as $clé => $valeur) {
print "conjoints[$clé]=$valeur\n";
}
// fim
exit;
function existe($conjoints, $mari) {
// verifica se a chave $mari existe no dicionário $conjoints
if (isset($conjoints[$mari]))
print "La clé [$mari] existe associée à la valeur [$conjoints[$mari]]\n";
else
print "La clé [$mari] n'existe pas\n";
}
?>
Os resultados:
Comentários
O código anterior aplica a um dicionário o que foi visto anteriormente para uma tabela simples. Apenas comentamos as novidades:
- linha 13: a função ksort (key sort) permite ordenar um dicionário pela ordem natural da chave.
- linha 21: a função array_keys($dictionnaire) apresenta a lista de chaves do dicionário sob a forma de tabela
- linha 26: a função array_values($dictionnaire) apresenta a lista de valores do dicionário sob a forma de tabela
- linha 47: a função isset($variable) devolve «true» se a variável $variable tiver sido definida; caso contrário, devolve «false».
- linha 36: a função unset($variable) elimina a variável $variable.
3.3.3. Matrizes multidimensionais (exemple_06)
<?php
// tabelas multidimensionais clássicas
// inicialização
$multi = array(array(0, 1, 2), array(10, 11, 12, 13), array(20, 21, 22, 23, 24));
// percurso
for ($i1 = 0; $i1 < count($multi); $i1++)
for ($i2 = 0; $i2 < count($multi[$i1]); $i2++)
print "multi[$i1][$i2]=" . $multi[$i1][$i2] . "\n";
// dicionários multidimensionais
// inicialização
$multi = array("zéro" => array(0, 1, 2), "un" => array(10, 11, 12, 13), "deux" => array(20, 21, 22, 23, 24));
// navegação
foreach ($multi as $clé => $valeur)
for ($i2 = 0; $i2 < count($valeur); $i2++)
print "multi[$clé][$i2]=" . $multi[$clé][$i2] . "\n";
?>
Resultados:
Comentários
- linha 5: os elementos da tabela $multi são, por sua vez, tabelas
- linha 12: a matriz $multi transforma-se num dicionário (clé,valeur) em que cada valeur é uma matriz
3.3.4. Relações entre cadeias de caracteres e tabelas (exemple_07)
<?php
// conversão de cadeia de caracteres para tabela
$chaine = "1:2:3:4";
$tab = explode(":", $chaine);
// iteração de matriz
print "tab a " . count($tab) . " éléments\n";
for ($i = 0; $i < count($tab); $i++)
print "tab[$i]=$tab[$i]\n";
// matriz para cadeia de caracteres
$chaine2 = implode(":", $tab);
print "chaine2=$chaine2\n";
// vamos adicionar um campo vazio
$chaine.=":";
print "chaîne=$chaine\n";
$tab = explode(":", $chaine);
// percurso pela matriz
print "tab a " . count($tab) . " éléments\n";
for ($i = 0; $i < count($tab); $i++)
print "tab[$i]=$tab[$i]\n"; // agora temos 5 elementos, sendo o último vazio
// vamos adicionar novamente um campo vazio
$chaine.=":";
print "chaîne=$chaine\n";
$tab = explode(":", $chaine);
// percorrer a matriz
print "tab a " . count($tab) . " éléments\n";
for ($i = 0; $i < count($tab); $i++)
print "tab[$i]=$tab[$i]\n"; // agora temos 6 elementos, sendo que os dois últimos estão vazios
?>
Resultados:
Comentários
- linha 5: a função explode($séparateur,$chaine) permite recuperar os campos de $chaine separados por $séparateur. Assim, a função explode(":",$chaine) permite recuperar, sob a forma de tabela, os elementos de $chaine que estão separados pela cadeia de caracteres ":".
- A função implode($séparateur,$tableau) realiza a operação inversa à função explode. Ela devolve uma cadeia de caracteres formada pelos elementos de $tableau separados por $séparateur.
3.4. As cadeias de caracteres
3.4.1. Notação (exemple_08)
<?php
// comparação de cadeias de caracteres
$chaine1 = "un";
$chaine2 = 'un';
print "[$chaine1,$chaine2]\n";
?>
Resultados:
3.4.2. Comparação (exemple_09)
<?php
// testes de comparação de cadeias de caracteres
compare("abcd", "abcd");
compare("", "");
compare("1", "");
exit;
function compare($chaine1, $chaine2) {
// compara a cadeia1 e a cadeia2
if ($chaine1 == $chaine2)
print "[$chaine1] est égal à [$chaine2]\n";
else
print "[$chaine1] est différent de [$chaine2]\n";
}
?>
Resultados:
3.5. Expressões regulares (exemple_10)
<?php
// expressões regulares em PHP
// recuperar os diferentes campos de uma cadeia
// o padrão: uma sequência de algarismos rodeada por caracteres quaisquer
// pretende-se recuperar apenas a sequência de números
$modèle = "/(\d+)/";
// comparamos a cadeia com o padrão
compare($modèle, "xyz1234abcd");
compare($modèle, "12 34");
compare($modèle, "abcd");
// o padrão: uma sequência de números rodeada por caracteres quaisquer
// pretende-se a sequência de números, bem como os campos que a precedem e a seguem
$modèle = "/^(.*?)(\d+)(.*?)$/";
// comparamos a cadeia de caracteres com o modelo
compare($modèle, "xyz1234abcd");
compare($modèle, "12 34");
compare($modèle, "abcd");
// o modelo — uma data no formato dd/mm/aa
$modèle = "/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/";
compare($modèle, "10/05/97");
compare($modèle, " 04/04/01 ");
compare($modèle, "5/1/01");
// o modelo — um número decimal
$modèle = "/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/";
compare($modèle, "187.8");
compare($modèle, "-0.6");
compare($modèle, "4");
compare($modèle, ".6");
compare($modèle, "4.");
compare($modèle, " + 4");
// fim
exit;
// --------------------------------------------------------------------------
function compare($modèle, $chaîne) {
// compara a cadeia $chaîne com o modelo $modèle
// a cadeia é comparada com o modelo
$correspond = preg_match($modèle, $chaîne, $champs);
// exibição dos resultados
print "\nRésultats($modèle,$chaîne)\n";
if ($correspond) {
for ($i = 0; $i < count($champs); $i++)
print "champs[$i]=$champs[$i]\n";
} else
print "La chaîne [$chaîne] ne correspond pas au modèle [$modèle]\n";
}
?>
Resultados:
Comentários
- linhas 3-4: aqui utilizamos expressões regulares para extrair os vários campos de uma cadeia de caracteres. As expressões regulares permitem ultrapassar as limitações da função implode. O princípio consiste em comparar uma cadeia de caracteres com outra cadeia denominada modèle, utilizando a função preg_match:
$correspond = preg_match($modèle, $chaîne, $champs);
A função preg_match devolve um valor booleano se a modèle puder ser encontrada na chaîne. Se sim, $champs[0] representa a subcadeia correspondente ao modelo. Por outro lado, se o modelo contiver submodelos entre parênteses, $champs[1] é a parte de $chaîne correspondente ao primeiro submodelo, $champs[2] é a parte de $chaîne correspondente ao segundo submodelo, etc...
Consideremos o primeiro exemplo. O modelo é definido na linha 8: designa uma sequência de um ou mais (+) algarismos (\d) colocados em qualquer ponto de uma cadeia. Além disso, o modelo define um submodelo entre parênteses.
- linha 10: o modelo /(\d+)/ (sequência de um ou mais algarismos em qualquer ponto da cadeia) é comparado com a cadeia «xyz1234abcd». Verifica-se que a subcadeia 1234 corresponde ao modelo. Assim, teremos $champs[0] igual a «1234». Além disso, o padrão tem subpadrões entre parênteses. Teremos $champs[1] = «1234».
- linha 11: o padrão /(\d+)/ é comparado com a cadeia "12 34". Verifica-se que as subcadeias 12 e 34 correspondem ao padrão. A comparação termina na primeira subcadeia que corresponde ao padrão. Teremos, portanto, $champs[0]=12 e $champs[1]=12.
- linha 12: o padrão /(\d+)/ é comparado com a cadeia «abcd». Não é encontrada qualquer correspondência.
Vamos explicar os padrões utilizados no resto do código:
$modèle = "/^(.*?)(\d+)(.*?)$/";
início da cadeia (^), seguido de 0 ou mais (*) caracteres quaisquer (.), seguido de 1 ou mais (+) algarismos, seguido novamente de 0 ou mais (*) caracteres quaisquer (.). O padrão (.*) designa 0 ou mais caracteres quaisquer. Um padrão deste tipo corresponderá a qualquer cadeia. Assim, o padrão /^(.*)(\d+)(.*)$/ nunca será encontrado, pois o primeiro subpadrão (.*) absorverá toda a cadeia. O padrão (.*?)(\d+) designa, por sua vez, 0 ou mais caracteres quaisquer até ao subpadrão seguinte (?), neste caso \d+. Assim, os algarismos já não são absorvidos pelo padrão (.*). O padrão acima corresponde, portanto, a [début de chaîne (^), une suite de caractères quelconques (.*?), une suite d'un ou plusieurs chiffres (\d+), une suite de caractères quelconques (.*?), la fin de la chaîne ($)].
$modèle = "/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/";
corresponde a [début de chaîne (^), 2 chiffres (\d\d), le caractère / (\/), 2 chiffres, /, 2 chiffres, une suite de 0 ou plusieurs espaces (\s*), la fin de chaîne ($)]
$modèle = "/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/";
[début de chaîne (^), 0 ou plusieurs espaces (\s*), un signe + ou - [+|-] présent 0 ou 1 fois (?), une suite de 0 ou plusieurs espaces (\s*), 1 ou plusieurs chiffres suivis d'un point décimal suivi de zéro ou plusieurs chiffres (\d+\.\d*) ou (|) un point décimal (\.) suivi d'un ou plusieurs chiffres (\d+) ou (|) un ou plusieurs chiffres (\d+), une suite de 0 ou plusieurs espaces (\s*)].
3.6. Modo de passagem dos parâmetros das funções (exemple_11)
<?php
// modo de passagem dos parâmetros
function f(&$i, $j) {
// $i será obtido por referência
// $j será obtido por valor
$i++;
$j++;
print "f[i,j]=[$i,$j]\n";
}
// ----------------------------------------testes
$i = 0;
$j = 0;
// $i e $j passados por valor
f($i, $j);
print "test[i,j]=[$i,$j]\n";
?>
Resultados:
Comentários
O código acima mostra os dois modos de passagem de parâmetros para uma função. Vejamos o seguinte exemplo:
- linha 1: define os parâmetros formais $a e $b da função f. Esta função processa estes dois parâmetros formais e devolve um resultado.
- linha 7: chamada da função f com dois parâmetros efetivos $i e $j. As ligações entre os parâmetros formais ($a, $b) e os parâmetros efetivos ($i, $j) são definidas pela linha 7
- &$a: o símbolo & indica que o parâmetro formal $a assumirá como valor o endereço do parâmetro efetivo $i. Por outras palavras, $a e $i são duas referências à mesma localização na memória. Manipular o parâmetro formal $a equivale a manipular o parâmetro efetivo $i. É isso que a execução do código demonstra. Este modo de passagem é adequado para parâmetros de saída e para dados volumosos, tais como tabelas e dicionários. Este modo de passagem é designado por «passagem por referência».
- $b: o parâmetro formal $b assumirá o valor do parâmetro efetivo $j. Trata-se de uma passagem por valor. Os parâmetros formais e efetivos são duas variáveis diferentes. Manipular o parâmetro formal $b não tem qualquer impacto no parâmetro efetivo $j. É isso que a execução do código demonstra. Este modo de passagem é adequado para parâmetros de entrada.
- Considere a função échange, que aceita dois parâmetros formais: $a e $b. A função troca o valor destes dois parâmetros. Assim, durante uma chamada de troca ($i,$j), o código chamador espera que os valores dos dois parâmetros efetivos sejam trocados. Trata-se, portanto, de parâmetros de saída (são modificados). Escrever-se-á, portanto:
3.7. Resultados devolvidos por uma função (exemple_12)
<?php
// resultados devolvidos por uma função
// uma função pode devolver vários valores numa matriz
list($res1, $res2, $res3) = f1(10);
print "[$res1,$res2,$res3]\n";
$res = f1(10);
for ($i = 0; $i < count($res); $i++)
print "res[$i]=$res[$i]\n";
// uma função pode devolver um pseudo-objeto
$res = f2(10);
print "[$res->res1,$res->res2,$res->res3]\n";
// fim
exit;
// função f1
function f1($valeur) {
// retorna um tabuleiro ($valeur+1,$aleur+2,$baleur+3)
return array($valeur + 1, $valeur + 2, $valeur + 3);
}
// função f2
function f2($valeur) {
// retorna um pseudo-objeto ($valeur+1,$aleur+2,$baleur+3)
$res->res1 = $valeur + 1;
;
$res->res2 = $valeur + 2;
$res->res3 = $valeur + 3;
// retorna o objeto
return $res;
}
?>
Resultados
Comentários
- O programa anterior mostra que uma função PHP pode devolver um conjunto de resultados e não apenas um, sob a forma de uma matriz ou de um objeto. O conceito de objeto é explicado mais adiante
- linhas 19-22: a função f1 devolve vários valores na forma de uma matriz
- linhas 25-33: a função f2 devolve vários valores na forma de um objeto
3.8. Os ficheiros de texto (exemple_13)
<?php
// processamento sequencial de um ficheiro de texto
// este é um conjunto de linhas com o formato login:pwd:uid:gid:infos:dir:shell
// cada linha é inserida num dicionário com o formato login => uid:gid:infos:dir:shell
// define-se o nome do ficheiro
$INFOS = "infos.txt";
// abre-se o ficheiro em modo de criação
if (!$fic = fopen($INFOS, "w")) {
print "Erreur d'ouverture du fichier $INFOS en écriture\n";
exit;
}
// gera-se um conteúdo arbitrário
for ($i = 0; $i < 100; $i++)
fputs($fic, "login$i:pwd$i:uid$i:gid$i:infos$i:dir$i:shell$i\n");
// fecha-se o ficheiro
fclose($fic);
// explora-se o ficheiro — o fgets mantém o marcador de fim de linha
// isto permite não recuperar uma cadeia vazia ao ler uma linha em branco
// abre-se o ficheiro em modo de criação
if (!$fic = fopen($INFOS, "r")) {
print "Erreur d'ouverture du fichier $INFOS en lecture\n";
exit;
}
while ($ligne = fgets($fic, 1000)) {
// elimina-se o marcador de fim de linha, caso exista
$ligne = cutNewLineChar($ligne);
// colocamos a linha numa matriz
$infos = explode(":", $ligne);
// recupera-se o nome de utilizador
$login = array_shift($infos);
// ignora-se a palavra-passe
array_shift($infos);
// cria-se uma entrada no dicionário
$dico[$login] = $infos;
}
// fecha-se o dicionário
fclose($fic);
// exploração do dicionário
afficheInfos($dico, "login10");
afficheInfos($dico, "X");
// fim
exit;
// --------------------------------------------------------------------------
function afficheInfos($dico, $clé) {
// exibe o valor associado à chave no dicionário $dico, caso exista
if (isset($dico[$clé])) {
// o valor existe — será um array?
$valeur = $dico[$clé];
if (is_array($valeur)) {
print "[$clé," . join(":", $valeur) . "]\n";
} else {
// $valeur não é uma matriz
print "[$clé,$valeur]\n";
}
} else {
// $clé não é uma chave do dicionário $dico
print "la clé [$clé] n'existe pas\n";
}
}
// --------------------------------------------------------------------------
function cutNewLinechar($ligne) {
// remove-se o marcador de fim de linha de $ligne, caso exista
$L = strlen($ligne); // comprimento da linha
while (substr($ligne, $L - 1, 1) == "\n" or substr($ligne, $L - 1, 1) == "\r") {
$ligne = substr($ligne, 0, $L - 1);
$L--;
}
// fim
return($ligne);
}
?>
O ficheiro infos.txt:
login0:pwd0:uid0:gid0:infos0:dir0:shell0
login1:pwd1:uid1:gid1:infos1:dir1:shell1
login2:pwd2:uid2:gid2:infos2:dir2:shell2
...
login98:pwd98:uid98:gid98:infos98:dir98:shell98
login99:pwd99:uid99:gid99:infos99:dir99:shell99
Os resultados:
Comentários
- linha 11: fopen(nom_fichier,"w") abre o ficheiro nom_fichier em modo de escrita (w=write). Se o ficheiro não existir, é criado. Se existir, é esvaziado. Se a criação falhar, fopen devolve o valor false. Na instrução if (!$fic = fopen($INFOS, "w")) {…}, há duas operações sucessivas: 1) $fic = fopen(..) 2) if( ! $fic) {...}
- linha 18: fputs($fic, $chaîne) escreve chaîne no ficheiro $fic.
- linha 20: fclose($fic) fecha o ficheiro $fic.
- linha 25: fopen(nom_fichier,"r") abre o ficheiro nom_fichier em modo de leitura (r=read). Se a abertura falhar (o ficheiro não existir), o fopen devolve um valor false.
- linha 29: fgets($fic,1000) lê a linha seguinte do ficheiro, com um limite de 1000 caracteres. Na operação while ($ligne = fgets($fic, 1000)) {…}, há duas operações sucessivas: 1) $ligne = fgets(...) 2) while ( ! $ligne). Depois de o último carácter do ficheiro ter sido lido, a função fgets devolve a cadeia vazia e o ciclo while termina.
- linha 31: a função fgets lê uma linha de texto, incluindo o caractere de fim de linha. A função cutNewLineChar nas linhas 70-79 elimina o eventual caractere de fim de linha.
- linha 72: a função strlen($chaîne) devolve o número de caracteres de $chaîne.
- linha 73: a função substr($ligne, $position, $taille) devolve $taille caracteres de $ligne, a partir do caractere n.º $position, sendo que o primeiro caractere tem o n.º 0. Em máquinas Windows, o marcador de fim de linha é «\r\n». Em máquinas Unix, é a cadeia «\n».
- linha 35: a função array_shift($tableau) elimina o primeiro elemento de $tableau e devolve-o como resultado.
- linha 37: a função array_shift($tableau) é utilizada, mas o seu resultado é ignorado
- linha 57: a função is_array($variable) devolve true se $variable for um tabuleiro; caso contrário, devolve false.
- linha 58: a função join faz o mesmo que a função implode já abordada