Archive for the ‘php’ Category

Listar archivos de un directorio web con PHP y XML

Lunes, Octubre 27th, 2008

Este es un sencillo script de PHP que nos permite generar un archivo XML con el listado de todos los archivos y carpetas que esten contenidos dentro del directorio en el que hemos situado el archivo PHP.

Esto nos puede resultar útil para realizar galerías fotográficas en las que queremos acceder a todas las imágenes de un directorio y queremos poder subir o borrar archivos. El archivo XML siempre estará actualizado a los ficheros del servidor.

El archivo PHP es el siguiente. Lo llamaremos list.php y lo subiremos al servidor dentro de la carpeta que nos interese listar.

Código :

<?php
   $dir = "./";
   
   echo "<XML encoding='UTF-8' standalone='yes' version='1.0'>n";
   echo "  <folder>n";
   
   if (is_dir($dir))
   {
       if ($gd = opendir($dir))
      {
           while (($archivo = readdir($gd)) !== false)
         {
            if ($archivo != "." & $archivo != ".." & $archivo != "list.php")
            {
               if (is_dir($archivo))
               {
                     echo "    <folder>$archivo</folder>n";
               }
               else
               {
                     echo "    <file>$archivo</file>n";
               }
            }
           }
           closedir($gd);
       }
   }
   
   echo "  </folder>n";
   echo "</XML>n";
?>

El script lo único que hace es recorrer todos los elementos de la carpeta en la que está situado y a base de "echos" formatea el XML.

Si visualizamos este archivo desde el navegador y miramos el código resultante este sería un archivo XML de este estilo:

Código :

<XML encoding='UTF-8' standalone='yes' version='1.0'>
  <folder>
    <file>img_001.jpg</file>
    <file>img_002.jpg</file>
    <file>img_003.jpg</file>
    <file>img_004.jpg</file>
    <file>img_005.jpg</file>
    <folder>thumbs</folder>
    <folder>hires</folder>
  </folder>
</XML>

De esta manera si quisiésemos, por ejemplo, listar el contenido de imágenes disponibles de este directorio dentro de un componente List de Flash haríamos lo siguiente:

Código :

import fl.data.DataProvider;

var _URLLoader = new URLLoader();
var _URLRequest = new URLRequest();

_URLRequest.url = "/img/list.php";
_URLLoader.load(_URLRequest);
_URLLoader.addEventListener(Event.COMPLETE, onListComplete);

function onListComplete(e:Event):void
{
   var xml:XML = new XML(e.target.data);
   var xmlList:XMLList = xml.folder.file;
   var dataProvider = new DataProvider();
   for each (var item in xmlList)
   {
      dataProvider.addItem({label:item});
   }
   listado.dataProvider = dataProvider;
}

Cargamos el archivo PHP como si de un XML se tratase, y de ahí lo convertimos en el dataProvider del componente.

Enviar comentario

Cómo obtener el total de días en un mes en PHP

Miércoles, Octubre 1st, 2008

Les paso una sencilla función para saber cuantos días tiene un mes. Ya existe una función nativa de php para eso, pero requiere tener instalada la extensión de calendario (no todos los servidores compilan php con esa extensión). Si no tienes la extensión, obtenemos el total de meses, con una función que se me ocurrió el otro día y es muy simple.

Código :

function getMonthDays($Month, $Year)
{
   //Si la extensión que mencioné está instalada, usamos esa.
   if( is_callable("cal_days_in_month"))
   {
      return cal_days_in_month(CAL_GREGORIAN, $Month, $Year);
   }
   else
   {
      //Lo hacemos a mi manera.
      return date("d",mktime(0,0,0,$Month+1,0,$Year));
   }
}
//Obtenemos la cantidad de días que tiene septiembre del 2008
echo getMonthDays(9, 2008);

Simplemente hay que pasarle como parámetro el mes y el año, es todo.

Enviar comentario

Conectarse a 2 bases de datos con PHP alternativamente

Miércoles, Octubre 1st, 2008

Cuando tenemos una página enlazada a la base de datos del servidor, pero queremos hacer pruebas en nuestro servidor remoto, nos encontramos con el problema de cambiar los datos de conexión, ya sea en tu archivo de conexión si lo tuvieras (muy recomendable) o cambiar los datos en cada pagina que llame al dicho archivo por otro que contenga los datos de tu servido local, es decir el problema se presenta como algo así:

Tienes esta linea para conectarte a tu servidor remoto

Código :

require_once('Connections/conexion_remota.php'); 

El cual esta llamando a un archivo con mas o menos el siguiente esquema

