Skip to content

3. Conceptos básicos de PHP

3.1. Un primer ejemplo

A continuación, se presenta un programa que muestra las primeras características de PHP.

3.1.1. El programa (exemple_01)


<?php

// esto es un comentario
// variable utilizada sin haber sido declarada
$nom = "dupont";

// una salida a pantalla
print "nom=$nom\n";

// una matriz con elementos de diferentes tipos
$tableau = array("un", "deux", 3, 4);

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

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

// inicialización de 2 variables con el contenido de un array
list($chaine1, $chaine2) = array("chaine1", "chaine2");

// concatenación de las dos cadenas
$chaine3 = $chaine1 . $chaine2;

// visualización del resultado
print "[$chaine1,$chaine2,$chaine3]\n";

// uso de una función
affiche($chaine1);

// se puede conocer el tipo de una variable
afficheType($n);
afficheType($chaine1);
afficheType($tableau);

// el tipo de una variable puede cambiar durante la ejecución
$n = "a changé";
afficheType($n);

// una función puede devolver un resultado
$res1 = f1(4);
print "res1=$res1\n";

// una función puede devolver una matriz de valores
list($res1, $res2, $res3) = f2();
print "(res1,res2,res3)=[$res1,$res2,$res3]\n";

// se podrían haber recuperado estos valores en un array
$t = f2();
for ($i = 0; $i < count($t); $i++)
  print "t[$i]=$t[$i]\n";

// pruebas
for ($i = 0; $i < count($t); $i++)
// solo muestra los canales
  if (getType($t[$i]) == "string")
    print "t[$i]=$t[$i]\n";

// otras pruebas
for ($i = 0; $i < count($t); $i++){
// solo muestra los números enteros mayores que 10
  if (getType($t[$i]) == "integer" and $t[$i] > 10)
    print "t[$i]=$t[$i]\n";
}

// un bucle 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";

// fin del programa
exit;

//----------------------------------
function affiche($chaine) {
  // muestra $chaine
  print "chaine=$chaine\n";
}

//----------------------------------
function afficheType($variable) {
  // muestra el tipo de $variable
  print "type[$variable]=" . getType($variable) . "\n";
}

//----------------------------------
function f1($param) {
  // suma 10 a $param
  return $param + 10;
}

//----------------------------------
function f2() {
  // devuelve 3 valores
  return array("un", 0, 100);
}
?>

Los 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

Comentarios

  • línea 5: en PHP, no se declara el tipo de las variables. Estas tienen un tipo dinámico que puede variar con el tiempo
  • $nom representa la variable de identificador nom
  • línea 8: para escribir en pantalla, se puede usar la instrucción print o la instrucción echo
  • línea 11: la palabra clave array permite definir un array. La variable $nom[$i] representa el elemento $i de la matriz $tableau.
  • línea 14: la función count($tableau) devuelve el número de elementos de la matriz $tableau
  • línea 18: las cadenas de caracteres están entre comillas " o apóstrofos '. Dentro de las comillas, las variables $variable se evalúan, pero no dentro de los apóstrofos.
  • línea 21: la función list permite reunir variables en una lista y asignarles un valor con una sola operación de asignación. Aquí, $chaine1="cadena1" y $chaine2="cadena2".
  • línea 24: el operador . es el operador de concatenación de cadenas.
  • línea 88: la palabra clave function define una función. Una función devuelve o no valores mediante la instrucción return. El código que la invoca puede ignorar o recuperar los resultados de una función. Una función puede definirse en cualquier parte del código.
  • línea 90: la función predefinida getType($variable) devuelve una cadena de caracteres que representa el tipo de $variable. Este tipo puede cambiar con el tiempo.
  • línea 79: la función predefinida exit detiene el script.

3.2. El alcance de las variables

3.2.1. Programa 1 (exemple_02)


<?php

// alcance de las variables

function f1() {
  // se utiliza la variable global $i
  $i = &$GLOBALS["i"];
  $i++;
  $j = 10;
  print "f1[i,j]=[$i,$j]\n";
}

function f2() {
  // se utiliza la variable global $i
  $i = &$GLOBALS["i"];
  $i++;
  $j = 20;
  print "f2[i,j]=[$i,$j]\n";
}

function f3() {
  // se utiliza una variable local $i
  $i = 4;
  $j = 30;
  print "f3[i,j]=[$i,$j]\n";
}

