Skip to content

3. Noções básicas do PHP

3.1. Um primeiro exemplo

Abaixo, você encontrará um programa que apresenta as primeiras características do PHP.

3.1.1. O programa (exemple_01)


<?php

// este é um comentário
// variável usada sem ter sido declarada
$nom = "dupont";

// uma exibição na tela
print "nom=$nom\n";

// um array com elementos de tipos diferentes
$tableau = array("un", "deux", 3, 4);

// o número de elementos
$n = count($tableau);

// um loop
for ($i = 0; $i < $n; $i++)
  print "tableau[$i]=$tableau[$i]\n";

// inicialização de duas variáveis com o conteúdo de uma matriz
list($chaine1, $chaine2) = array("chaine1", "chaine2");

// concatenação das duas cadeias de caracteres
$chaine3 = $chaine1 . $chaine2;

// exibição do resultado
print "[$chaine1,$chaine2,$chaine3]\n";

// uso de 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 retornar um resultado
$res1 = f1(4);
print "res1=$res1\n";

// uma função pode retornar uma matriz de valores
list($res1, $res2, $res3) = f2();
print "(res1,res2,res3)=[$res1,$res2,$res3]\n";

// esses valores poderiam ter sido recuperados em um array
$t = f2();
for ($i = 0; $i < count($t); $i++)
  print "t[$i]=$t[$i]\n";

// testes
for ($i = 0; $i < count($t); $i++)
// exibe apenas os canais
  if (getType($t[$i]) == "string")
    print "t[$i]=$t[$i]\n";

// outros testes
for ($i = 0; $i < count($t); $i++){
// exibe apenas os números inteiros maiores que 10
  if (getType($t[$i]) == "integer" and $t[$i] > 10)
    print "t[$i]=$t[$i]\n";
}

// um loop 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:

nom=dupont
tableau[0]=un
tableau[1]=deux
tableau[2]=3
tableau[3]=4
[chaine1,chaine2,chaine1chaine2]
chaine=chaine1
type[4]=integer
type[chaine1]=string
type[Array]=array
type[a changé]=string
res1=14
(res1,res2,res3)=[un,0,100]
t[0]=un
t[1]=0
t[2]=100
t[0]=un
t[2]=100
t[0]=8
t[1]=5
somme=13

Comentários

  • linha 5: em PHP, não se declara o tipo das variáveis. Elas têm um tipo dinâmico que pode variar ao longo do tempo
  • $nom representa a variável de identificador nom
  • linha 8: para escrever na tela, pode-se usar a instrução print ou a instrução echo
  • linha 11: a palavra-chave array permite definir uma matriz. A variável $nom[$i] representa o elemento $i da matriz $tableau.
  • linha 14: a função count($tableau) retorna o número de elementos da matriz $tableau
  • linha 18: as cadeias de caracteres são delimitadas por 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 em uma 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 retornar valores por meio 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 lugar do código.
  • linha 90: a função predefinida getType($variable) retorna uma sequência de caracteres que representa o tipo de $variable. Esse tipo pode mudar ao longo do tempo.
  • linha 79: a função predefinida exit encerra o script.

3.2. O escopo das variáveis

3.2.1. Programa 1 (exemple_02)


<?php

// escopo das variáveis

function f1() {
  // usa-se a variável global $i
  $i = &$GLOBALS["i"];
  $i++;
  $j = 10;
  print "f1[i,j]=[$i,$j]\n";
}

function f2() {
  // usa-se a variável global $i
  $i = &$GLOBALS["i"];
  $i++;
  $j = 20;
  print "f2[i,j]=[$i,$j]\n";
}

function f3() {
  // usa-se uma variável local $i
  $i = 4;
  $j = 30;
  print "f3[i,j]=[$i,$j]\n";
}

// testes
$i = 0;
$j = 0;  // essas duas variáveis são conhecidas por uma função f por meio da matriz $GLOBALS
f1();
f2();
f3();
print "test[i,j]=[$i,$j]\n";
?>

Os resultados:

1
2
3
4
f1[i,j]=[1,10]
f2[i,j]=[2,20]
f3[i,j]=[4,30]
test[i,j]=[2,0]

Comentários

  • linhas 29-30: definem duas variáveis, $i e $j, do programa principal. Essas variáveis não são reconhecidas dentro 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 acessar uma variável $variable do programa principal por meio de uma tabela de variáveis globais chamada $GLOBALS. Na linha 7, a notação $GLOBALS["i"] refere-se à variável global $i do programa principal. Se escrevermos