Código :

<?php
$hostname='tu.servidor.remoto';
$username='usuario_remoto';
$password='password_remoto';
$dbname='base_de_datos'; 

$base = mysql_connect($hostname,$username, $password) OR DIE ('No puedo conectarme a la base de datos! Inténtelo nuevamente.');
?>

Si quisieras conectarte a otra base en vez de esta como ya lo dije arriba o bien cambias la linea del include para llamar a otro archivo quedando algo como

Código :

#require_once('Connections/conexion_remota.php');
require_once('Connections/conexion_local.php'); 

Con la consiguiente creación del archivo de conexión local, sin embargo existe otra manera de evitar todo este engorroso procedimiento. Cada vez que deseamos conectarnos a la base local, en vez de la remota, podemos usar este código. Lean los comentarios:

Código :

<?php
$hostname='tu.servidor.remoto';
$username='tu_usuario_remoto';
$password='tu_password_remoto'; 

$hostname2='localhost'; //puede ser reemplazado por el nombre de tu servidor local si fuera otro nombre
$username2='tu_usuario_local';
$password2='tu_password_local'; 

$dbname='tu_base_de_datos';
#Para efectos del ejemplo supondremos que es la misma base de datos en ambas bases de datos tanto la remota como la local 

$conex_remota = @mysql_connect($hostname,$username, $password);
#notese el @ antes del comando mysql_connect para evitar que arroje mensaje de error de PHP 

if (!($conex_remota)) {
    $conex_local = @mysql_connect($hostname2,$username2, $password2) OR DIE ('No puedo conectarme a la base de datos local! Intentelo nuevamente.');
}
mysql_select_db($dbname);
?>

Espero les sirva este pequeño aporte. Con algunas pequeñas modificaciones podría servir para conectarse a una segunda base de datos remota, en vez de la local, en caso la base principal no pueda ser accesible.

Enviar comentario

Clase para renombrar varios archivos mediante PHP

Lunes, Septiembre 15th, 2008

Me gusta que los nombres de los archivos que descargo sean correctos y sea fácil, buscarlos. Esto significa que los nombres deben tener el numero de capitulo, la serie/anime en cuestión y el nombre del capítulo.

El problema, es que a veces se consiguen con nombres de archivos que parecen el resultado de alguna función random, por lo que tenemos una ardua labor de renombrar cada uno de los archivos a mano.

Así que hice un pequeño script en PHP para facilitarme la vida:

Código :

<?php
class files
{
   private $total;
   private $archivos;
   private $serie;
   private $nombre;
   private $ext;
   private $report;
   private $sep;
   
   function __construct() {
      $directorio = getcwd();
      $me = $_SERVER['SCRIPT_NAME'];
      $me = basename($me);

      $this->report = '';
      
      $dire = opendir($directorio);
      
      if ($dire)
      {
         while($nombre_archivo = readdir($dire))
         {
            if ((is_file($nombre_archivo)) && ($nombre_archivo != $me))
            {
               $this->archivos[] = $nombre_archivo;
            }
         }
      }
      sort($this->archivos);
      $this->total = count($this->archivos);
      $this->ext = substr($this->archivos[0], -3, 3);
   }
   
   public function getTotal()
   {
      return $this->total;
   }
   
   public function getName($value)
   {
      return $this->archivos[$value];
   }

   public function getReport()
   {
      return $this->report;
   }

   public function setSerie($value)
   {
      $this->serie = $value;
   }

   public function setSep($value)
   {
      $this->sep = ' ' . $value . ' ';
   }
   
   public function setExt($value)
   {
      $this->ext = '.' . $value;
   }   

   public function getExt()
   {
      return $this->ext;
   }
   
   public function setName($i, $value, $uppercase)
   {
      if ($value != '') {
         if ($uppercase) {
            $value = ucfirst(strtolower($value));
         }
         $this->nombre[$i] = $this->setCapitulo($i + 1) . $this->sep . $this->serie . $this->sep . $value . $this->ext;
      } else {
         $this->nombre[$i] = $this->archivos[$i];
      }
   }
   
   private function setCapitulo($value)
   {
      if ($value <= 9) {
         return '0' . $value;
      } else {
         return $value;
      }
   }
   
   public function renombrar()
   {
      for ($x=0; $x < $this->total; $x++) {
         rename($this->archivos[$x], $this->nombre[$x]);
         $this->report .= 'Cambie: "' . $this->archivos[$x] . '" por "' . $this->nombre[$x] . '" <br />';   
      }
   }
}

$archi = new files();

