En este curso abordaremos los procedimientos comunes de programación en lenguaje PHP.
Estructura y sintáxis
MARCADORES
<?php ... ?> | Bloque de código PHP. Lo que no esté dentro de estos marcadores se envía directamente a la salida. |
||||||||||||||||||||||||||
// ó # ... | Comentario en una línea. | ||||||||||||||||||||||||||
/* ... */ | Comentario multilínea (no anidable). | ||||||||||||||||||||||||||
' ... ' | Cadena simple. Para incluir el caracter ' (apóstrofe) en una cadena simple hay que ponerle delante una barra invertida (caracter de escape). Para incluir una barra invertida justo delante del apóstrofe final hay que añadirle delante otra barra invertida. |
||||||||||||||||||||||||||
" ... " | Cadena interpretable. En una cadena interpretable las variables invocadas son sustituidas por su dato convertido a tipo cadena. Para incluir el caracter " (comillas) en una cadena interpretable hay que ponerle delante una barra invertida (caracter de escape). Para incluir una barra invertida justo delante del caracter comillas final hay que añadirle delante otra barra invertida. |
||||||||||||||||||||||||||
[ ... ] | Elemento de una matriz. | ||||||||||||||||||||||||||
( ... ) | Delimitadores de expresiones o parámetros. | ||||||||||||||||||||||||||
{ ... } | Bloque de instrucciones, delimitadores de caracter en una cadena, o delimitadores de un nombre de variable en una expresión ambigua. | ||||||||||||||||||||||||||
; | Separador de instrucciones. | ||||||||||||||||||||||||||
, | Separador de expresiones o parámetros. | ||||||||||||||||||||||||||
@ | No enviar a salida un posible mensaje de error. Se pone a la izquierda de la instrucción afectada. |
||||||||||||||||||||||||||
\ | Caracter de escape. Sirve para marcar caracteres que de otra manera podrían confundir al intérprete. Inicia las llamadas secuencias de escape que serán sustituidas por su valor real.
|
TIPOS DE DATO
- Escalares:
Se dice que un tipo es escalar, u ordinal, si existe un orden entre sus valores individuales.
string (cadena, serie de caracteres) integer (número sin decimales) float o double (número con decimales. El separador decimal es el punto, no la coma) boolean (lógico) - Valores posibles: TRUE (verdadero) o FALSE (falso) Cuando un dato se conviente a boolean, será FALSE si:
- es boolean y vale FALSE
- es integer o float y vale 0 ó 0.0 (cero)
- es string y está vacío o vale '0'
- es array y no tiene elementos
- es object y no tiene variables miembro
- es NULL
En cualquier otro caso es TRUE (ojo, esto incluye a los números negativos).
Cuando un boolean se convierte a número, TRUE será 1 y FALSE será 0.
Cuando un boolean se convierte a cadena, True será '1' y FALSE será '' (vacía). - Compuestos:
array (matriz) object (objeto) - Especiales:
resource (recurso) NULL (nulo) - Valor posible: NULL Una variable no definida se considera de tipo NULL. - Pseudo tipos: (no reales, referidos sólo a parámetros de funciones)
mixed (múltiples tipos posibles) number (integer o float) callback (llamada de retorno)
VARIABLES
Creación y uso
Los nombres deben empezar por $ (signo de dolar).
El caracter a continuación debe ser un _ subrayado) o una letra, y
después cualquier combinación de subrayados, letras y números. Las letras
mayúsculas y minúsculas se consideran diferentes.
Además de los caracteres de 'a' a 'z' y de 'A' a 'Z',
para los nombres se consideran letras los caracteres ASCII del 127 al 255.
Hay variables ya creadas por el intérprete que pueden usarse directamente,
las demás se crean al asignarles un dato.
El tipo de una variable es determinado por el contexto.
Al usar una variable no creada se considera de tipo NULL.
Variables como referencia a otras variables
(su uso es poco frecuente)A una variable se le puede asignar la referencia de otra, anteponiendo a ésta un & (ampersand). Ejemplo:
$a = 'coco'; $b = &$a;Con esto, $a y $b apuntan al mismo dato ('coco'), que puede usarse o cambiarse por cualquiera de ellas.
A una variable se le puede dar nombre con el contenido de otra variable de tipo cadena. Ejemplo:
$a = 'hola'; $$a = 'mundo';Con esto se crea una variable $hola que contiene 'mundo'.
También puede referenciarse una variable con su nombre contenido en otra, poniendo ésta entre llaves. Ejemplo:
$hola = 'mundo'; $c = 'hola'; echo ${$c};Con esto se mostrará 'mundo' en el navegador.
MATRICES
Una matriz puede considerarse una variable especial que apunta a una lista de parejas clave/dato.
Se puede crear con:
$matriz = array(lista_de_elementos_separados_por_coma);En la definición de una lista un elemento puede ser solo un dato (al que se le asignará una clave numérica), o una pareja clave/dato en la forma:
clave => dato
La clave puede ser un número entero o una cadena.
El dato puede ser cualquier valor, incluso otra matriz.
Si no se especifica la clave, se le asignará la clave entera mayor que tenga la
matriz + 1.
Si se especifica la clave y ésta ya existe en la matriz, se sustituirá su dato
con el nuevo.
$matriz[clave]Si el dato es otra matriz, sus elementos se referencian como:
$matriz[clave][clave2]y así sucesivamente.
CONSTANTES
Las constantes referencian a datos que una vez definidos no se pueden cambiar.
Las reglas de formación de nombres de constantes son las mismas que las de nombres de variables excepto que los nombres de las constantes NO empiezan con $, y por convención se escriben en mayúsculas.
Hay constantes ya predefinidas que pueden usarse directamente, las demás se crean con la función:define(nombre, dato, sensibilidad);
El nombre tiene que ser de tipo cadena y el dato tiene que ser de tipo escalar.
Sensibilidad se refiere a si el nombre de la constante será sensible o no a mayúsculas/minúsculas. Si es TRUE la constante podrá usarse con las letras de su nombre en mayúsculas o minúsculas indistintamente, si es FALSE tendrá que usarse con el nombre tal como se haya definido. Este parámetro puede omitirse (no es frecuente ponerlo) y por defecto asume FALSE.
Las constantes pueden ser definidas y accedidas en cualquier ámbito.
EXPRESIONES
Una expresión es cualquier construcción que de como resultado un dato.
PHP es un lenguaje orientado a expresiones, por lo que casi todo son expresiones.
Expresiones son un dato explícito, un nombre de variable, una función, y combinaciones de éstos con operadores.
OPERADORES
Un operador realiza una acción sobre el dato o datos (operando/s) a los que
se asocia, y esta acción produce un dato como resultado.
El conjunto de operandos y operadores es una expresión, y a su vez los operandos
pueden ser el resultado de otras expresiones.
- Operador de asignación:
= Asigna a la variable de la izquierda el operando de la derecha.
- Operadores de cadena:
. Une el operando de la derecha al de la izquierda, sin modificarlos. .= Une el operando de la derecha a la cadena contenida en la variable de la izquierda y asigna el resultado a la variable de la izquierda.
- Operadores aritméticos:
+ Suma el operando de la derecha. - Resta el operando de la derecha.
Unario: Si a la izquierda no tiene otro operando, el resultado es el operando de la derecha con el signo cambiado (como multiplicado por -1, o como si el operando de la izquierda que falta tuviera valor cero).* Multiplica por el operando de la derecha. / Divide entre el operando de la derecha. % Obtiene el resto (módulo) de dividir entre el operando de la derecha. +=
-=
*=
/=
%=Hace la operación correspondiente con el operando de la derecha a la variable de la izquierda y asigna el resultado a la variable de la izquierda. ++ Suma 1 al valor de la variable a la que se une.
si este operador va a la izquierda, la suma se produce antes de evaluar el dato; si va a la derecha, la suma se produce después de evaluar el dato.-- Resta 1 al valor de la variable a la que se une.
Las reglas son las mismas que las de ++, pero restando en vez de sumando. - Operadores lógicos:
(TRUE: verdadero, FALSE: falso, OR: o, AND: y, XOR: o exclusivo, NOT (!): no)== TRUE si los operandos a izquierda y derecha son iguales,
FALSE si son diferentes.=== TRUE si son iguales y del mismo tipo,
FALSE si son diferentes o de distinto tipo.!= TRUE si los operandos a izquierda y derecha son diferentes,
FALSE si son iguales.!== TRUE si son diferentes o de distinto tipo,
FALSE sin son iguales y del mismo tipo.< TRUE si el operando de la izquierda es menor que el de la derecha,
FALSE si es igual o mayor.<= TRUE si menor o igual,
FALSE si es mayor.> TRUE si el operando de la izquierda es mayor que el de la derecha,
FALSE si es igual o menor.>= TRUE si es mayor o igual,
FALSE si es menor.|| ó OR TRUE si el operando de la izquierda O de la derecha es TRUE,
FALSE sin el resultado de ambos es FALSE.&& ó AND TRUE si el operando de la izquierda Y de la derecha son TRUE,
FALSE si cualquiera de ellos es FALSE.XOR TRUE si el operando de la izquierda O de la derecha es TRUE,
FALSE si ambos son TRUE o ambos son FALSE.! TRUE si el operando de la derecha es FALSE,
FALSE si el operando de la derecha es TRUE. - Operador ternario:
expr1 ? expr2 : expr3 Se evalúa la expresión 1; si su resultado es TRUE, el resultado final es el de la expresión 2; si es FALSE, el resultado final es el de la expresión 3. - Operadores de matrices:
+ El resultado es la matriz de la izquierda a la que se añaden los elementos de la matriz de la derecha, excepto los elementos con la misma clave en la matriz de la izquierda. No modifica las matrices originales. == TRUE si las matrices tienen las mismas parejas clave/dato. === TRUE si las matrices son idénticas, es decir que tienen las mismas parejas clave/dato, en el mismo orden y con los mismos tipos de dato. != ó <> TRUE si las matrices no tienen las mismas parejas clave/dato. !== TRUE si las matrices no son idénticas. En todos los casos, FALSE si la condición no se cumple. - Operadores de manejo de bits:
Los operadores de bit activan o desactivan bits individuales de un entero.
Si las expresiones a la izquierda y a la derecha son cadenas, el operador de bit actuará sobre los valores ASCII de los caracteres.| (or) En el resultado estarán activos los bits que en uno de los operandos estén activos, e inactivos los que en ambos operandos estén inactivos. & (and) En el resultado estarán activos los bits que en ambos operandos estén activos, e inactivos los que en uno de los operandos estén inactivos. ^ (xor) En el resultado estarán activos los bits que estén activos en uno de los operandos pero no en el otro, e inactivos los que en ambos operandos estén activos o en ambos estén inactivos. ~ (not) En el resultado estarán activos los que en el operando de la derecha estén inactivos, e inactivos los que en ese operando estén activos. << En el resultado los bits del operando de la izquierda estarán desplazados hacia la izquierda tantos pasos como indique el operando de la derecha. >> En el resultado los bits del operando de la izquierda estarán desplazados hacia la derecha tantos pasos como indique el operando de la derecha. |=
&=
^=
~=
<<=
>>=Hace la operación correspondiente con el operando de la derecha a la variable de la izquierda y asigna el resultado a la variable de la izquierda. - Operadores de forzado de tipos:
El tipo de dato del resultado de una expresión dependerá de los tipos de los operadores y de la operación que se realize, pero puede haber casos en los que interese que el resultado sea de un tipo concreto y eso puede conseguirse usando estos operadores.
(string) El operando de la derecha se convertirá a tipo string (cadena). (int) El operando de la derecha se convertirá a tipo integer (número sin decimales). (float) El operando de la derecha se convertirá a tipo float (número con decimales). (array) El operando de la derecha se convertirá a tipo array (matriz). (object) El operando de la derecha se convertirá a tipo object (objeto).
Precedencia de operadores
En una expresión los operadores actúan en un orden determinado, salvo que se indique su prioridad por medio de paréntesis, de manera que primero se harán las operaciones contenidas en los paréntesis de dentro afuera, y en cada nivel de paréntesis según la precedencia establecida para cada operador. Cuando los operadores tienen la misma precedencia, actúan en orden de izquierda a derecha.
También pueden usarse los paréntesis para aumentar la legibilidad del código.
Esta es la lista de mayor a menor precedencia, teniendo la misma los de cada línea:
-
++ --
! ~
- (unario)
(int) (float) (string) (array) (object)
* / %
+ - .
<< >> < <= > >=
== != === !==
&
^
|
&&
||
? : (ternario)
= .= += -= *= /= %= &= |= ^= ~= <<= >>=
AND
XOR
OR
Hay que observar que && y || tienen mayor precedencia que AND y OR.
INSTRUCCIONES
Las instrucciones son los diferentes pasos que tiene que ir ejecutando el programa.
Muchas expresiones pueden considerarse instrucciones, pero no todas: para que
una expresión sea una instrucción su resultado tiene que haber quedado
almacenado de manera que pueda ser utilizado por instrucciones posteriores.
Por el contrario, las instrucciones puras no pueden considerarse expresiones,
pues no producen un resultado en forma de dato que pueda usarse después en el
mismo programa, por ejemplo pueden estar enviando información dirigida al
usuario o controlando el flujo de instrucciones que se van ejecutando.
Las instrucciones se separan con ; (punto y coma) y pueden agruparse
una o varias (o ninguna) encerrándolas entre llaves { }.
Un bloque de instrucciones así agrupadas también se considera una instrucción,
es decir, donde pueda ir una instrucción también podrá ir un bloque de
instrucciones entre llaves. Y también podría no ir ninguna.
Instrucciones generales
echo expr1, expr2 ... ;
Envía el resultado de las expresiones indicadas a la salida estándar.
El resultado de las expresiones se convierte a tipo cadena.
Aunque pueden ir varias expresiones separadas por comas, el resultado es el
mismo que si se concatenan usando el . (punto, operador de unión de
cadenas).
Cuando sólo va una expresión pueden usarse paréntesis como si echo() fuera una
función, pero no lo es, por tanto echo() no puede usarse en una expresión.
Si fuera necesario habría que usar la función print(expr) en su lugar.
echo <<<FIN
varias líneas
de texto
FIN;
De esta manera pueden enviarse a la salida varias líneas de texto. El
delimitador (En este caso FIN) debe estar solo en la última línea con el
; y ningún otro caracter, ni siquiera espacio/s en blanco.
Las líneas de texto se tratarán como una cadena interpretable, con la excepción
de que ni las comillas ni los apóstrofes tienen que llevar caracter de escape.
array ( lista_de_elementos_separados_por_coma );
Crea una matriz. La lista de elementos puede estar vacía.
unset ( lista_de_variables_separadas_por_coma );
Destruye las variables especificadas en la lista.
Si en vez de una variable se indica un elemento de una matriz, sólo elimina ese
elemento, no destruye toda la matriz.
include ( 'nombrefichero' );
require ( 'nombrefichero' );
Incluyen y evalúan el fichero especificado.
El fichero incluido hereda el ámbito de variables del sitio en el que se
incluyó.
El fichero incluido debe tener marcados sus propios bloques de código PHP, lo
que no esté dentro de los bloques marcados se envia directamente a la salida.
Se diferencian en que, si fallan, include da un aviso y continúa, y
require da un error fatal y termina la ejecución.
include_once ( 'nombrefichero' );
require_once ( 'nombrefichero' );
Se comportan como include y require excepto que el fichero especificado sólo se incluye y evalúa una vez, es decir que otro include_once o require_once del mismo fichero será omitido.
exit ( mensaje ); ó
exit ( número );
die ( mensaje ); ó
die ( número );
Se termina la ejecución del programa, enviando previamente el mensaje a la salida si la expresión es una cadena, o poniendo el valor como estatus de terminación si es un número entero entre 0 y 254. Si se omite la expresión se considera 0 (terminación correcta).
Instrucciones de control de ejecución
- Ejecución condicionada o alternativa:
if ( expr ) instrucción
Si el resultado de la expresión es TRUE se ejecutará la instrucción, si es FALSE no se ejecutará.
La instrucción condicionada puede ser también otro if, y así sucesivamente.else instrucción
La instrucción else es una extensión de la instrucción if, de manera que siempre tiene que ir tras una if.
Si el resultado de la expresión del if es FALSE se ejecutará la instrucción del else, si es TRUE no se ejecutará.
La instrucción condicionada del else puede ser otro if, y así sucesivamente.elseif ( expr ) instrucción
Es una combinación de else e if. De hecho funciona igual que si else e if estuvieran separados.
if ( expr ) : instrucción elseif ( expr ) : instrucción else : instrucción endif;
Esta es una manera alternativa (y poco usada) de escribir una instrucción if.
elseif(): y else: son opcionales.
De esta forma si la instrucción condicionada es un bloque no tiene que ir entre llaves.switch ( expr1 )
{
case expr2 : instrucción
case expr3 : instrucción
...
default : instrucción
}La expresión de switch se evalúa una vez;
Luego se van evaluando secuencialmente las expresiones de los case y cuando el resultado de una de ellas es igual que el de la de switch se ejecuta la instrucción asociada. Si ésta es un bloque de instrucciones no tiene que ir entre llaves.
Cuando se ha ejecutado la instrucción del case y no se quiere que se continúen evaluando los cases siguientes (es decir, que finalice el switch) hay que añadir una instrucción break o continue (ver más adelante estas instrucciones en Instrucciones de control de bucles, considerando que, aunque no lo sea, break o continue actuarán como si switch fuese una instrucción de bucle).
default: es opcional.
Si se alcanza el default, ya sea porque las expresiones de los case no han resultado iguales que la de switch o porque no se ha finalizado con break o continue, se ejecuta la instrucción asociada a default.switch ( expr1 ) :
case expr2 : instrucción
case expr3 : instrucción
...
default : instrucción
endswitch;Esta es una manera alternativa (y poco usada) de escribir una instrucción switch.
De esta forma los case / default no tienen que ir entre llaves. - Ejecución en bucle repetitivo:
while ( expr ) instrucción
Si el resultado de la expresión es TRUE se ejecuta la instrucción y se vuelve a evaluar la expresión, si de nuevo es TRUE vuelve a ejecutarse la instrucción y la evaluación, y así sucesivamente hasta que el resultado de la expresión sea FALSE. Si el resultado de la expresión la primera vez es FALSE no se ejecuta la instrucción.
while ( expr ) : instrucción endwhile;
Manera alternativa (y poco usada) de escribir una instrucción while.
De esta forma si la instrucción condicionada es un bloque no tiene que ir entre llaves.do instrucción while ( expr );
Funciona igual que while ( expr ) instrucción, excepto que la instrucción se ejecuta siempre una vez antes de evaluar la expresión.
for ( expr1 ; expr2 ; expr3 ) instrucción
La primera expresión se evalúa sólo la primera vez;
La segunda expresión se evalúa y si es TRUE se ejecuta la instrucción, se evalúa la tercera expresión y otra vez la segunda expresión, y si es TRUE vuelve a ejecutarse la instrucción y la evaluación de la tercera y de la segunda expresión, y así sucesivamente hasta que el resultado de la segunda expresión sea FALSE.
Si el resultado de la segunda expresión la primera vez es FALSE, no se ejecuta la instrucción y finaliza el bucle.
Cualquiera de las tres expresiones puede estar vacía (o las tres). Si falta la segunda se considera TRUE.for ( expr1 ; expr2 ; expr3 ) : instrucción endfor;
Manera alternativa (y poco usada) de escribir una instrucción for.
De esta forma si la instrucción condicionada es un bloque no tiene que ir entre llaves.foreach ( $matriz as $valor ) instrucción
Se usa para recorrer una matriz desde su primer elemento, o no hace nada si la matriz está vacía.
En cada iteración el valor del elemento se asigna a $valor, se ejecuta la instrucción y el puntero interno de la matriz se avanza al elemento siguiente, o finaliza el bucle si no hay más elementos.
Esta instrucción es equivalente a:while (list(, $valor) = each($matriz)) instrucción
foreach ( $matriz as $clave => $valor ) instrucción
Igual que el anterior foreach, excepto que además del valor del elemento
se asigna su clave a $clave en cada iteración.
Esta instrucción es equivalente a:
while (list($clave, $valor) = each($matriz)) instrucción
break número ;
Hace que finalice el bucle en el que se encuentra o los bucles anidados que se indiquen en el número, que es opcional y si se omite se considera 1.
continue número ;
Hace que se salten el resto de instrucciones y siga la ejecución al comienzo de la siguiente iteración del bucle, o de los bucles anidados que se indiquen en el número, que es opcional y si se omite se considera 1.
FUNCIONES
Una función es un bloque de instrucciones que se define con un nombre y se ejecuta al ser invocada por su nombre. La función puede devolver un dato como resultado, por lo que una función invocada puede considerarse, o formar parte como un operando de, una expresión.
PHP ya incorpora muchas funciones, la mayoría preparadas para su uso, y otras en extensiones que es necesario activar en la configuración para que se puedan usar.
Definición general de función
function nombre_funcion (
lista_de_parámetros_separados_por_coma )
{
global
lista_de_variables_globales_separadas_por_coma ;
static $variable ;
otras instrucciones
return dato_de_retorno ;
}
Los parámetros son nombres de variables que serán usadas por las
instrucciones de la función. No tienen nada que ver con otras posibles variables
creadas con el mismo nombre fuera de la función (ver Ámbito de las variables).
A las variables parámetro se les asignan los datos por su orden en la lista de
izquierda a derecha, y se les puede asignar un valor explícito por defecto por
si se omiten al invocar la función.
La lista de parámetros puede estar vacía, pero no pueden omitirse los paréntesis.
Las instrucciones declarativas global y static son opcionales, sólo se ponen cuando es necesario.
La función puede opcionalmente devolver un dato como resultado, por medio de la instrucción return.
Invocación de función
nombre_funcion (
lista_de_expresiones_separadas_por_coma );
ó
$retorno = nombre_funcion (
lista_de_expresiones_separadas_por_coma );
La lista de expresiones debe ir en el mismo orden que la lista de parámetros. Si se omite alguna debe mantenerse la coma de separación, excepto si son las últimas de la derecha.
La lista de expresiones puede estar vacía, pero no pueden omitirse los paréntesis.
Ámbito de las variables
Dentro de una función las variables tienen su propio espacio, de manera que si se referencia una variable creada fuera de ella saldrá un aviso de que la variable no existe; asimismo pueden crearse y referenciarse dentro de la función variables con el mismo nombre que otras ya existentes fuera de la función, pero éstas desaparecerán cuando la función termine, y las variables fuera de la función seguirán como estaban.
Las variables creadas fuera de cualquier función se denominan GLOBALES.
Las variables creadas dentro de una función (incluidos sus parámetros) se denominan LOCALES. Las variables locales desaparecen cuando termina la función.
Para poder usar variables globales dentro de una función se tienen que declarar como tales por medio de la instrucción:
global lista_de_variables_globales_separadas_por_coma;o referenciándolas directamente como:
$GLOBALS['nombre_variable'] (ojo: nombre_variable sin $ inicial)
$GLOBALS es una variable de tipo matriz que además de ser global no se tiene que declarar como tal y puede ser accedida desde cualquier ámbito. A estas variables especiales creadas por el propio intérprete se las denomina SUPERGLOBALES.
Si se necesita que variables creadas dentro de una función no desaparezcan cuando termine la función (es decir, que permanezcan con su valor cuando vuelva a invocarse la función), hay que declararlas como ESTÁTICAS por medio de la instrucción:
static $variable;
Las variables estáticas, como las locales, solo se reconocen dentro del ámbito de la función.
Referencias a variables
(su uso es poco frecuente)Cuando se invoca una función, a cada uno de sus parámetros se les asigna por valor el dato correspondiente de la lista, pero puede indicarse en la definición de la función que se asignen referencias a variables en lugar de su valor poniendo un & (ampersand) a la izquierda de los parámetros. Ejemplo:
function ejemplo ($parm1, &$parm2) { $parm2 = $parm1; } $var1 = 'hola'; ejemplo ('adios', $var1); echo $var1;
Tras la ejecución de este fragmento de código, $var1 contendrá 'adios', y se
enviará ese dato a la salida. Observemos que como el segundo parámetro se ha
definido como referencia a una variable, en la invocación de la función el
segundo dato de la lista tiene que ser una variable y no cualquier otra
expresión. (Ver Referencias a variables).
Otra a cosa a considerar es que $var1 podría no ser una variable global pues la
función ejemplo() podría ser invocada desde dentro de otra función.
Una función también puede devolver una referencia a una variable, poniendo un & (ampersand) a la izquierda del nombre de la función al definirla y también al invocarla. Ejemplo:
$var1 = 1; $var2 = 2; function &ejemplo () { global $var1, $var2; if ($var1 < $var2) return $var1; return $var2; } $var3 = &ejemplo (); $var3 = 'pepe'; echo $var1 . ' ' . $var2;
Tras la ejecución de este fragmento de código, $var3 referenciará a $var2 o a
$var1 si el dato de ésta es menor que el de $var2.
Como el dato de $var1 es menor, se mostrará 'pepe 2'.