// pruebas
$i = 0;
$j = 0;  // estas dos variables son conocidas por una función f a través de la matriz $GLOBALS
f1();
f2();
f3();
print "test[i,j]=[$i,$j]\n";
?>

Los 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]

Comentarios

  • líneas 29-30: definen dos variables, $i y $j, del programa principal. Estas variables no son conocidas dentro de las funciones. Así, en la línea 9, la variable $j de la función f1 es una variable local de la función f1 y es diferente de la variable $j del programa principal. Una función puede acceder a una variable $variable del programa principal a través de una tabla de variables globales llamada $GLOBALS. En la línea 7, la notación $GLOBALS["i"] hace referencia a la variable global $i del programa principal. Si escribimos
$i=$GLOBALS["i"]

A la variable local $i se le asigna el valor de la variable global $i. Se trata de dos variables diferentes, y modificar la variable local $i no modificará la variable global $i. La notación

$i=&Globals["i"]

hace que la variable local $i tenga la misma dirección de memoria que la variable global $i. Por lo tanto, manipular la variable local $i equivale a manipular la variable global $i.

3.2.2. Programa 2 (exemple_03)


<?php

// el alcance de una variable es global para los bloques de código
$i = 0; {
  $i = 4;
  $i++;
}
print "i=$i\n";
?>

Los resultados:

i=5

Comentarios

En algunos lenguajes, una variable definida dentro de llaves tiene el alcance de estas: no es conocida fuera de ellas. Los resultados anteriores muestran que esto no es así en PHP. La variable $i definida en la línea 5 dentro de las llaves es la misma que la utilizada en las líneas 4 y 8 fuera de ellas.

3.3. Las tablas

3.3.1. Tablas clásicas unidimensionales (exemple_04)


<?php

// matrices clásicas
// inicialización
$tab1 = array(0, 1, 2, 3, 4, 5);

// recorrido - 1
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
  print "tab1[$i]=$tab1[$i]\n";

// recorrido - 2
print "tab1 a " . count($tab1) . " éléments\n";
reset($tab1);
while (list($clé, $valeur) = each($tab1))
  print "tab1[$clé]=$valeur\n";

// agregación de elementos
$tab1[] = $i++;
$tab1[] = $i++;

// recorrido - 3
print "tab1 a " . count($tab1) . " éléments\n";
$i = 0;
foreach ($tab1 as $élément) {
  print "tab1[$i]=$élément\n";
  $i++;
}

// eliminación del último elemento
array_pop($tab1);

// recorrido - 4
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
  print "tab1[$i]=$tab1[$i]\n";

// eliminación del primer elemento
array_shift($tab1);

// recorrido - 5
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
  print "tab1[$i]=$tab1[$i]\n";

// agregar al final de la tabla
array_push($tab1, -2);

// recorrido - 6
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
  print "tab1[$i]=$tab1[$i]\n";

// agregar al inicio de la tabla
array_unshift($tab1, -1);

// recorrido - 7
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
  print "tab1[$i]=$tab1[$i]\n";
?>

Los 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

Comentarios

El programa anterior muestra operaciones de manipulación de una matriz de valores. Existen dos formas de escribir las matrices en PHP:

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

La tabla 1 se denomina «tabla» y la tabla 2, «diccionario», donde los elementos se escriben clave => valor. La notación $contraires["beau"] designa el valor asociado a la clave «guapo». En este caso, es la cadena «feo». La tabla 1 no es más que una variante del diccionario y podría escribirse así:

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

Así, tenemos $tableau[2] = «tres». Al final, solo hay diccionarios. En el caso de una matriz clásica de n elementos, las claves son los números enteros del intervalo [0,n-1].

  • línea 15: la función each($tableau) permite recorrer un diccionario. En cada llamada, devuelve un par (clave, valor) del mismo.
  • línea 14: la función reset($dictionnaire) posiciona la función each en el primer par (clave, valor) del diccionario.
  • línea 15: el bucle while se detiene cuando la función each devuelve un par vacío al llegar al final del diccionario.
  • línea 19: la notación $tableau[]=valor agrega el elemento valeur como último elemento de $tableau.
  • línea 25: se recorre el array con un foreach. Este elemento sintáctico permite recorrer un diccionario, es decir, un array, según dos sintaxis:
foreach($dictionnaire as $clé=>$valeur)
foreach($tableau as $valeur)