$i=$GLOBALS["i"]

à variável local $i é atribuído o valor da variável global $i. Trata-se de duas variáveis diferentes, e alterar a variável local $i não alterará a variável global $i. A notação

$i=&Globals["i"]

faz com que a variável local $i tenha o mesmo endereço 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 escopo de uma variável é global aos blocos de código
$i = 0; {
  $i = 4;
  $i++;
}
print "i=$i\n";
?>

Os resultados:

i=5

Comentários

Em algumas linguagens, uma variável definida entre chaves tem o escopo dessas chaves: ela não é reconhecida fora delas. Os resultados acima mostram que isso não acontece no PHP. A variável $i, definida na linha 5 dentro das chaves, é a mesma 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++;
}

// exclusã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";

// exclusã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:

tab1 a 6 éléments
tab1[0]=0
tab1[1]=1
tab1[2]=2
tab1[3]=3
tab1[4]=4
tab1[5]=5
tab1 a 6 éléments
tab1[0]=0
tab1[1]=1
tab1[2]=2
tab1[3]=3
tab1[4]=4
tab1[5]=5
tab1 a 8 éléments
tab1[0]=0
tab1[1]=1
tab1[2]=2
tab1[3]=3
tab1[4]=4
tab1[5]=5
tab1[6]=6
tab1[7]=7
tab1 a 7 éléments
tab1[0]=0
tab1[1]=1
tab1[2]=2
tab1[3]=3
tab1[4]=4
tab1[5]=5
tab1[6]=6
tab1 a 6 éléments
tab1[0]=1
tab1[1]=2
tab1[2]=3
tab1[3]=4
tab1[4]=5
tab1[5]=6
tab1 a 7 éléments
tab1[0]=1
tab1[1]=2
tab1[2]=3
tab1[3]=4
tab1[4]=5
tab1[5]=6
tab1[6]=-2
tab1 a 8 éléments
tab1[0]=-1
tab1[1]=1
tab1[2]=2
tab1[3]=3
tab1[4]=4
tab1[5]=5
tab1[6]=6
tab1[7]=-2

Comentários

O programa acima demonstra operações de manipulação de uma matriz de valores. Existem duas formações para as matrizes em PHP:

$tableau=array("un",2,"trois")
$contraires=array("petit"=>"grand", "beau"=>"laid", "cher"=>"bon marché")

A tabela 1 é chamada de tabela e a tabela 2, de dicionário, onde os elementos são representados como chave => valor. A notação $contraires["beau"] designa o valor associado à chave “belo”. Portanto, neste caso, trata-se da sequência “feio”. A tabela 1 é apenas uma variante do dicionário e poderia ser representada da seguinte forma:

$tableau=array(0=>"un",1=>2,2=>"trois")

Assim, temos $tableau[2] = “três”. No fim das contas, trata-se apenas de dicionários. No caso de uma matriz 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, ela retorna um par (chave, valor) desse dicionário.
  • linha 14: a função reset($dictionnaire) posiciona a função each no primeiro par (chave, valor) do dicionário.
  • linha 15: o loop while é interrompido quando a função each retorna 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 array é percorrido com um foreach. Esse elemento sintático permite percorrer um dicionário, e portanto um array, de acordo com duas sintaxes:
foreach($dictionnaire as $clé=>$valeur)
foreach($tableau as $valeur)

A primeira sintaxe retorna um par (clé,valeur) a cada iteração, enquanto a segunda sintaxe retorna 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) remove 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";

// classificaçã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";

// busca por uma chave
existe($conjoints, "Jacques");
existe($conjoints, "Lucette");
existe($conjoints, "Jean");

// exclusã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:

Nombre d'éléments du dictionnaire : 4
conjoints[Pierre]=Gisèle
conjoints[Paul]=Virginie
conjoints[Jacques]=Lucette
conjoints[Jean]=
conjoints[Jacques]=Lucette
conjoints[Jean]=
conjoints[Paul]=Virginie
conjoints[Pierre]=Gisèle
clés[0]=Jacques
clés[1]=Jean
clés[2]=Paul
clés[3]=Pierre
valeurs[0]=Lucette
valeurs[1]=
valeurs[2]=Virginie
valeurs[3]=Gisèle
La clé [Jacques] existe associée à la valeur [Lucette]
La clé [Lucette] n'existe pas
La clé [Jean] existe associée à la valeur []
Nombre d'éléments du dictionnaire : 3
conjoints[Jacques]=Lucette
conjoints[Paul]=Virginie
conjoints[Pierre]=Gisèle

