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: ,

Buscar enlaces en una cadena y convertirlos en enlaces HTML con php (preg_replace_callback).

diciembre 10th, 2009 by Webmaster

Actualmente casi todos los sitios webs tiene algún método para reconocer enlaces. Da igual donde dejemos un comentario. Puede ser un foro, un chat, un blog, etc. Seguro que cuando enviemos un mensaje, si este contiene algún enlace, una vez publicado podremos pinchar sobre él.

Yo como usuario, lo encuentro bastante útil y cómodo. Por un lado, si soy un visitante, es algo incomodo copiar y pegar el enlace en la barra de direcciones. Es mucho mas fácil hacer “click” sobre el enlace.

Por otro lado, si soy el autor de un comentario y quiero dejar un enlace, solo tengo que escribirlo, no tengo que preocuparme de hacer que sea pinchable.

Por ese motivo, dejo a vuestra disposición una clase en php para leer un texto y convertir en etiquetas HTML todos los enlaces que contenga el texto.

Actualmente solo reconoce los enlaces que comienzan por “http://” pero puede mejorarse para que detecte mas enlaces o realice mas operaciones, esto ya depende de las necesidades de cada uno.

A continuación el código y un ejemplo de uso.

<?php
/**
 * Con esta clase podemos convertir los enlaces de un texto.
 * Por ejemplo si escribirmos:
 * http://www.ejemplo.com
 * se convertirá automáticamente en:
 * <a href="http://www.ejemplo.com">http://www.ejemplo.com</a>
 */
class Enlaces
{
    private $_texto;
    private $_logs;
    private $_debug = false;
    private $_existen = false;
 
    public function __construct($texto = false, $debug = false)
    {
        //Saber si hay que mostar los mensajes de debug por pantalla o no.
        if($debug) {
            $this->_debug = true;
        }
 
        //Verificar que se indicó un texto a parsear
        if(!$texto || empty($texto)) {
            $this->_logs = "Error! Usted no indico la cadena a parsear. rn";
        } else {
            $this->_texto = $texto;
        }
 
        //Parsear texto
        if(!$this->parsear()) {
            $this->_logs .= "Error! El texto indicado no se puede parsear o no
        tiene enlaces. rn";
        } else {
            $this->_logs .= "Texto parseado correctamente";
        }
    }
 
/*
 * Parsear el texto buscando enlaces. Se buscan las cadenas que comienzan por:
 * "http://" sin comillas.
 *
 * Retorna: true si se parsea correctamente, false si no se parsea o
 * si no existen enlaces en el texto.
 */
    private function parsear()
    {
        $this->_texto = preg_replace_callback("/(http://[w/*?*&*=*.*]+)/",
                             "Enlaces::enlacesDetectados", $this->_texto);
 
        if($this->_texto == "NULL" || $this->_existen == false) {
            return false;
        } else {
            return true;
        }
    }
 
/**
 * Convierte los enlaces en enlaces HTML. Si queremos añadir atributos a los enlaces generados, debemos
 * hacerlo aquí.
 */
    private function enlacesDetectados($coincidencias)
     {
         foreach($coincidencias as $enlace)
         {
             $this->_existen = true;
             $enlace = "<a href='" . $enlace . "'>" . $enlace . "</a>";
                return $enlace;
         }
     }
 
/**
 * Devuelve el texto con los enlaces convertidos.
 */
    public function getTexto()
    {
        return $this->_texto;
    }
 
/**
 * Devuelve el logs generado durante la ejecución. Solo devuelve el logs si se indico previamente.
 */
    public function getLogs()
    {
        if($this->_debug) {
            return $this->_logs;
        }
    }
}
 
/**
 * EJEMPLO DE USO
 */
 $texto = " Este es un texto de prueba. Con un enlace a http://www.google.es y
otro enlace a http://google.com, &iquest; Que te parece ?";
 
$enlaces = new Enlaces($texto);
echo $enlaces->getTexto();
 
/**
 * Se imprime:
 *
Este es un texto de prueba. Con un enlace a <a href='http://www.google.es'>http://www.google.es</a> y
otro enlace a <a href='http://google.com'>http://google.com</a>, &iquest; Que te parece ?
 
 */