La primera sintaxis devuelve un par (clé,valeur) en cada iteración, mientras que la segunda sintaxis solo devuelve el elemento valeur del diccionario.

  • línea 31: la función array_pop($tableau) elimina el último elemento de $tableau
  • línea 39: la función array_shift($tableau) elimina el primer elemento de $tableau
  • línea 47: la función array_push($tableau,valor) agrega valeur como último elemento de $tableau
  • línea 39: la función array_unshift($tableau,valor) agrega valeur como primer elemento de $tableau

3.3.2. El diccionario (exemple_05)


<?php

// diccionarios
$conjoints = array("Pierre" => "Gisèle", "Paul" => "Virginie", "Jacques" => "Lucette", "Jean" => "");

// recorrido - 1
print "Nombre d'éléments du dictionnaire : " . count($conjoints) . "\n";
reset($conjoints);
while (list($clé, $valeur) = each($conjoints))
  print "conjoints[$clé]=$valeur\n";

// ordenación del diccionario por clave
ksort($conjoints);

// recorrido - 2
reset($conjoints);
while (list($clé, $valeur) = each($conjoints))
  print "conjoints[$clé]=$valeur\n";

// lista de claves del diccionario
$clés = array_keys($conjoints);
for ($i = 0; $i < count($clés); $i++)
  print "clés[$i]=$clés[$i]\n";

// lista de valores del diccionario
$valeurs = array_values($conjoints);
for ($i = 0; $i < count($valeurs); $i++)
  print "valeurs[$i]=$valeurs[$i]\n";

// búsqueda de una clave
existe($conjoints, "Jacques");
existe($conjoints, "Lucette");
existe($conjoints, "Jean");

// eliminación de una clave-valor
unset($conjoints["Jean"]);
print "Nombre d'éléments du dictionnaire : " . count($conjoints) . "\n";
foreach ($conjoints as $clé => $valeur) {
  print "conjoints[$clé]=$valeur\n";
}

// fin
exit;

function existe($conjoints, $mari) {
  // verifica si la clave $mari existe en el diccionario $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";
}

?>

Los 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

Comentarios

El código anterior aplica a un diccionario lo que se ha visto anteriormente para una tabla simple. Solo comentaremos las novedades:

  • línea 13: la función ksort (ordenación por clave) permite ordenar un diccionario según el orden natural de las claves.
  • línea 21: la función array_keys($dictionnaire) devuelve la lista de claves del diccionario en forma de tabla
  • línea 26: la función array_values($dictionnaire) devuelve la lista de valores del diccionario en forma de tabla
  • línea 47: la función isset($variable) devuelve «true» si se ha definido la variable $variable; de lo contrario, devuelve «false».
  • línea 36: la función unset($variable) elimina la variable $variable.

3.3.3. Las matrices multidimensionales (exemple_06)


<?php

// tablas multidimensionales clásicas
// inicialización
$multi = array(array(0, 1, 2), array(10, 11, 12, 13), array(20, 21, 22, 23, 24));
// recorrido
for ($i1 = 0; $i1 < count($multi); $i1++)
  for ($i2 = 0; $i2 < count($multi[$i1]); $i2++)
    print "multi[$i1][$i2]=" . $multi[$i1][$i2] . "\n";
// diccionarios multidimensionales
// inicialización
$multi = array("zéro" => array(0, 1, 2), "un" => array(10, 11, 12, 13), "deux" => array(20, 21, 22, 23, 24));
// recorrido
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

Comentarios

  • línea 5: los elementos de la matriz $multi son a su vez matrices
  • línea 12: la matriz $multi se convierte en un diccionario (clé,valeur) donde cada valeur es una matriz

3.3.4. Relaciones entre cadenas y tablas (exemple_07)


<?php

// cadena a matriz
$chaine = "1:2:3:4";
$tab = explode(":", $chaine);

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

// de matriz a cadena
$chaine2 = implode(":", $tab);
print "chaine2=$chaine2\n";

// agregamos un campo vacío
$chaine.=":";
print "chaîne=$chaine\n";
$tab = explode(":", $chaine);

// recorrido por la matriz
print "tab a " . count($tab) . " éléments\n";
for ($i = 0; $i < count($tab); $i++)
  print "tab[$i]=$tab[$i]\n"; // ahora tenemos 5 elementos, siendo el último vacío
  
// agregamos nuevamente un campo vacío
$chaine.=":";
print "chaîne=$chaine\n";
$tab = explode(":", $chaine);