Comentários

O código anterior aplica a um dicionário o que foi visto anteriormente para uma matriz simples. Comentaremos apenas as novidades:

  • linha 13: a função ksort (classificação por chave) permite classificar um dicionário na ordem natural das chaves.
  • linha 21: a função array_keys($dictionnaire) exibe a lista de chaves do dicionário na forma de tabela
  • linha 26: a função array_values($dictionnaire) retorna a lista de valores do dicionário na forma de tabela
  • linha 47: a função isset($variable) retorna true se a variável $variable tiver sido definida; caso contrário, retorna false.
  • linha 36: a função unset($variable) exclui 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));
// navegação
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:

multi[0][0]=0
multi[0][1]=1
multi[0][2]=2
multi[1][0]=10
multi[1][1]=11
multi[1][2]=12
multi[1][3]=13
multi[2][0]=20
multi[2][1]=21
multi[2][2]=22
multi[2][3]=23
multi[2][4]=24
multi[zéro][0]=0
multi[zéro][1]=1
multi[zéro][2]=2
multi[un][0]=10
multi[un][1]=11
multi[un][2]=12
multi[un][3]=13
multi[deux][0]=20
multi[deux][1]=21
multi[deux][2]=22
multi[deux][3]=23
multi[deux][4]=24

Comentários

  • linha 5: os elementos da matriz $multi são, por sua vez, matrizes
  • linha 12: a matriz $multi se transforma em um dicionário (clé,valeur), no qual cada valeur é uma matriz

3.3.4. Relações entre cadeias de caracteres e tabelas (exemple_07)


<?php

// conversão de string para matriz
$chaine = "1:2:3:4";
$tab = explode(":", $chaine);

// percorro matriz
print "tab a " . count($tab) . " éléments\n";
for ($i = 0; $i < count($tab); $i++)
  print "tab[$i]=$tab[$i]\n";

// matriz para string
$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:

tab a 4 éléments
tab[0]=1
tab[1]=2
tab[2]=3
tab[3]=4
chaine2=1:2:3:4
chaîne=1:2:3:4:
tab a 5 éléments
tab[0]=1
tab[1]=2
tab[2]=3
tab[3]=4
tab[4]=
chaîne=1:2:3:4::
tab a 6 éléments
tab[0]=1
tab[1]=2
tab[2]=3
tab[3]=4
tab[4]=
tab[5]=

Comentários

  • linha 5: a função explode($séparateur,$chaine) permite recuperar os campos de $chaine separados por $séparateur. Assim, explode(":",$chaine) permite recuperar, na forma de tabela, os elementos de $chaine que estão separados pela sequência de caracteres ":".
  • A função implode($séparateur, $tableau) realiza a operação inversa à função explode. Ela retorna uma sequência 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 strings
$chaine1 = "un";
$chaine2 = 'un';
print "[$chaine1,$chaine2]\n";
?>

Resultados:

[un,un]

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 string1 e string2
  if ($chaine1 == $chaine2)
    print "[$chaine1] est égal à [$chaine2]\n";
  else
    print "[$chaine1] est différent de [$chaine2]\n";
}

?>

Resultados:

1
2
3
[abcd] est égal à [abcd]
[] est égal à []
[1] est différent de []

3.5. Expressões regulares (exemple_10)


<?php

// expressões regulares em PHP
// recuperar os diferentes campos de uma string

// o modelo: uma sequência de números entre caracteres quaisquer
// queremos recuperar apenas a sequência de números
$modèle = "/(\d+)/";
// comparamos a string com o modelo
compare($modèle, "xyz1234abcd");
compare($modèle, "12 34");
compare($modèle, "abcd");

// o padrão: uma sequência de números entre caracteres quaisquer
// queremos a sequência de números, bem como os campos que a precedem e a seguem
$modèle = "/^(.*?)(\d+)(.*?)$/";
// comparamos a sequência 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 sequência $chaîne com o modelo $modèle
  // a string é comparada ao 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:

Résultats(/(\d+)/,xyz1234abcd)
champs[0]=1234
champs[1]=1234

Résultats(/(\d+)/,12 34)
champs[0]=12
champs[1]=12

Résultats(/(\d+)/,abcd)
La chaîne [abcd] ne correspond pas au modèle [/(\d+)/]

Résultats(/^(.*?)(\d+)(.*?)$/,xyz1234abcd)
champs[0]=xyz1234abcd
champs[1]=xyz
champs[2]=1234
champs[3]=abcd

