Archivo

Supervisar directorios con PHP

septiembre 14th, 2011 by admin

Si tenemos una web que permite a los visitantes subir archivos, debemos controlar que no se suba nada inadecuado.

Lo primero sería programar la web de forma segura, intentando que sea “imposible” que un usuario malintencionado suba ficheros maliciosos.

Si hemos realizado lo anterior correctamente es muy probable que no tengamos ningún problema, pero si deseamos un poco mas de seguridad (o control) podemos supervisar el directorio donde esta la web. De esta forma si detectamos cambios en ficheros o ficheros nuevos podemos saber cuales son y actuar en consecuencia.

En el caso de que la web permita subir imágenes, quizás debamos modificar este código para filtrar las imágenes, de lo contrario, cada imagen que se suba nos generará una alerta.

<?php
date_default_timezone_set('Europe/Madrid');
//Timezone soportados: http://www.php.net/manual/es/timezones.php
 
class FileLog
{
	private $_baseDir = ""; //Directorio que se controla
	private $_numSubDir = 0; //Número de subdirectorios
	private $_numFiles = 0; //Número de ficheros
	private $_fileMod = 0; //Número de archivos modificados
	private $_time = ""; //Fecha base desde la que se registran cambios
	private $_badFiles = array(); //Ficheros nuevos o modificados desde la fecha base
 
	public function __construct($dir)
	{
		$this->_baseDir = $dir;
	}
 
	/**
	 * Leer todos los ficheros de un directorio de forma recursiva.
	 * @param String $dir directorio base
	 * @param boolean $review indica si se estan buscando ficheros nuevos/modificados
	 */
	public function readDir($dir, $review = false) {
 
		$openDir = opendir($dir);
 
		while($file = readdir($openDir))
		{
			if($file == "." || $file == ".." || $file == "fileLog.txt") {continue; }			
 
			if(is_dir($dir . "/" . $file)) {
 
				if($review) {
					$this->readDir($dir . "/" . $file . "/", true);	
				} else {
					$this->readDir($dir . "/" . $file . "/");
					$this->_numSubDir++;
				}					
 
			} else { 
 
				if($review) {
					clearstatcache();
 
					$ftime = filemtime($dir . "/" . $file);				
 
					if($ftime > $this->_time) {
						$this->_badFiles[] = date("d/m/Y H:i:s", $this->_time) . " - " . date("d/m/Y H:i:s", $ftime) . " | " . $dir . "/" . $file;
						$this->_fileMod++;
					}
				} else {				
					$this->_numFiles++;
				}
 
			}
		}
	}
 
	/**
	 * 
	 * Crea un archivo (si no existe) y guarda la información de el directorio
	 * que se esta supervisando. La información se guarda con este formato:
	 * fecha&dir&file
	 * 
	 * fecha en formato unix
	 * dir el número de subdirectorios dentro de el directorio supervisado
	 * file el número de ficheros dentro del directorio supervisado
	 * 
	 * @return boolean
	 */
	private function _writeFile()
	{
		$path = dirname(__FILE__) . "/fileLog.txt";
		$data = time() .'&'. $this->_numSubDir .'&'. $this->_numFiles;
 
		$fopen = fopen($path, "w");
 
		if($fopen) {
			if(fwrite($fopen, $data)) {
				return true;
			} else {
				return false;
			}
		} else {
			return true;
		}
	}
 
