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.