Résultats(/^(.*?)(\d+)(.*?)$/,12 34)
champs[0]=12 34
champs[1]=
champs[2]=12
champs[3]= 34

Résultats(/^(.*?)(\d+)(.*?)$/,abcd)
La chaîne [abcd] ne correspond pas au modèle [/^(.*?)(\d+)(.*?)$/]

Résultats(/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/,10/05/97)
champs[0]=10/05/97
champs[1]=10
champs[2]=05
champs[3]=97

Résultats(/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/,  04/04/01  )
champs[0]=  04/04/01  
champs[1]=04
champs[2]=04
champs[3]=01

Résultats(/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/,5/1/01)
La chaîne [5/1/01] ne correspond pas au modèle [/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/]

Résultats(/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/,187.8)
champs[0]=187.8
champs[1]=
champs[2]=187.8

Résultats(/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/,-0.6)
champs[0]=-0.6
champs[1]=-
champs[2]=0.6

Résultats(/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/,4)
champs[0]=4
champs[1]=
champs[2]=4

Résultats(/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/,.6)
champs[0]=.6
champs[1]=
champs[2]=.6

Résultats(/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/,4.)
champs[0]=4.
champs[1]=
champs[2]=4.

Résultats(/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/, + 4)
champs[0]= + 4
champs[1]=+
champs[2]=4

Comentários

  • linhas 3-4: aqui utilizamos expressões regulares para extrair os diversos campos de uma sequência de caracteres. As expressões regulares permitem superar as limitações da função implode. O princípio consiste em comparar uma sequência de caracteres com outra sequência chamada modèle, utilizando a função preg_match:

$correspond = preg_match($modèle, $chaîne, $champs);

A função preg_match retorna um valor booleano se a modèle puder ser encontrada na chaîne. Se sim, $champs[0] representa a subcadeia correspondente ao modelo. Além disso, se o modelo contiver submodelos entre parênteses, $champs[1] é o trecho 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: ele designa uma sequência de um ou mais (+) dígitos (\d) posicionados em qualquer lugar de uma string. Além disso, o modelo define um submodelo entre parênteses.

  • linha 10: o modelo /(\d+)/ (sequência de um ou mais dígitos em qualquer lugar da string) é comparado à string “xyz1234abcd”. Vemos que a subseqüência 1234 corresponde ao modelo. Portanto, teremos $champs[0] igual a “1234”. Além disso, o padrão possui subpadrões entre parênteses. Teremos $champs[1] = “1234”.
  • linha 11: o padrão /(\d+)/ é comparado à sequência "12 34". Percebe-se que as subsequências 12 e 34 correspondem ao padrão. A comparação é interrompida na primeira subsequência que corresponde ao padrão. Teremos, portanto, $champs[0]=12 e $champs[1]=12.
  • linha 12: o padrão /(\d+)/ é comparado à sequência “abcd”. Não é encontrada nenhuma correspondência.

Vamos explicar os padrões utilizados no restante do código:


$modèle = "/^(.*?)(\d+)(.*?)$/";

início da sequência (^), seguido de 0 ou mais (*) caracteres quaisquer (.), seguido de 1 ou mais (+) dígitos, seguido novamente de 0 ou mais (*) caracteres quaisquer (.). O padrão (.*) designa 0 ou mais caracteres quaisquer. Um padrão desse tipo corresponderá a qualquer sequência. Assim, o padrão /^(.*)(\d+)(.*)$/ nunca será encontrado, pois o primeiro subpadrão (.*) absorverá toda a sequência. O padrão (.*?)(\d+) designa 0 ou mais caracteres quaisquer até o subpadrão seguinte (?), neste caso \d+. Portanto, os algarismos agora não são mais 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:

f[i,j]=[1,1]
test[i,j]=[1,0]

Comentários

O código acima mostra os dois modos de passagem de parâmetros para uma função. Vejamos o seguinte exemplo:

1
2
3
4
5
6
7
function f(&$a,$b){

}

// programa principal
$i=10; $j=20;
f($i,$j);
  • linha 1: define os parâmetros formais $a e $b da função f. Essa função processa esses dois parâmetros formais e retorna um resultado.
  • linha 7: chamada da função f com dois parâmetros efetivos $i e $j. As relaçõ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. Em outras palavras, $a e $i são duas referências ao mesmo endereço de 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. Esse modo de passagem é adequado para parâmetros de saída e dados volumosos, como tabelas e dicionários. Esse modo de passagem é chamado de 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 efeito sobre o parâmetro efetivo $j. É o que mostra a execução do código. Esse 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 os valores desses 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. Portanto, trata-se de parâmetros de saída (eles são modificados). Assim, escreveremos:
function échange(&$a,&$b){....}

3.7. Resultados retornados por uma função (exemple_12)


<?php

// resultados retornados por uma função
// uma função pode retornar vários valores em um array
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 retornar um pseudo-objeto
$res = f2(10);
print "[$res->res1,$res->res2,$res->res3]\n";

// fim
exit;

// função f1
function f1($valeur) {
  // retorna um array ($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

1
2
3
4
5
[11,12,13]
res[0]=11
res[1]=12
res[2]=13
[11,12,13]

Comentários

  • O programa anterior mostra que uma função PHP pode retornar um conjunto de resultados, e não apenas um, na forma de uma matriz ou de um objeto. O conceito de objeto é explicado mais adiante
  • linhas 19-22: a função f1 retorna vários valores na forma de uma matriz
  • linhas 25-33: a função f2 retorna vários valores na forma de um objeto

3.8. Arquivos de texto (exemple_13)


<?php

// processamento sequencial de um arquivo de texto
// este é um conjunto de linhas no formato login:pwd:uid:gid:infos:dir:shell
// cada linha é inserida em um dicionário no formato login => uid:gid:infos:dir:shell

// define-se o nome do arquivo
$INFOS = "infos.txt";

// abrimos o arquivo para 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 arquivo
fclose($fic);

// explora-se o arquivo — o `fgets` mantém o marcador de fim de linha
// isso evita que uma string vazia seja recuperada ao ler uma linha em branco
// abre-se o arquivo para gravação
if (!$fic = fopen($INFOS, "r")) {
  print "Erreur d'ouverture du fichier $INFOS en lecture\n";
  exit;
}
while ($ligne = fgets($fic, 1000)) {
  // remove-se o marcador de fim de linha, se houver
  $ligne = cutNewLineChar($ligne);
  // colocamos a linha em uma matriz
  $infos = explode(":", $ligne);
  // recupera-se o login
  $login = array_shift($infos);
  // ignora-se a senha
  array_shift($infos);
  // cria-se uma entrada no dicionário
  $dico[$login] = $infos;
}
// fechamos o dicionário
fclose($fic);

// análise do dicionário
afficheInfos($dico, "login10");
afficheInfos($dico, "X");

// fim
exit;

// --------------------------------------------------------------------------
function afficheInfos($dico, $clé) {
  // exibe o valor associado à chave no dicionário $dico, se ele existir
  if (isset($dico[$clé])) {
    // valor existe — é uma matriz?
    $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) {
  // a marca de fim de linha de $ligne é removida, 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 arquivo 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:

[login10,uid10:gid10:infos10:dir10:shell10]
la clé [X] n'existe pas

Comentários

  • linha 11: fopen(nom_fichier,"w") abre o arquivo nom_fichier para gravação (w=write). Se o arquivo não existir, ele será criado. Se já existir, seu conteúdo será apagado. Se a criação falhar, fopen retornará 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) grava chaîne no arquivo $fic.
  • linha 20: fclose($fic) fecha o arquivo $fic.
  • linha 25: fopen(nom_fichier,"r") abre o arquivo nom_fichier para leitura (r=read). Se a abertura falhar (o arquivo não existir), fopen retorna um valor false.
  • linha 29: fgets($fic,1000) lê a próxima linha do arquivo, com um limite de 1.000 caracteres. Na operação while ($ligne = fgets($fic, 1000)) {…}, há duas operações sucessivas: 1) $ligne = fgets(...) 2) while ( ! $ligne). Depois que o último caractere do arquivo for lido, a função fgets retorna a string vazia e o loop while é encerrado.
  • 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 remove o eventual caractere de fim de linha.
  • linha 72: a função strlen($chaîne) retorna o número de caracteres de $chaîne.
  • linha 73: a função substr($ligne, $position, $taille) retorna $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 sequência “\n”.
  • linha 35: a função array_shift($tableau) remove o primeiro elemento de $tableau e o retorna como resultado.
  • linha 37: a função array_shift($tableau) é utilizada, mas seu resultado é ignorado
  • linha 57: a função is_array($variable) retorna true se $variable for uma matriz; caso contrário, retorna false.
  • linha 58: a função join faz o mesmo que a função implode já vista