	/** 
	 * Genera los avisos cuando hay nuevos ficheros o ficheros modificados
	 * @param int $dir número de directorios en el registro base
	 * @param int $files número de ficheros en el registro base
	 */
	private function _alert($dir, $files)
	{
		$log = "";
		$msg = "";
 
		//Avisar de los nuevos ficheros
		$msg = "Hay directorios o ficheros nuevos.\r\n";
		$msg .= "Directorios nuevos: " . ($this->_numSubDir - $dir) . "\r\n";
		$msg .= "Ficheros nuevos: " . ($this->_numFiles - $files);	
		$msg .= "\r\n";	
		$msg .= "En breve recibirá un email con los cambios en los ficheros";	
		$this->_send($msg);
 
		//Buscar fichero nuevos
		$this->readDir($this->_baseDir, true);
 
		//Avisar de los ficheros nuevos y modificados
		foreach($this->_badFiles as $file)
		{
			$log .= $file . "\r\n";
		}
 
		$msg = "Informe de cambios en ficheros\r\n";
		$msg .= "Directorios nuevos: " . ($this->_numSubDir - $dir) . "\r\n";
		$msg .= "Ficheros nuevos: " . ($this->_numFiles - $files) . "\r\n";
		$msg .= "Archivos modificados: " . ($this->_fileMod - ($this->_numFiles - $files)) . "\r\n";
		$this->_send($msg . $log);
	}
 
	/**
	 * Procesa los mensajes generados. En este ejemplo los muestra en pantalla.
	 * Pero si este fichero es ejecutado por un cron la mejor opción sería enviar
	 * estos mensajes por email on crear un archivo log.
	 * @param String $msg
	 */
	private function _send($msg)
	{
		echo nl2br($msg);
		echo "<hr>";
	}
 
	public function __destruct()
	{
		$pathFileLog = dirname(__FILE__) . "/fileLog.txt";
 
		if(file_exists($pathFileLog)) {
 
			$data = file_get_contents($pathFileLog);
			$data = explode("&", $data);
 
			$this->_time = intval(trim($data[0]));
			$dir = $data[1];
			$files = $data[2];
 
			if($this->_numSubDir > $dir || $this->_numFiles > $files) {
				$this->_alert($dir, $files);
			}
 
		} else {
			$this->_writeFile();
		}
	}
}
 
//Exec
$read = new FileLog(dirname(__FILE__));
$read->readDir(dirname(__FILE__));

Etiquetas: ,

Ejecutar archivos PHP desde consola (windows)

septiembre 13th, 2011 by admin

Primero tenemos que localizar el archivo php.exe, su localización depende de cada instalación. Cuando lo tengamos localizado abrimos una consola.

Inicio – Ejecutar – cmd

Ahora vamos al directorio donde esta el archivo php.exe. Cuando estemos en el mismo directorio podremos ejecutar los archivos php.

>php.exe -f “Ruta al fichero php”

Ejemplo:

 >php.exe -f “c:\hola_mundo.php

Nos puede ocurrir que un fichero php que funciona correctamente ejecutado desde un navegador, no funcione desde consola. Esto puede ser debido a que el fichero utilice funciones de alguna extensión (MySQL, cUrl, SimpleXML, …) que se estén cargando como modulo de apache.

Para saber que extensiones (módulos) esta cargando php y no apache podemos ejecutar el comando:

>php.exe -m

Para terminar, indicaros el comando necesario para acceder a la ayuda de php.exe.

>php.exe -h

Enlaces interesantes:

Instalación de Apache, PHP y MySQL por separado

http://www.clubdesarrolladores.com/articulos/mostrar/27-como-instalar-y-configurar-apache-php-y-mysql-en-windows

Ayuda para el CLI de php

http://www.php.net/manual/en/features.commandline.options.php

Etiquetas: , ,

Obtener el día de la semana correspondiente a una fecha especificada con php (mktime y date).

diciembre 11th, 2009 by Webmaster

A continuación dejo una simple función que permite realizar lo ya indicado en el titulo. Es algo realmente simple, pero cuando yo necesite este dato, tuve que buscar durante unos minutos en la documentación de php y después preparar la función.

Como es un trozo muy pequeño de código, es posible que este se pierda. Para evitar que esto ocurra y para aquellos usuarios que lo necesiten expongo el código.

<?php
/**
 * Obtener el día de la semana para una fecha concreta.
 */
function diaSemana($ano,$mes,$dia)
{
	// 0->domingo	 | 6->sabado
	$dia= date("w",mktime(0, 0, 0, $mes, $dia, $ano));
		return $dia;
}
 
/**
 * Ejemplo de uso
 */
