jueves, 19 de julio de 2007

FTP mediante PHP

Señoritas y señores, tengan un buen día. He estado trabajando en un sitio web en PHP y en un momento me vi en la necesidad de crear un script para poder subir archivos via FTP a un hosting mediante PHP, y gracias a la información de sitios como Desarrollo web y mediante algunos libros, estuve estudiando lo que son un "set" de métodos para poder subir, bajar archivos y realizar otras operaciones usando el protocolo FTP mediante PHP, y aunque solo voy a cubrir algunas básicas, espero dar a entender la idea y sembrar en ustedes las semillita de curiosidad para poder seguir investigando y realizando cosas mas complejas de este tema. Bueno, asumo que tenemos conocimientos básicos acerca de FTP, pero si no, es un protocolo de transferencia de archivos, el cual, valga la redundancia permite subir archivos a un servidor FTP y tambien bajarlos del mismo. Para ello se utilizan comandos en el servidor, entonces lo que hacen estas funciones en PHP es, literamente, "escribir los comandos necesarios" para realizar una determinada operación como bajar un archivo o algo por el estilo.

En esta ocasión hice una clasesita en PHP que me permite hacer lo siguiente:subir un archivo de *.* permitiendo buscarlo en nuestra computadora, así como asignarle un nombre, que es el que tendrá en el servidor (ahi se puede especificar la extension del archivo en el servidor, que puede variar, lo cual es, digamos, un bugsito y no busque como solucionarlo, pero en otro post veremos eso XD ) asi como tambien visualizar los directorios que se encuentran en la carpeta raíz para seleccionar uno (en un listbox) el cual será el directorio en el cual queremos subir el archivo, luego de subirlo nos indica el vínculo para poder descargar el archivo. La clase la tengo a continuación:



class upFile
{

function inicializar()
{
define("ServerFTP","nombreDelServidor");
define("Puerto",puertoDelServidor);//El numero de puerto es un tipo int, asi que va sin comillas dobles o simples
define("Nombrecito","usuarioParaLogin");
define("Secretito","contrasenaParaLogin");
}

function conectarFTP()
{
$conexion = ftp_connect(ServerFTP,Puerto);
ftp_login($conexion,Nombrecito,Secretito);
ftp_pasv($conexion,true);
return $conexion;
}

function subirFile($rutaLocal, $nombreRem)
{
$this->inicializar();
$conexion = $this->conectarFTP();
ftp_put($conexion,$nombreRem,$rutaLocal,FTP_BINARY);
ftp_close($conexion);
}

function verDirs()
{
$this->inicializar();
$conexion = $this->conectarFTP();
$lista = array();
$lista = ftp_nlist($conexion,"/");
for($i = 0;$i<=count($lista);$i++)
{
if (strpos($lista[$i],'.') > 0)
{
unset($lista[$i]);
}
}
ftp_close($conexion);
return $lista;
}

}

?>




Y aqui lo que he hecho es básicamente lo siguiente:

conectarFTP() Iniciamente uso el método ftp_connect(servidor,puerto) para establecer una conexión, cuyo resultado se almacena en una variable que en esencia, es la conexion.

OJO: ¡¡¡Ahorita estamos conectados, pero aun no hemos accedido al servidor!!! Esto es, digamos, como que si "pusieramos" una pasarela entre nosotros y el servidor FTP al cual queremos entrar, pero aun no usamos la pasarela.

Luego, nos logueamos en el servidor para poder acceder a sus archivos y hacer con ellos lo que queramos (segun estén configurados los permisos del servidor) con la función ftp_login(conexion,usuario,contraseña) y luego se usa la función ftp_pasv(conexion,booleano) donde el booleano determinará si la conexión será activa (false) o pasiva (true).

NOTA:Para más información acerca del modo activo/pasivo de conexión FTP, puede ver la siguiente página http://www.ignside.net/man/ftp/pasivo.php.

