Skip to content

3. Los fundamentos de PHP

3.1. Un primer ejemplo

A continuación, se muestra un programa que presenta 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 tipos diferentes
$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 una matriz
list($chaine1, $chaine2) = array("chaine1", "chaine2");

// concatenación de las 2 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 una matriz
$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 las cadenas
  if (getType($t[$i]) == "string")
    print "t[$i]=$t[$i]\n";

// otras pruebas
for ($i = 0; $i < count($t); $i++){
// solo muestra los enteros >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 «nombre»
  • línea 8: para escribir en pantalla, se puede utilizar la instrucción print o la instrucción echo
  • línea 11: la palabra clave array permite definir una matriz. 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 se escriben entre comillas " o entre 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 agrupar variables en una lista y asignarles un valor con una única 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 se puede definir 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 ámbito de las variables

3.2.1. Programa 1 (exemple_02)


<?php

// ámbito 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";
?>

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"] designa 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, por lo que 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. Manipular la variable local $i equivale, por tanto, a manipular la variable global $i.

3.2.2. Programa 2 (exemple_03)


<?php

// El ámbito 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 entre llaves tiene el mismo ámbito que 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";

// adició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";

// añadir 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";

// añadir al principio 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 tabla de valores. Existen dos notaciones para las tablas 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 anotan clave => valor. La notación $contraires["beau"] designa el valor asociado a la clave «guapo». En este caso, se trata de 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) coloca 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 final del diccionario.
  • línea 19: la notación $tableau[]=valor añade el elemento valor como último elemento de $tableau.
  • línea 25: la matriz se recorre con un foreach. Este elemento sintáctico permite recorrer un diccionario, y por tanto una matriz, según dos sintaxis:
foreach($dictionnaire as $clé=>$valeur)
foreach($tableau as $valeur)

La primera sintaxis devuelve un par (clave, valor) en cada iteración, mientras que la segunda sintaxis solo devuelve el elemento «valor» 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) añade valor como último elemento de $tableau
  • línea 39: la función array_unshift($tableau,valor) añade valor 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) {
  // comprueba 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) muestra 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, false en caso contrario.
  • 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 tabla $multi se convierte en un diccionario (clave, valor) donde cada valor es una tabla

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";

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

// añadamos 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
  
// añadamos de nuevo 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 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. Expresiones regulares (exemple_10)


<?php

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

// el patrón: una secuencia de dígitos rodeada de caracteres cualquiera
// solo queremos recuperar la secuencia de dígitos
$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 dígitos rodeada de caracteres arbitrarios
// 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 denominada patrón mediante la función preg_match:

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

La función preg_match devuelve un valor booleano si el patrón se encuentra en la cadena. En caso afirmativo, $champs[0] representa la subcadena correspondiente al patrón. Por otra parte, si el patrón contiene subpatrones entre paréntesis, $champs[1] es el fragmento de $chaîne correspondiente al primer subpatrón, $champs[2] es la parte de $chaîne correspondiente al segundo submodelo, 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) situados 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 se ajusta al patrón. Por lo tanto, tendremos $champs[0] igual a «1234». Por otra parte, 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 (.), seguido de 1 o más (+) dígitos, y de nuevo 0 o más (*) caracteres cualquiera (.). El patrón (.*) designa 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 siguiente subpatrón (?), en este caso \d+. Por lo tanto, los dígitos ya no son absorbidos por el patrón (.*). El patrón anterior se corresponde, por tanto, 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. Tomemos 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 manipula 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. Dicho de otro modo, $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 los parámetros de salida y para datos de gran volumen, 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 ninguna incidencia 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 de intercambio que admite dos parámetros formales $a y $b. La función intercambia el valor de estos dos parámetros. Así, en una llamada de intercambio ($i,$j), el código llamante espera que se intercambien los valores de los dos parámetros efectivos. Por lo tanto, se trata de 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 uno solo, en forma de matriz u objeto. El concepto de objeto se explica con más detalle 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 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 introduce 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: fgets conserva el marcador de fin de línea
// esto permite no recuperar 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 carácter de fin de línea si existe
  $ligne = cutNewLineChar($ligne);
  // se coloca la línea en una tabla
  $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 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 borra su contenido. Si la creación falla, fopen devuelve un valor falso. 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 la cadena 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 lectura (r=read). Si la apertura falla (el archivo no existe), fopen devuelve un valor falso.
  • 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 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 el posible carácter de fin de línea.
  • 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, tomados a partir del carácter n.º $position, siendo el primer carácter el n.º 0. En equipos Windows, el marcador de fin de línea es «\r\n». En equipos 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, false en caso contrario.
  • línea 58: la función join hace lo mismo que la función implode que ya hemos visto