if ($_POST)
{
   $caps = $_POST['cap'];
   $formats = $_POST['format'];
   $archi->setSerie($_POST['serie']);
   $archi->setSep($_POST['sep']);
   $archi->setExt($_POST['ext']);
   for ($i=0; $i < $archi->getTotal(); $i++) {
      $archi->setName($i, $caps[$i], $formats[$i]);
   }
   $archi->renombrar();
   echo $archi->getReport();
}
else
{

?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Renombrando archivos</title>
    </head>
    <body>
    </body>
    <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" />
    Serie: <input type="text" name="serie" /><br />
    Separador: <input type="text" name="sep" value="-" /><br />
    Extension: <input type="text" name="ext" value="<?php echo $archi->getExt(); ?>" /><br />
    <?php for ($i=0; $i < $archi->getTotal(); $i++) { ?>
    Capitulo <?php echo $i + 1; ?>: <?php echo $archi->getName($i); ?> -> Nombre nuevo: <input type="text" name="cap[<?php echo $i; ?>]" /> Formatear texto <input type="checkbox" value="true" checked="checked" name="format[<?php echo $i; ?>]" /><br />
    <?php } ?>
    <input type="submit" value="Renombrar" />
    </form>
    </html>
<?php
}
?>

A explicar un poco todo ahora.

Para que este script funcione, como mínimo, los archivos deben estar ordenados. No importa cómo, pero por lo general, si los bajamos de Internet, vienen ordenados. Y el script debe estar en la misma carpeta que los archivos a renombrar.
Aclaración: NO hace validación de caracteres, así que si ponen cosas como ¿\: lo más probable es que no realice el cambio de nombre de ese archivo.


El formulario

Cuando ejecutamos por primera vez el script vamos a ver el formulario con los siguientes inputs:

  • El nombre de la serie en cuestión.
  • El separador que queremos usar, por defecto está el guión "-".
  • La extensión de los archivos, por defecto toma la de los archivos.
  • Un listado con los capítulos actuales, y el nuevo nombre que le queremos dar. Este nombre deberá ser el nombre del capítulo.
  • Luego veremos un checkbox que es para darle un formato; esto viene a cuento de que a veces conseguimos una lista con los nombres de capítulos y por ejemplo, un nombre puede ser "La Vaca Que Cruzó la Calle", esto estimados, está MAL ortográficamente hablando (sí, así de obsesivo soy), si el check esta tildado (opción por defecto) convierte esa cadena a "La vaca que cruzó la calle". Si desactivamos el check, el nombre del capitulo será tal cual lo escribimos en el input.

Luego de que escribamos todos los nombres, viene la magia.

Voy a dar un ejemplo del script:

Serie: "Burst angel"
Separador: "-"
Extensión: "avi"
Capitulo 1: "La Batalla del Ángel Caído" Format: true
Capitulo 2: "Joe asesina a Meg" Format: false

El resultado será:
01 - Burst angel - La batalla del ángel caído.avi
02 - Burst angel - Joe asesina a Meg.avi


La clase

El constructor: Lo que hace el constructor es hacer el listado que vimos antes en el formulario, ordena los archivos, los cuenta, y setea algunas variables.
Luego tenemos los setters y getters:

  • setSep: Automáticamente agrega un espacio antes y después del separador.
  • setExt: Automáticamente agrega el punto antes de la extensión.
  • setName: Crea un vector con los nuevos nombres, si está el check activado, formatea el nombre del capítulo. Una validación que tiene, es si no ingresamos nada como nombre, le asignara el mismo nombre que tiene actualmente.
  • setCapitulo: Formatea el numero del capítulo, si es menor a 9, le agrega un cero (se verá 09).

Luego, viene el que hace la otra parte de la magia; renombrar.
Esta función recorre los 2 vectores (uno que contiene el nombre de archivo, y el otro que contiene el nuevo nombre), renombrando los archivos, y generando un reporte diciendo a qué archivo le puse qué nombres.


Uso de la clase.

Luego de que se instancia la case, viene un if. Con ese if sabremos si estamos o no recibiendo variables desde el formulario. Si no las recibimos, veremos el formulario con todo lo explicado anteriormente.
Cuando enviamos todo por el formulario, vamos a setear el nombre de la serie, el separador, la extensión de los archivos y tendremos 2 vectores, uno con el nombre de los capítulos y otro con un true/false para saber si debemos darle un formato. Luego de eso, viene un for para setear el nombre de los archivos, a continuación le decimos que renombre y nos muestre el reporte.

Espero que les sea útil.

Enviar comentario