$diaSemana = diaSemana("2009", "12", "10");
echo $diaSemana;
 
/**
 * Imprime:
 * 4 | El cuatro corresponde a Jueves
 */
?>

Etiquetas: ,

Añadir marco a las imágenes con php y GD

junio 27th, 2009 by admin

La función mostrada a continuación permite la creación de un marco a las imágenes que queramos. Podemos elegir el ancho del marco y el color. Ademas también podremos indicar el prefijo para la nueva imagen creada, ya con el marco.

La imagen que genera esta función es algo mas grande que la imagen original. Si queremos cambiar el tamaño de la imagen para que tenga el mismo que la original u otro tamaño podemos utilizar esta clase mencionada ya en mascodigo.

A continuación facilito el código fuente.

<?php
/**
 * Ejemplo de uso
 */
crearMarco("img.jpg", 1, "48,192,255");
 
/**
 * Crear un marco para una imagen
 */
function crearMarco($rutaImagen, $anchoDelMarco, $colorRGBMarco, $prefijo = "marco_")
{
    //Crear imagen
    $imagen = imagecreatefromjpeg($rutaImagen);
 
    //obtener ancho y alto de la imagen
    $ancho = imagesx($imagen);
    $alto = imagesy($imagen);
 
    //crear imagen que utilizaremos de marco
    $anchoNuevaImagen = $ancho + ($anchoDelMarco + $anchoDelMarco);
    $altoNuevaImagen = $alto + ($anchoDelMarco + $anchoDelMarco);
 
    $imagenMarco = imagecreatetruecolor($anchoNuevaImagen, $altoNuevaImagen);
 
    //poner color a  la imagen
    $colores = explode(",", $colorRGBMarco); 
 
    $color = imagecolorallocate($imagenMarco, $colores[0], $colores[1], $colores[2]);
 
    imagefill($imagenMarco, 0, 0, $color);
 
    //añadir marco a la imagen
    imagecopymerge($imagenMarco, $imagen, $anchoDelMarco, $anchoDelMarco, 0,0, $ancho, $alto, 90);
 
    //guardar imagen en fichero
    imagejpeg($imagenMarco, $prefijo . $rutaImagen);
}
?>

Etiquetas: , ,

Creación de thumbnails con PHP

marzo 22nd, 2009 by admin

La creación de thumbnails es algo muy utilizado en las aplicaciones web, en las páginas y en algunos otros sitios.

Frecuentemente desarrollo web que serán auto-gestionadas por el usuario final, por lo tanto, intento hacer el administrador del sitio lo mas cómodo y fácil posible.

Una de las cosas que me ocupa mas tiempo es la posibilidad de que puedan subir imágenes. Lo malo de esta opción para los usuarios finales del sitio, es que, normalmente no se preocupan por subirlas con un tamaño y peso adecuado para su visualización.

Entonces aquí me encuentro con dos posibilidades, que son:

- intentar concienciar al usuario de como debe subir las imágenes. Esta opción la descarto por que el solo hecho de tener que indicarle esto, seguramente acarreara que según su punto de vista el sitio no sea bueno o el programador no es lo suficientemente bueno. Además si algún día no respeta las normas indicadas y la web se muestra de forma incorrecta, ¿ a quien llamara ?.

- Programar la web para que trate las imágenes de forma transparente al usuario. Y es aquí donde quería llegar, creación automática de thumbnails.

Para utilizar la clase imágenes mostrada al final del articulo debemos seguir los siguientes pasos:

/**
 * Ejemplo de uso
 */
 
//añadir la clase
include("./class_imagenes.php");
 
//imagen origen (1280px)
$imagen = "./fondo.jpg";
 
//crear objeto
$thumbnails = new Imagenes();
 
//indicar la imagen origen
$thumbnails->setImagen($imagen);
 
//indicar el formato de la imagen origen
$thumbnails->setFormato("jpg");
 
//indicar el nivel de compresión. Segun este nivel la imagen
//tendra mayor o menos calidad.
$thumbnails->setCompresion(90);
 