?>

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: , ,

Enviar datos POST en PHP sin formulario, utilizando fsockopen.

junio 21st, 2009 by admin

Hace unos días, me encontré con la necesidad de enviar una serie de datos, a una página, utilizando el método POST.

Al principio pensé en realizar esto con la función “header” pero no lo conseguí. Entonces comencé a buscar en google y encontré algunos sitios que utilizaban “curl” para el envió de datos.

Los ejemplos que encontré con “curl”, parecían sencillos de implementar, el único problema es que hay que tener “curl” instalado en el servidor.

Seguí buscando en google y encontré otras páginas que explicaban como hacer esto con “fsockopen”.

Una vez utilice “fsockopen” para conectar a un servidor POP3 y obtuve buenos resultados, a si que, me decidí a intentar conseguir mi objetivo inicial utilizando esta función.

A continuación muestro el código de dos ficheros php. Un fichero llamado “enviarPOST.php” y otro llamado “variablesPOST.php”.

Como podréis imaginar por el nombre de los ficheros “enviarPOST.php” se encarga de enviar a “variablesPOST.php” los datos que este espera.

enviarPOST.php

<?php
/**
 * CONFIGURACIÓN
 */
$carpeta = "/tmp/a/variablesPOST.php";
$host = "localhost";
$datos = "variable=correctoOK";
$size = strlen($datos);
 
$c = fsockopen($host, "80");
 
if(!$c) {
    echo "Error!";
}
 
//Enviar datos POST
fputs($c, "POST " . $carpeta . " HTTP/1.0rn");
fputs($c, "Content-Type: application/x-www-form-urlencodedrn");
fputs($c, "Content-Length: " . $size . "rn");
fputs($c, "Connection: close rrnn");
fputs($c, $datos . "rn");
 
//Obtener datos
while(!feof($c))
{
    $datoss .= fgets($c,4096);
}
 echo $datoss;
?>

variablesPOST.php

<?php
echo "La variable es: " . $_POST["variable"];
?>

Etiquetas: , , ,

Instalación fácil ( 4 pasos ) de eclipse con soporte php

mayo 27th, 2009 by admin

 

Página de descarga:

 

http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/galileo/RC1/eclipse-php-galileo-RC1-linux-gtk.tar.gz

 

Descargamos el archivo. La descarga tardará unos minutos, puesto que el tamaño del archivo es de 138MB aproximadamente.

Una vez descargado, abrimos un terminal (Menú → accesorios → terminal ).

 

Desde el terminar con el comando ls ( ver los archivos y directorios ) y cd ( cambiar de directorio) nos situamos en el directorio donde descargamos el archivo.

 

El nombre del archivo será parecido a este “eclipse-php-galileo-RC1-linux-gtk.tar.gz”. Cuando ya estemos en el directorio, descomprimimos el archivo con la siguiente instrucción:

tar -zxvf NombreDelArchivo


Después de descomprimir, entramos en la carpeta creada (en este caso la carpeta creada se llama eclipse).

cd eclipse


Ahora ejecutamos el programa.

./eclipse


Al ejecutarse nos pregunta nuestro espacio de trabajo. Le indicamos el que nosotros queramos.

Una vez iniciado el programa, vamos a:

windows → open perspective → other → php(default)


Y listo. Ya podemos trabajar con php en eclipse.

 

Ahora para tener un poco de orden en nuestro ordenador realizamos lo siguiente.

* Vamos al directorio donde descargamos el programa. Renombramos la carpeta que se creo (eclipse) por “.eclipse”:

mv eclipse .eclipse


Le añadimos un punto delante, para convertir el directorio en oculto.

* Ahora copiamos el directorio a nuestro home, en mi caso “/home/felipe/”:

cp -a .eclipse /home/felipe/


* Para terminar creamos un acceso directo al programa en nuestro escritorio:

ln -s /home/felipe/.eclipse/eclipse /home/felipe/Escritorio/eclipsePHP


Ahora vamos al escritorio, botón secundario sobre el acceso directo, propiedades y le ponemos el icono que queramos.

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: , ,