// recorrido por la tabla
print "tab a " . count($tab) . " éléments\n";
for ($i = 0; $i < count($tab); $i++)
  print "tab[$i]=$tab[$i]\n"; // ahora tenemos 6 elementos, siendo los dos últimos vacíos
?>

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]=

Comentarios

  • línea 5: la función explode($séparateur,$chaine) permite recuperar los campos de $chaine separados por $séparateur. Así, explode(":",$chaine) permite recuperar, en forma de matriz, los elementos de $chaine que están separados por la cadena ":".
  • La función implode($séparateur,$tableau) realiza la operación inversa a la función explode. Devuelve una cadena de caracteres formada por los elementos de $tableau separados por $séparateur.

3.4. Las cadenas de caracteres

3.4.1. Notación (exemple_08)


<?php

// notación de cadenas
$chaine1 = "un";
$chaine2 = 'un';
print "[$chaine1,$chaine2]\n";
?>

Resultados:

[un,un]

3.4.2. Comparación (exemple_09)


<?php

// pruebas de comparación de cadenas
compare("abcd", "abcd");
compare("", "");
compare("1", "");
exit;

function compare($chaine1, $chaine2) {
  // compara cadena1 y cadena2
  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. Las expresiones regulares (exemple_10)


<?php

// expresiones regulares en PHP
// extraer los distintos campos de una cadena

// el patrón: una secuencia de números rodeada de caracteres cualquiera
// solo queremos extraer la secuencia de números
$modèle = "/(\d+)/";
// comparamos la cadena con el patrón
compare($modèle, "xyz1234abcd");
compare($modèle, "12 34");
compare($modèle, "abcd");

// el patrón: una secuencia de números rodeada de caracteres cualquiera
// queremos la secuencia de números, así como los campos que la preceden y la siguen
$modèle = "/^(.*?)(\d+)(.*?)$/";
// comparamos la cadena con el patrón
compare($modèle, "xyz1234abcd");
compare($modèle, "12 34");
compare($modèle, "abcd");

// el patrón: una fecha en 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");

// el patrón: un 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");

// fin
exit;

// --------------------------------------------------------------------------
function compare($modèle, $chaîne) {
  // compara la cadena $chaîne con el patrón $modèle
  // se compara la cadena con el patrón
  $correspond = preg_match($modèle, $chaîne, $champs);
  // visualización de 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

Comentarios

  • líneas 3-4: aquí utilizamos expresiones regulares para extraer los distintos campos de una cadena de caracteres. Las expresiones regulares permiten superar las limitaciones de la función implode. El principio consiste en comparar una cadena de caracteres con otra cadena llamada modèle mediante la función preg_match:

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

La función preg_match devuelve un valor booleano si modèle se puede encontrar en chaîne. Si es así, $champs[0] representa la subcadena correspondiente a la plantilla. Por otra parte, si el modelo contiene submodelos entre paréntesis, $champs[1] es la parte de $chaîne que corresponde al primer submodelo, $champs[2] es la parte de $chaîne que corresponde al segundo subpatrón, etc...

Consideremos el primer ejemplo. El patrón se define en la línea 8: designa una secuencia de uno o más (+) dígitos (\d) ubicados en cualquier lugar de una cadena. Además, el patrón define un subpatrón entre paréntesis.

  • Línea 10: el patrón /(\d+)/ (secuencia de uno o más dígitos en cualquier lugar de la cadena) se compara con la cadena «xyz1234abcd». Vemos que la subcadena 1234 coincide con el patrón. Por lo tanto, tendremos que $champs[0] es igual a «1234». Además, el patrón tiene subpatrones entre paréntesis. Tendremos $champs[1] = «1234».
  • línea 11: el patrón /(\d+)/ se compara con la cadena "12 34". Se observa que las subcadenas 12 y 34 coinciden con el patrón. La comparación se detiene en la primera subcadena que coincide con el patrón. Por lo tanto, tendremos: $champs[0]=12 y $champs[1]=12.
  • línea 12: el patrón /(\d+)/ se compara con la cadena «abcd». No se encuentra ninguna coincidencia.

Explicaremos los patrones utilizados en el resto del código:


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

inicio de cadena (^), seguido de 0 o más (*) caracteres cualquiera (.), luego 1 o más (+) dígitos, y nuevamente 0 o más (*) caracteres cualquiera (.). El patrón (.*) representa 0 o más caracteres cualquiera. Un patrón de este tipo coincidirá con cualquier cadena. Por lo tanto, el patrón /^(.*)(\d+)(.*)$/ nunca se encontrará, ya que el primer subpatrón (.*) absorberá toda la cadena. El patrón (.*?)(\d+) designa 0 o más caracteres cualquiera hasta el subpatrón siguiente (?), en este caso \d+. Por lo tanto, los dígitos ya no son absorbidos por el patrón (.*). El patrón anterior, por lo tanto, coincide con [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 paso de los parámetros de las funciones (exemple_11)


<?php

// modo de paso de parámetros

function f(&$i, $j) {
  // $i se obtendrá por referencia
  // $j se obtendrá por valor
  $i++;
  $j++;
  print "f[i,j]=[$i,$j]\n";
}

// ----------------------------------------pruebas
$i = 0;
$j = 0;
// $i y $j pasados por valor
f($i, $j);
print "test[i,j]=[$i,$j]\n";
?>

Resultados:

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

Comentarios

El código anterior muestra los dos modos de pasar parámetros a una función. Veamos el siguiente ejemplo:

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

}

// programa principal
$i=10; $j=20;
f($i,$j);
  • línea 1: define los parámetros formales $a y $b de la función f. Esta función procesa estos dos parámetros formales y devuelve un resultado.
  • línea 7: llamada a la función f con dos parámetros efectivos $i y $j. Las relaciones entre los parámetros formales ($a, $b) y los parámetros efectivos ($i, $j) se definen en la línea 7
  • &$a: el signo & indica que el parámetro formal $a tomará como valor la dirección del parámetro efectivo $i. En otras palabras, $a y $i son dos referencias a la misma ubicación de memoria. Manipular el parámetro formal $a equivale a manipular el parámetro efectivo $i. Esto es lo que muestra la ejecución del código. Este modo de paso es adecuado para parámetros de salida y datos de gran tamaño, como tablas y diccionarios. A este modo de paso se le denomina «paso por referencia».
  • $b: el parámetro formal $b tomará como valor el del parámetro efectivo $j. Se trata de un paso por valor. Los parámetros formales y efectivos son dos variables diferentes. Manipular el parámetro formal $b no tiene ningún impacto en el parámetro efectivo $j. Esto es lo que muestra la ejecución del código. Este modo de paso es adecuado para los parámetros de entrada.
  • Consideremos la función échange, que admite dos parámetros formales: $a y $b. La función intercambia el valor de estos dos parámetros. Así, durante una llamada de intercambio ($i, $j), el código que realiza la llamada espera que se intercambien los valores de los dos parámetros efectivos. Por lo tanto, son parámetros de salida (se modifican). Por lo tanto, se escribirá:
function échange(&$a,&$b){....}

3.7. Resultados devueltos por una función (exemple_12)


<?php

// resultados devueltos por una función
// una función puede devolver varios valores en una 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";

//: una función puede devolver un pseudoobjeto
$res = f2(10);
print "[$res->res1,$res->res2,$res->res3]\n";

// fin
exit;

// función f1
function f1($valeur) {
  // devuelve una matriz ($valeur+1,$aleur+2,$baleur+3)
  return array($valeur + 1, $valeur + 2, $valeur + 3);
}

// función f2
function f2($valeur) {
  // devuelve un pseudoobjeto ($valeur+1,$aleur+2,$baleur+3)
  $res->res1 = $valeur + 1;
  ;
  $res->res2 = $valeur + 2;
  $res->res3 = $valeur + 3;
  // devuelve el objeto
  return $res;
}

?>

Resultados

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

Comentarios

  • El programa anterior muestra que una función PHP puede devolver un conjunto de resultados y no solo uno, en forma de tabla u objeto. El concepto de objeto se explica con más detalle un poco más adelante
  • líneas 19-22: la función f1 devuelve varios valores en forma de matriz
  • líneas 25-33: la función f2 devuelve varios valores en forma de un objeto

3.8. Los archivos de texto (exemple_13)


<?php

// procesamiento secuencial de un archivo de texto
// este es un conjunto de líneas con el formato login:pwd:uid:gid:infos:dir:shell
// cada línea se coloca en un diccionario con el formato login => uid:gid:infos:dir:shell

// Se establece el nombre del archivo
$INFOS = "infos.txt";

// se abre en modo de creación
if (!$fic = fopen($INFOS, "w")) {
  print "Erreur d'ouverture du fichier $INFOS en écriture\n";
  exit;
}

// se genera un contenido arbitrario
for ($i = 0; $i < 100; $i++)
  fputs($fic, "login$i:pwd$i:uid$i:gid$i:infos$i:dir$i:shell$i\n");
// se cierra el archivo
fclose($fic);

// se aprovecha la vulnerabilidad: fgets conserva el marcador de fin de línea
// esto evita que se recupere una cadena vacía al leer una línea en blanco
// se abre en modo de creación
if (!$fic = fopen($INFOS, "r")) {
  print "Erreur d'ouverture du fichier $INFOS en lecture\n";
  exit;
}
while ($ligne = fgets($fic, 1000)) {
  // se elimina el marcador de fin de línea si existe
  $ligne = cutNewLineChar($ligne);
  // se coloca la línea en una matriz
  $infos = explode(":", $ligne);
  // se recupera el nombre de usuario
  $login = array_shift($infos);
  // se omite la contraseña
  array_shift($infos);
  // se crea una entrada en el diccionario
  $dico[$login] = $infos;
}
// se cierra
fclose($fic);

// explotación del diccionario
afficheInfos($dico, "login10");
afficheInfos($dico, "X");

// fin
exit;

// --------------------------------------------------------------------------
function afficheInfos($dico, $clé) {
  // muestra el valor asociado a la clave en el diccionario $dico si existe
  if (isset($dico[$clé])) {
    // El valor existe: ¿es una matriz?
    $valeur = $dico[$clé];
    if (is_array($valeur)) {
      print "[$clé," . join(":", $valeur) . "]\n";
    } else {
      // $valeur no es una matriz
      print "[$clé,$valeur]\n";
    }
  } else {
    // $clé no es una clave del diccionario $dico
    print "la clé [$clé] n'existe pas\n";
  }
}

// --------------------------------------------------------------------------
function cutNewLinechar($ligne) {
  // se elimina el marcador de fin de línea de $ligne si existe
  $L = strlen($ligne);  // longitud de la línea
  while (substr($ligne, $L - 1, 1) == "\n" or substr($ligne, $L - 1, 1) == "\r") {
    $ligne = substr($ligne, 0, $L - 1);
    $L--;
  }
  // fin
  return($ligne);
}

?>

El archivo 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

Los resultados:

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

Comentarios

  • línea 11: fopen(nom_fichier,"w") abre el archivo nom_fichier en modo de escritura (w=write). Si el archivo no existe, se crea. Si existe, se vacía. Si falla la creación, fopen devuelve el valor false. En la instrucción if (!$fic = fopen($INFOS, "w")) {…}, hay dos operaciones sucesivas: 1) $fic = fopen(..) 2) if( ! $fic) {...}
  • línea 18: fputs($fic, $chaîne) escribe chaîne en el archivo $fic.
  • línea 20: fclose($fic) cierra el archivo $fic.
  • línea 25: fopen(nom_fichier,"r") abre el archivo nom_fichier en modo de lectura (r=read). Si la apertura falla (el archivo no existe), fopen devuelve un valor false.
  • línea 29: fgets($fic,1000) lee la siguiente línea del archivo con un límite de 1000 caracteres. En la operación while ($ligne = fgets($fic, 1000)) {…}, hay dos operaciones sucesivas: 1) $ligne = fgets(...) 2) while ( ! $ligne). Una vez que se ha leído el último carácter del archivo, la función fgets devuelve la cadena vacía y el bucle while se detiene.
  • línea 31: la función fgets lee una línea de texto, incluido el carácter de fin de línea. La función cutNewLineChar en las líneas 70-79 elimina cualquier carácter de fin de línea que pueda haber.
  • línea 72: la función strlen($chaîne) devuelve el número de caracteres de $chaîne.
  • línea 73: la función substr($ligne, $position, $taille) devuelve $taille caracteres de $ligne, a partir del carácter n.º $position, siendo el primer carácter el n.º 0. En las máquinas con Windows, el marcador de fin de línea es «\r\n». En las máquinas Unix, es la cadena «\n».
  • línea 35: la función array_shift($tableau) elimina el primer elemento de $tableau y lo devuelve como resultado.
  • línea 37: se utiliza la función array_shift($tableau), pero se ignora su resultado
  • línea 57: la función is_array($variable) devuelve true si $variable es una matriz; de lo contrario, devuelve false.
  • línea 58: la función join hace lo mismo que la función implode que ya hemos visto