//indicar donde se creará y con que nombre el thumbnails
$thumbnails->setNombre("./thumb_fondo.jpg");
 
//indicar el tamaño del thumbnails (250)
$thumbnails->reducir(250);

La clase (class_imagenes.php):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
<?php
/**
 * Creación de thumbnails ( creación de imágenes en miniatura )
 *
*/
class Imagenes
{
	//Propiedades de la clase
	private $_imagen;
	private $_formato = 'jpg';
	private $_nuevaImagen;
	private $_compresion = 90;
	private $_nombre;
 
	/**
	 * Verificar si la libreria GD esta instalada.
	 */
	public function __construct()
	{		
		$gd=gd_info();
 
		foreach ($gd as $key => $valor)
		{
			if(!$valor) { 
				return 'La libreria GD no esta disponible.'; 
			} 
		}
	}
 
	/**
	 * Indicar a la clase con que imagen vamos a trabajar, es decir, a que
	 * imagen le vamos a crear un thumbnails.
	 */
	public function setImagen($urlImagen)
	{
		$this->_imagen = $urlImagen;
	}
 
	/*
	 * Indicar el formato de que tiene la imagen. La indicada en el 
	 * método "setImagen".
	 */
	public function setFormato($ext)
	{
		switch($ext)
		{				
			case "jpeg": 
				$this->_imagen = imagecreatefromjpeg($this->_imagen); 
				$this->_formato = $ext; 
				break;
 
			case "jpg": 
				$this->_imagen = imagecreatefromjpeg($this->_imagen);
				$this->_formato = $ext; 
				break;
 
			case "png": 
				$this->_imagen = imagecreatefrompng($this->_imagen);
				$this->_formato = $ext; 
				break;
 
			default : return "Formato de imagen NO soportado.[jpeg|jpg|png]";
		}		
	}	
 
	/**
	 * Obtener el ancho (width) de la imagen.
	 */
	public function getImagenX()
	{
		return imagesx($this->_imagen);
	}
 
	/**
	 * Obtener el alto (height) de la imagen.
	 */
	public function getImagenY()
	{
		return imagesy($this->_imagen);
	}
 
	/**
	 * Nivel de compresión de la nueva imagen.
	 * Máximo 100.
	 * Cuanto mayor sea este valor mejor sera la calidad, 
	 * pero tambien aumentara el tamaño.
	 */
	public function setCompresion($compresion)
	{
		$this->_compresion = $compresion;
	}
 
	/**
	 * Idicar nombre y ruta para la nueva imagen.
	 */
	public function setNombre($nombre)
	{
		$this->_nombre = $nombre;
	}
 
	/**
	 * Redimensionar imagen.
	 * Este método recibe el ancho (x) y el alto (y) que tendra 
	 * la nueva imagen.
	 * Si $y no se indica, este se añadira con un ancho proporcinal.
	 */
	public function reducir($x, $y = 0)
	{		
		if($y == 0) {
			//Obtener el alto proporcionalmente.
			$y = imagesy($this->_imagen) * $x;
			$y = $y / imagesx($this->_imagen);
		}
 
		$this->_nuevaImagen = imagecreatetruecolor($x, $y);
 
		imagecopyresampled($this->_nuevaImagen,
				   $this->_imagen,
				   0,
				   0,
				   0,
			           0,
				   $x,
			           $y,
				   imagesx($this->_imagen),
				   imagesy($this->_imagen));
 
		switch($this->_formato)
		{				
			case "jpeg": imagejpeg($this->_nuevaImagen,$this->_nombre,$this->_compresion); 
				break;
 
			case "jpg": imagejpeg($this->_nuevaImagen,$this->_nombre,$this->_compresion);
				break;
 
			case "png": imagepng($this->_nuevaImagen,$this->_nombre,$this->_compresion);
				break;
 
			default : return "Formato de imagen NO soportado.[jpeg|jpg|png]";
				break;
		}				
	}
}
?>

Etiquetas: , ,