miércoles, 19 de diciembre de 2012

Generar imágenes al vuelo con PHP

En esta ocasión vamos a ver un ejemplo muy simple para la generación de una imagen con formato PNG mediante algunas de las funciones que ofrece la biblioteca GD2.

Hemos utilizado imagepng() para generar al vuelo el archivo png, es decir, enviamos directamente la imagen al navegador, pero podríamos haber guardado la imagen en el disco simplemente añadiendo un segundo parámetro con su nombre.

//definimos el ancho y alto
$width = 200;
$height = 200;

//Creamos un lienzo sobre el que trabajar
$img = imagecreatetruecolor($width, $height) or die('No se pudo iniciar el flujo de la imagen');

//colores
$blanco = imagecolorallocate($img, 255, 255, 255);
$otro = imagecolorallocate($img, 130, 205, 242);
$azul = imagecolorallocate($img, 0, 0, 64);

//dibujar la imagen
imagefill($img, 0, 0, $azul);
imageline($img, 0, 0, $width, $height, $blanco);
imagefilledrectangle($img, 0, 0, 100, 100, $otro);
imagestring($img, 4, 40, 145, 'Un texto', $blanco);
imagestring($img, 4, 110, 50,  'Otro Texto', $blanco);

//ofrecer el resultado
header('Content-type: image/png');
imagepng($img);

//liberar recursos
imagedestroy($img);

Ahora vamos a escribir un texto centrado sobre una imagen jpg ya existente, para ello necesitamos obtener las dimensiones de la imagen y también del texto para poder ubicarlo correctamente.

$texto = 'un texto centrado';
$tamano_texto = 20;
$fuente = $_SERVER['DOCUMENT_ROOT'] . '/site/arial.ttf';

$img = imagecreatefromjpeg('iron-maiden.jpg');
$ancho = imagesx($img);
$alto = imagesy($img);

$caja_texto = imagettfbbox($tamano_texto, 0, $fuente, $texto);

$ancho_texto = $caja_texto[2] - $caja_texto[0];
$alto_texto = abs($caja_texto[7] - $caja_texto[1]);

$posicion_texto_x = ($ancho/2.0) - ($ancho_texto/2.0);
$posicion_texto_y = ($alto/2.0) - ($alto_texto/2.0);

$blanco = imagecolorallocate($img, 255, 255, 255);

imagettftext($img, $tamano_texto, 0, $posicion_texto_x, $posicion_texto_y, $blanco, $fuente, $texto);

header('Content-type: image/jpeg');
imagejpeg($img);

imagedestroy($img);
martes, 18 de diciembre de 2012

Conectar a un FTP con PHP para cargar, descargar y eliminar archivos

Contactarse a un servidor FTP y realizar todo tipo de acciones sobre los archivos alojados remotamente es posible gracias a las funciones específicas del leguaje PHP para trabajar con este protocolo. A excepción del comando mget (varios get) prácticamente todo lo que se puede hacer desde una línea de comandos FTP se puede llevar a cabo de una forma muy sencilla, subir y bajar archivos, eliminarlos, listar directorios, etc.

Vamos a ver un pequeño ejemplo en el que realizaremos algunas de las operaciones típicas. Para ello primero establecemos una conexión con el servidor FTP remoto, a continuación iniciamos sesión indicando nuestras credenciales de acceso para poder, primero descargar un archivo remoto, después subir un archivo al servidor, eliminarlo y finalmente listar los archivos ubicados en el directorio raíz del FTP.

$host = 'ftp.servidor-remoto.com';
$user = 'mi_usuario';
$pass = 'mi_contrasena';
$remote_file = 'copia_remota.txt';
$local_file = $_SERVER['DOCUMENT_ROOT'] . '/sitio/copia_local.txt';

//conectarse al host
$conn = @ftp_connect($host);

//Comprobar que la conexión ha tenido éxito
if (!$conn) {
echo 'Error al tratar de conectar con ' . $host . "\n";
exit();
}
echo 'Conectado con ' . $host . "\n";