Al final de la función conectarFTP() hecha por mí, retorno lo que es la conexión como tal para poder ser usada por cualquiera de los métodos que implemente en mi aplicación. Luego tenemos el método subirFile(rutaLocal, nombre) en donde solicito lo que es la ubicación del archivo y el nombre que se desea que el archivo tenga en el servidor. Primeramente, inicializo ciertas variables que contienen datos que ustedes no pueden ver como el nombre del servidor FTP al cual se pretende conectar, el usuario, la contraseña y el puerto en el cual está "escuchando" el servidor (por default 21). Despues de iniciarlizarlas, llamo a la función conectarFTP() para obtener una conexión FTP abierta al servidor, luego uso la función ftp_put(conexion,rutaArchivo,nombre,modo) en donde rutaArchivo es, bueno, ESO, la ruta del archivo, para ello usé un elemento de formulario de tipo file cuya propiedad value almacena la ruta del archivo que fué buscado, mientras que nombre es el nombre especificado que tendrá en el servidor, y finalmente modo que francamente no lo entiendo bien, pero puede ser ftp_ascii ó ftp_binary, y lo que hace esta función es subir el archivo que esta en la ruta especificada usando la conexión especificada y colocándole en el servidor el nombre especificado, usando el modo especificado. Finalmente cierro la conexión con ftp_close(conexion). Esto es lo básico de esta clasesita sencillisima a la cual le faltan cosas como controlar el tipo de archivos a subir, el tamaño de archivos a subir, los permisos que podemos tener sobre los diferentes directorios, etc. Lo cual puede hacerse con otras funciones en PHP del paquetito de funciones FTP que posee, que estan an una libreria que ya incorpora PHP por default.

Debido a razones de evitar abusos de la aplicacioncita o infiltraciones maldeseadas, no la puse activa en algun servidor, pero ustedes pueden descargar la aplicación >>AQUI<< que consta de la clase php, una página para seleccionar el archivo y un directorio y finalmente una página en la cual saldrá la confirmación de que el archivo fué subido así como su ruta para poder ser descargado, y lo que tienen que hacer es únicamente cambiar los valores del nombre del servidor, usuario y contraseña (si los tiene el servidor donde lo prueben) y el puerto por el cual el servidor escucha, en el método inicializar() de la clase. Espero que esto les sirva mucho y cualquier opinión o aporte al tema es bienvenido. Feliz día y ya les traigo más.

jueves, 12 de julio de 2007

Usando POST con AJAX

Tengan un buen día apreciables personas que visitan este foro, recientemente estuve trabajando en un proyectito de un mini-sitio y me auxilié de una tecnología bastante interesante y útil llamada AJAX, que hablando en términos "mundanos" lo que permite es que en una página web, al activarse un evento HTML como onClick, onLoad, onKeyPressed, etc. se "actualize un pedazo de la página", es decir, se haga una petición (request) al servidor diciéndole: "Servidor, nececito x página para actualizar únicamente un sector de la página actual" entonces el servidor, valga la redundancia, te "sirve" la página o script para que sea cargada en un sector de la página, sin hacer una petición de toda la página.

En este caso, sabemos que existen 2 métodos para mandar los datos en una petición al servidor, que son GET y POST, en el cual en el primero los datos se mandan seguidos de la URL y un signo de interrogación, de la siguiente manera:
http://www.data2max.com/?pagina=2&tema=sqlserver

NOTA: Recomiendo a todos los que concurran este pequeño blog que visiten el sitio www.data2max.com que está dedicado al desarrollo de temas referentes a bases de datos y también desarrollo.

Continuando, al contrario de GET, usando POST los datos no se mandan en la URL, sinó que dentro del cuerpo del request, más información de solicitudes al servidor >>AQUI<<. Bueno, a partir de aqui parto que los que estén leyendo este post tienen conocimientos básicos de AJAX, si no es así pero desean aprender, pueden revisar este otro post acerca de introducción a AJAX, veanlo >>AQUI<<. Para usar AJAX con el método GET, únicamente necesitan especificar que usarán GET al abrir el "canal" para realizar la solicitud asíncrona, y al mandar la solicitud usando el método send() del objeto XMLHTTPRequest no necesitan poner nada debido a que los datos que se mandan van en la URL, pero qué pasa si estamos usando POST con AJAX? En tal caso, debemos de especificar ciertas cosas como la codificación de los datos que vamos a mandar y otras cosas más en el método setRequestHeader() del mismo objeto, y luego en el método send() debemos colocar un string que lleve el par de datos (variable=valor[&variable2=valor]...) de la siguiente forma: objetoAjax.send(nombre="Aniceto"&apellido="Chilango") Bueno, perfecto, lo hacemos y ya. Pero, digamos que tenemos mi problema. Yo estaba haciendo un sitio web para un colegio en el cual tenia un buen número de formularios necesarios para inscribir alumnos, registrar profesores, realizar búsquedas personalizadas, etc. Y luego de rellenar los formularios, deseaba que "magicamente" apareciera ya sea una confirmación o algun resultado de enviar el formulario en un panel que estaba en la misma página sin que se actualizara el sitio y pense ¡¡¡AAAAAJAX!!!, pero luego, al hacer el código para mandar la información del formulario mediante POST (debido al valor de los datos) para un formulario, observé que eso solo me iba a servir para un solo form, entonces pensé en hacer un script que me sirviera para mandar cualquier formulario mediante post, y aqui está el script, y lo pongo a disposición de ustedes para que puedan usarlo.