//Iniciamos sesión
$login = @ftp_login($conn, $user, $pass);
if (!$login) {
echo 'Error al intentar acceder con el usuario ' . $user;
ftp_quit($conn);
exit();
}
echo 'Conectado con el usuario ' . $user . "\n";

//obtenemos el archivo del servidor
if (ftp_get($conn, $local_file, $remote_file, FTP_BINARY)) {
echo 'El archivo ' . $local_file . ' se ha guardado.' . "\n";
} else {
echo 'El archivo ' . $local_file . ' NO se ha guardado.' . "\n";
}

//subimos un archivo al servidor remoto
$remote_file = 'copia_remota.txt';
$local_file = $_SERVER['DOCUMENT_ROOT'] . '/sitio/copia_local.txt';;

if (ftp_put($conn, $remote_file, $local_file, FTP_BINARY)) {
echo 'El archivo ' . $local_file . ' se ha cargado en el servidor remoto.' . "\n";
} else {
echo 'El archivo ' . $local_file . ' NO se ha cargado en el servidor remoto.' . "\n";
}

//borramos el archivo del servidor
if (ftp_delete($conn, $remote_file)) {
echo 'El archivo ' . $remote_file . ' ha sido borrado del servidor.' . "\n";
}

//obtenemos una lista con los archivos del servidor
$files = ftp_nlist($conn, '.');
foreach ($files as $file) {
echo $file . "\n";
}

//Cerramos la conexion
ftp_close($conn);
viernes, 14 de diciembre de 2012

Subir archivos al servidor con PHP

El upload o subida de archivos al servidor mediante PHP es una tarea muy sencilla. Únicamente necesitamos un formulario HTML y manejar la matriz superglobal $_FILES. El formulario, que debe ser enviado utilizando el método POST, necesitará una entrada de carga de archivos de type file (type="file") con el que seleccionaremos el archivo a subir y un atributo para el tag form que indique al servidor que se va a adjuntar un archivo junto con el resto de información (enctype="multipart/form-data").

<form name="frm_upload" action="upload.php"
method="post" enctype="multipart/form-data">
<input type="file" name="archivo" />
</form>

Para procesar el archivo en el lado del servidor utilizaremos los siguientes elementos de la matriz $_FILES. Esta matriz toma el valor del atributo name del campo de tipo file como índice de su primera dimensión y almacena toda la información proporcionada por el archivo.

$_FILES['archivo']['tmp_name'] es la ruta temporal donde se ha guardado el archivo.
$_FILES['archivo']['name'] el nombre real del archivo en origen.
$_FILES['archivo']['size'] el tamaño del archivo en bytes.
$_FILES['archivo']['type'] tipo MIME del archivo subido al servidor.
$_FILES['archivo']['error'] código de error.

En el siguiente ejemplo cargamos un archivo en el servidor y si la operación tiene éxito informamos algunos detalles sobre el archivo subido.

//ruta donde colocaremos el archivo
$archivo = $_SERVER['DOCUMENT_ROOT'] . '/libro/18/uploads/' .
$_FILES['userfile']['name'];
//archivo temporal cargado en el servidor
$archivo_tmp = $_FILES['userfile']['tmp_name'];
$archivo_size = $_FILES['userfile']['size'];
$archivo_type = $_FILES['userfile']['type'];

if (is_uploaded_file($_FILES['userfile']['tmp_name'])) {
 if (!move_uploaded_file($archivo_tmp, $archivo)) {
  echo 'El archivo no ha podido ser ubicado en el directorio de destino.';
 } else {
  echo 'Archivo guardado correctamente.<br />';
  echo 'Ruta completa: ' . $archivo . '<br />';
  echo 'Tamaño archivo: ' . round($archivo_size / 1024, 2) . 'KB. <br />';
  echo 'Tipo: ' . $archivo_type . '<br />';
 }
}
domingo, 2 de diciembre de 2012

Importar/exportar datos en MySql con LOAD DATA INFILE desde y hacia un fichero externo

La instrucción de MySql LOAD DATA INFILE nos permite cargar datos desde un archivo externo, básicamente se trata de leer el contenido de un fichero y volcarlo en una tabla. El comando en cuestión tiene la siguiente sintaxis básica:

LOAD DATA INFILE 'c:/archivo_datos.txt' INTO TABLE nombre_tabla;

Las opciones de las que dispone esta instrucción son numerosas y permiten adaptar el tipo de volcado a nuestras necesidades concretas. Veamos un ejemplo:

LOAD DATA INFILE 'c:/archivo_datos.txt'
INTO TABLE nombre_tabla
FIELDS TERMINATED BY ';'
ENCLOSED BY '\"'
ESCAPED BY '\\'
LINES TERMINATED BY '\r\n'

En este caso le estamos indicando al motor de base de datos que cargue el archivo considerando que cada campo está separado por el carácter de punto y coma, también que todos los valores le llegaran entrecomillados con comillas dobles (si usamos el modificador OPTIONALLY sólo se entrecomillarán las columnas de texto y fecha), el carácter de escape es la barra invertida y cada salto de línea se indica con \r\n (Importante: Si se ha generado el fichero de texto en un sistema Windows , se tiene que usar LINES TERMINATED BY '\r\n' para leer correctamente el fichero, ya que los programas de Windows típicamente usan dos caracteres como terminadores de línea, de lo contrario bastará el signo de nueva línea '\n').

Otra cuestión a considerar y que puede llegar a producir un verdadero dolor de cabeza es el "conjunto de caracteres" y "collation" de la tabla. Aunque nuestra tabla sea utf-8 (CHARACTER SET utf8, COLLATION utf8_general_ci) los acentos y las eñes no se importarán correctamente. Para solucionar este problema debemos indicar CHARACTER SET UTF8 después del nombre de la tabla, y emplear LOCAL como parte del comando si estamos cargando datos desde nuestro propio ordenador.

LOAD DATA LOCAL INFILE 'c:/archivo_datos.txt'
INTO TABLE nombre_tabla CHARACTER SET UTF8
FIELDS TERMINATED BY ';'
OPTIONALLY ENCLOSED BY '\"'
ESCAPED BY '\\'
LINES TERMINATED BY '\r\n'

Del mismo modo podemos realizar la operación contraria, es decir, generar un archivo de texto plano con los datos de una tabla dada. Veamos un ejemplo:

SELECT * FROM nombre_tabla
INTO OUTFILE 'c:/archivo_datos.txt'
FIELDS TERMINATED BY ';'
OPTIONALLY ENCLOSED BY '\"'
LINES TERMINATED BY '\r\n';

De esta manera obtenemos un archivo llamado "archivo_datos.txt" con un registro por línea, cuyos valores de columna se encuentran separados por un punto y coma y los campos con valores de texto y fechas se entrecomillarán.

miércoles, 28 de noviembre de 2012

Copia de seguridad de MySql con mysqldump

Una forma bastante fácil y práctica para realizar un backup de nuestras bases de datos en Mysql es mediante el comando mysqldump que se utiliza de la siguiente forma:

mysqldump --opt --all-databases > archivo_de_copia.sql

Encontraremos mysqldump en el directorio bin de nuestra instalación de MySql. Podemos ejecutarlo desde la consola y establecer una serie de parámetros para adaptar el volcado según nuestras necesidades. En la página oficial de MySql encontramos todos estos parámetros y sus diferentes usos.

Vamos a ver como haríamos una copia de seguridad básica que incluye todas las tablas y los datos de una base de datos concreta:

mysqldump -u[usuario] -p[contraseña] base_de_datos > ruta_archivo_de_copia.sql

Para más información sobre copias de seguridad en MySql consultar:
http://dev.mysql.com/doc/refman/5.0/es/backup.html
http://dev.mysql.com/doc/refman/5.0/es/mysqldump.html