function ajaxFunction()
{
var xmlHttp;
try
{
// Firefox, Opera 8.0+, Safari
xmlHttp=new XMLHttpRequest();
return xmlHttp;
}
catch (e)
{
// Internet Explorer
try
{
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
return xmlHttp;
}
catch (e)
{
try
{
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
return xmlHttp;
}
catch (e)
{
alert("Your browser does not support AJAX!");
return false;
}
}
}
}
function mandarForm(url)
{
var ajax; var vinculo = url;

var largoForm = document.forms[0].length; var i = 0; var postr; larguito=largoForm-1;
while (i <= larguito)
{
if (i != 0)
{
postr += "&";
}
postr += document.forms[0].elements[i].name + "=";
postr += document.forms[0].elements[i].value; i++;
}


ajax=ajaxFunction();
ajax.open("POST",vinculo,true);
//ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
ajax.setRequestHeader("encoding", "utf8");


ajax.onreadystatechange=function()
{
if (ajax.readyState==4)
{
if (ajax.status==200)
{
document.getElementById('capaAjax').innerHTML = ajax.responseText;
}
}
}

ajax.send(postr);
}



Pero, hay un pequeño problema, y es que si utilizo este script en un formulario, el primer campo del formulario (digamos un textbox) su valor no se manda al realizar la solicitud asíncrona, aun no se porqué y espero que si alguien conoce el porqué tengo ese problema, puede hacerlo saber en los comentarios. Así que lo que hago simplemente, para evadir el problema, creo un elemento del tipo hidden al principio del form, como primer elemento, para que solo su valor no sea mandado y todo el formulario sea mandado. Espero que les sirva. En otro post voy a poner una explicación del funcionamiento de este script. Tengan un buen día.

viernes, 6 de julio de 2007

Webcast de controles personalizados con SilverLight 1.1


Tengan un buen día gentes. Quiero anunciar un webcast que va a realizar Microsoft dentro de unas horas acerca de la elaboración y uso de controles personalizados eligiendo uno de los lenguajes de programación por excelencia en .NET (Visual Basic o C#) en SilverLight 1.1 Alpha, una especie de plug-in para navegadores creado por Microsoft el cual tiene soporte para lenguajes .NET, AJAX, Ruby, Phyton, etc. (Más información aquí).


Dicho webcast será dado por Roberto Hernández-Pou, quien tiene las ceritficaciones MCSD.NET, MCT, MCSE, MCDBA, MVP VisualStudio.NET Security, por lo que auguro que estará bastante interesante, los invito a verlo, el vínculo es el siguiente:

http://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032344788&EventCategory=4&culture=es-SV&CountryCode=SV

miércoles, 4 de julio de 2007

Herramienta para depurar JavaScript, Ajax y más

Como primer artículo, quiero anunciar la existencia de una herramienta que me saca de aguas (de aprietos XD) cuando estoy haciendo algo web que involucre JavaScript, AJAX, CSS o algo así, pues tengo algo asi como un apego al modo de trabajo de Visual Studio y su depurador que tiene vistas de variables locales, de objetos, etc. mostrando además la línea exacta de error en algun trozo de código, y eso no se encuentra de forma en los lenguajes mencionados, ya que si tenemos un error en nuestro precioso código JavaScript únicamente vemos un ícono en la parte inferior izquierda que nos lo indica.

Pero ya no más.En mi búsqueda por un depurador con indicadores de error, me encontré con Firebug, un complemento para Mozilla Firefox que, analiza el código ya sea de HTML, CSS, JavaScript, AJAX y XML para encontrar algun error en tiempo de ejecución, señalando la línea del error junto a una pequeña descripción, y muchas cosas más, así que lo recomiendo para todos aquellos, como yo, que tienen problema para detectar errores en sus scripts.

El vínculo para el sitio oficial es http://www.getfirebug.com/. Disfrutenlo.

P.D.: Probablemente existan más herramientas de este tipo, así que si conocen de otras, pueden hacerlas saber en los comentarios, pues en mi caso es la primera que encontré.