martes, 7 de diciembre de 2010

Funciones útiles para el manejo de archivos con PHP

Estas son sólo algunas de las funciones para el manejo de archivos nativas en PHP.

file_exists() Comprueba la existencia de un archivo.

$path = $_SERVER['DOCUMENT_ROOT'] . '/directorio/archivo.txt';
if (file_exists($path) {
  //si el archivo existe lo abrimos y lo leemos
  $fp = fopen($path, 'rb');
  while (!feof($fp)) {
    $linea = fgets($fp);
    echo $linea . '<br />'
  }
}

filesize() determina el tamaño en bytes de un archivo.

filesize($_SERVER['DOCUMENT_ROOT'] . '/directorio/archivo.txt');

En PHP no existe una función "delete" para la eliminación física de archivos en el servidor. Para realizar esa tarea el lenguaje pone a nuestra disposición unlink()

unlink($_SERVER['DOCUMENT_ROOT'] . '/directorio/archivo.txt');
domingo, 5 de septiembre de 2010

Gestión de parámetros en funciones con PHP

La mejor forma de separar y organizar nuestro código es mediante el uso de funciones. PHP permite la definición de funciones con o sin parámetros, estos pueden ser opcionales o como veremos a continuación pasarlos a la función sin previamente haber sido definidos.

//definimos una funcion
//en principio no espera parametros
function no_params() {
  echo "Número de parámetros pasados a la función: ";
  echo func_num_args();
  echo "<br />";
  //obtenemos un array con todos
  //los parámtros pasados
  $args = func_get_args();
  foreach ($args as $arg) {
    echo $arg."<br />";
  }
}
//pero al llamarla le pasamos una
//lista de parámetros
no_params("param1", "param2", 12);
//con lo que obtenemos en pantalla
param1
param2
12

Expresiones regulares con PHP

Recordamos algunas reglas básicas para el uso y manejo de expresiones regulares en PHP.

Carácter Significado
\ Carácter de escape
^ Coincidencia al principio
$ Coincidencia al final
. Coincidencia con cualquier carácter excepto nueva línea \n
| Opción alternativa OR
( Inicio subpatrón
) Final subpatrón
* Se repite 0 o más veces
+ Se repite 1 o más veces
{ Inicio cuantificador min/max
} Final cuantificador min/max
? Subpatrón opcional
Carácteres especiales utilizados detro de corchetes
\ Carácter de escape
^ No, utilizado en una posición inicial
- Indica rangos de carácter

Veamos algunos ejemplos prácticos del uso de esta sintaxis con la ayuda de algunas funciones de PHP para buscar o reemplazar cadenas.

Podemos comprobar la existencia de subcadenas que coincidan con el patrón de la expresión regular con las funciones ereg() y eregi(). La única diferencia entre ellas es que eregi() es "case insensitive", es decir no diferencia entre mayúsculas y minúsculas, mientras que ereg() sí.

$cadena = "http://www.google.com";
ereg('^(http|https):\/\/', $cadena);
//devuelve true ya que la cadena
//empieza por http://

ereg_replace('^(http|https):\/\/', 'https://', $cadena);
//sustituimos http:// por https://

Otro función útil para el manejo de expresiones regulares con PHP es split. Con su ayuda podemos dividir cadenas y obtener un array con las subcadenas resultantes.

$cadena = "http://www.google.com";
$arr = split('\/\/|\.', $cadena);
while (list($k, $v) = each($arr)) {
 echo $v .'<br />'; 
}
//retorna
http:
www
google
com

Para realizar una comparación global de una expresión regular utilizamos la función preg_match_all() que buscará todas las coincidencias de la expresión regular dada y las introduce en un array en el orden que especifiquemos opcionalmente.

$cadena = "En el año 1942 Cristobal Colon descubrió américa. ";
$cadena .= "Murió en el 1506.";
preg_match_all("/[0-9]{4}/", $cadena, $coincidencias);
foreach ($coincidencias as $a) {
  foreach ($a as $v) {
    echo $v . '<br />'; 
  }
}
//imprime
1942
1506
sábado, 4 de septiembre de 2010

Sustitución de subcadenas con PHP

Más recursos para el manejo de strings str_replace() y substr_replace(). Sirven básicamente para buscar y reemplazar cadenas.

//podemos utilizar una variable o un array
//para indicar los terminos buscados
$arr_busca = array("hola", "clavel", "corazón");
$arr_reemplaza = array("adiós", "flor", "amor");
str_replace($arr_busca, $arr_reemplaza, "hola clavel, adiós corazón");
//resulta
adiós flor, adiós amor

Del mismo modo la función substr_replace permite buscar y reemplazar una subcadena de una cadena en función de su posición. Espera los parámetros: cadena, sustitución, inicio y longitud. Si el valor del parámetro inicio es positivo o 0 el desplazamiento se calcula desde el principio, si es negativo se establece con respecto al final de la cadena. El valor de longitud representa el número de caracteres que será sustituido, si es 0 la cadena de sustitución se inserta sin sobreescribir la cadena existente, si este es negativo representa el punto donde se dentendrá la sustitución.

$var = substr_replace($str, 'hola', 2, 0); 

Funciones prácticas para manipular cadenas con PHP

La manipulación de cadenas de texto es una de las tareas más comunes a la hora de trabajar con PHP. Este lenguaje incorpora de forma nativa un buen número de funciones que nos facilitan enormemente el manejo de strings. Vamos a repasar algunas de estas las funciones para manipular cadenas más comunes.

Función Descripción
strtoupper() Convierte la cadena pasada como parámetro en mayúsculas.
strtolower() Convierte la cadena en minúsculas.
ucfirst() Pone en mayúsculas el primer carácter de la cadena.
ucwords() Pone en mayúsculas la primera letra de cada palabra.
addslashes() Escapa carácteres especiales agregando la barra invertida correspondiente.
stripslashes() Elimina las barras de escape.

Ejemplos de uso de otras funciones.

//substr() retorna una subcadena a partir
//de los puntos indicados como parámetro incial y final
$var = substr("hola que tal", 1);
//devuelve
ola que tal

//si el valor inicio es negativo
//devuelve la parte final de la cadena
//con los caracteres indicados
substr("hola que tal", -3);
//devueve
tal

//el parámetro longitud sirve para
//indicar el número de carácteres a devolver
//si es positivo o la posición final de la
//secuencia de retorno si es negativo
substr("hola que tal", 0, 4);
//devuelve
hola
substr("hola que tal", 0, -4);
//devuelve
hola que

Para buscar subcadenas dentro de otras cadenas utilizamos strstr(), que espera que le pasemos 2 parámetros, primero el texto donde buscar y segundo el texto buscado. Devuelve el texto pasado como parámetro número 1 desde la posición donde se haya encontrado la cadena buscada o false en caso de no encontrarla.

$cadena = "En un lugar de la mancha";
echo strstr($cadena, "lugar");
//devuelve
lugar de la mancha

Para obtener la posición de una subcadena utilizaremos strpos() y strrpos() que funcionan básicamente igual que strstr() con la diferencia de que en lugar de devolver una subcadena devuelve su posición numérica.

$cadena = "En un lugar de la mancha";
echo strpos($cadena, "un");
//imprime 3 ya que 3 es la
//posición que ocupa "un" en la
//cadena principal

//podemos emplear un tercer parámetro
//que sirve para indicar la posición
//a partir de la cual comenzamos a buscar
echo strpos($cadena, "n", 3);
//devuelve 4 ya que no se ha tenido en cuenta
//la primera n de "En"

La función strrpos() realiza la misma tarea pero retorna la posición de la última coincidencia en lugar de la primera. Estas dos funciones devolverán false si no encuentran la subcadena buscada. Importante: utilizar comparaciones estrictas y el operador === para evitar falsos positivos.