Para leer el contenido de un directorio, pero sólo los ficheros o directorios (sin "." ni ".."):
$directorio=dir(RUTA);
while ($fichero=$directorio->read()){
//Mientras siga pudiendo leer.
//Siempre que el fichero no sea ni "." ni ".."
if ($fichero!='.' && $fichero!='..'){
//trabajo con el fichero
}
}
Para leer el fichero en bloques de 8kb (más seguro que leerlo de una vez):
$file=fopen(RUTA_FICHERO);
if ($file!=0){
//No ha dado error.
//Escribo el contenido.
$contenido = '';
while (!feof($file)) {
$contenido .= fread($file, 8192);
}
//Hago lo que tenga que hacer con el contenido del fichero.
fclose($file);
viernes, 27 de febrero de 2009
martes, 24 de febrero de 2009
Interfaces en PHP 5
La siguiente es la estructura de un interface común:
interface BeingDamage{
public function processDamage($weapon);
public function damageHealth($damage);
}
El interfaz se implementaría de la siguiente manera:
class character implements BeingDamage{
function processDamage($weapon){
//implementación
}
function damageHealth($damage){
//implementación
}
}
Es importante recordar que la reutilización de clases y métodos sugiere que conviene programar a interfaces, no a implementaciones.
interface BeingDamage{
public function processDamage($weapon);
public function damageHealth($damage);
}
El interfaz se implementaría de la siguiente manera:
class character implements BeingDamage{
function processDamage($weapon){
//implementación
}
function damageHealth($damage){
//implementación
}
}
Es importante recordar que la reutilización de clases y métodos sugiere que conviene programar a interfaces, no a implementaciones.
miércoles, 18 de febrero de 2009
Solucionar compatibilidades entre navegadores en CSS
Para evitar problemas de compatibilidades entre diferentes navegadores, sobre todo en cuanto se usen listas, conviene añadir lo siguiente a la hoja de estilos CSS:
* { margin:0; padding:0; border: 0; }
* { margin:0; padding:0; border: 0; }
Etiquetas:
compatibilidad,
css,
programación web
martes, 17 de febrero de 2009
Extraer información de un archivo de texto formateado de cierta manera
Organizo valores constantes mediante archivos ini para poder modificarlos rápidamente y que afecten diferentes sitios. Uso la siguiente función:
function devuelveValorIni($claveIni,$archivoIni){
$datos=archivoTextoAString("/ini/" . $archivoIni);
//Queda separarlo en función de los delimitadores y del texto.
$textoConvertido="[" . $claveIni;
$valorIni=extraeUnidad($datos,$textoConvertido,"]");
return $valorIni;
}
function archivoTextoAString($archivo){
//Se busca en el archivo ini los hit die para esa clase especificada.
$directorioBase=parent_directory();
// read file into string
$data = file_get_contents($directorioBase . $archivo) or die("Could not read file!");
//Teniendo ya el archivo en un string, hago la búsqueda y separación.
return $data;
}
function parent_directory(){
return dirname(dirname(__FILE__));
}
Asumo la siguiente estructura:
[LIMITEMAPA:150]
Se establece que el primer límite donde empezar a buscar es '[LIMITEMAPA:' y el último es el cierre, ']'.
function devuelveValorIni($claveIni,$archivoIni){
$datos=archivoTextoAString("/ini/" . $archivoIni);
//Queda separarlo en función de los delimitadores y del texto.
$textoConvertido="[" . $claveIni;
$valorIni=extraeUnidad($datos,$textoConvertido,"]");
return $valorIni;
}
function archivoTextoAString($archivo){
//Se busca en el archivo ini los hit die para esa clase especificada.
$directorioBase=parent_directory();
// read file into string
$data = file_get_contents($directorioBase . $archivo) or die("Could not read file!");
//Teniendo ya el archivo en un string, hago la búsqueda y separación.
return $data;
}
function parent_directory(){
return dirname(dirname(__FILE__));
}
Asumo la siguiente estructura:
[LIMITEMAPA:150]
Se establece que el primer límite donde empezar a buscar es '[LIMITEMAPA:' y el último es el cierre, ']'.
Funciones JavaScript no definidas y Firebug
A menudo una página no funciona como debería y Firebug nos devuelve que una función de JavaScript está "not defined" o "undefined". Uno tiende a pensar que se debería a que no tiene acceso a la función y el tag script no ha funcionado bien por algún motivo, pero en realidad se suele deber a un error de sintaxis. Asegúrate de que el código javascript sea correcto. También suele pasar cuando desde un archivo .js llamas a funciones de otro (como librerías Prototype).
Etiquetas:
javascript,
programación web
Pasar un array de PHP a JavaScript mediante JSON
Por algún motivo, pasar arrays de PHP a JavaScript es más complicado de lo que debería ser. Por fortuna, para arreglar el asunto podemos traducir el array de PHP a JSON.
Cualquier servidor de PHP mayor que el 5 tiene la siguiente función:
$arrayAJS=json_encode($arrayEnPHP);
Nota muy importante: nada más pasar el array PHP a JSON y enviarlo como parámetro, la función javascript lo considera un array normal y corriente. No hace falta deserializarlo.
Cualquier servidor de PHP mayor que el 5 tiene la siguiente función:
$arrayAJS=json_encode($arrayEnPHP);
Nota muy importante: nada más pasar el array PHP a JSON y enviarlo como parámetro, la función javascript lo considera un array normal y corriente. No hace falta deserializarlo.
Etiquetas:
ajax,
javascript,
json,
php,
programación web
Estilo de menús horizontales en CSS usando ambos navegadores
Uno de los elementos específicos que siempre crea problemas de compatibilidad entre los dos navegadores principales, Firefox y IE, son los menús horizontales. Hay que jugar con la propiedad margin tanto de esa capa como la que le precede, intentando combinaciones de números positivos y negativos en ambos para acabar ajustando ambos. Por ejemplo:
#PaisesContenedorLogo{
width: 700px;
height: 132px;
background-color: #888888;
background: url("../img/logo.jpg");
background-repeat: no-repeat;
margin-bottom: 16px;
}
#PaisesContenedorMenu{
background-color: #95b48b;
color: #000000;
height: 30px;
margin-top: -16px;
}
En el caso expuesto, 'PaisesContenedorLogo' está situada por encima de 'PaisesContenedorMenu' y en la misma capa, pero, como se ve, los margin no parecen muy racionales.
#PaisesContenedorLogo{
width: 700px;
height: 132px;
background-color: #888888;
background: url("../img/logo.jpg");
background-repeat: no-repeat;
margin-bottom: 16px;
}
#PaisesContenedorMenu{
background-color: #95b48b;
color: #000000;
height: 30px;
margin-top: -16px;
}
En el caso expuesto, 'PaisesContenedorLogo' está situada por encima de 'PaisesContenedorMenu' y en la misma capa, pero, como se ve, los margin no parecen muy racionales.
Etiquetas:
compatibilidad,
css,
programación web
lunes, 16 de febrero de 2009
Crear un array unidimensional en JSON
No confundir con los arrays asociativos.
{
"arrayUnidimensional" : [0,0,2,3,0,1,0,5]
}
{
"arrayUnidimensional" : [0,0,2,3,0,1,0,5]
}
Crear Request Object para recibir JSON usando AJAX
Omito el lado del servidor, pero el archivo php debe generar un texto que respete la sintaxis.
var the_object;Es conveniente limpiar la cadena enviada por el servidor para evitar posibles inyecciones de código.
var http_request = new XMLHttpRequest();
http_request.open( "GET", url, true );
http_request.send(null);
http_request.onreadystatechange = function () {
if ( http_request.readyState == 4 ) {
if ( http_request.status == 200 ) {
var inputJSON=http_request.responseText;
var my_JSON_object = !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
text.replace(/"(\\.|[^"\\])*"/g, ''))) &&
eval('(' + inputJSON + ')');
} else {
alert( "There was a problem with the URL." );
}
http_request = null;
}
};
Función para crear un XML Request Object válido
function devuelveXMLRequestObject {
xmlhttp=false;
this.requestFile = file;
this.encodeURIString = true;
this.execute = false;
this.AjaxFailedAlert = "Funcionalidades no soportadas.";
if (window.XMLHttpRequest) {
this.xmlhttp = new XMLHttpRequest();
if (this.xmlhttp.overrideMimeType) {
this.xmlhttp.overrideMimeType('text/xml');
}
}
else if (window.ActiveXObject) {
//Internet Explorer
try {
this.xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}catch (e) {
try {
this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
this.xmlhttp = null;
}
}
if (!this.xmlhttp && typeof XMLHttpRequest!='undefined') {
this.xmlhttp = new XMLHttpRequest();
if (!this.xmlhttp){
this.failed = true;
}
}
}
return this.xmlhttp ;
}
Ejemplo de envío de datos mediante POST en AJAX
A pesar de la carga al servidor que implica, a menudo conviene enviar los parámetros para una operación mediante POST en vez de GET, ya que el GET escribe los parámetros en la url.
Para realizar una Request usando post, también debemos componer la lista de de parámetros como quedaría en la URL:
campo1=valor
$campo2=valor
Por ejemplo:
'campo1='+document.getElementById('campo1').value
+ '&campo2='+document.getElementById('campo2').value
Posteriormente, debemos enviar esos valores mediante la función send del objeto request.
ajax.open ('POST', url, true);
ajax.onreadystatechange=funcion;
ajax.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
ajax.send(valores);
El setRequestHeader es útil en caso de que el Content-Type se quiera cambiar a XML en vez de dejarlo por defecto en el fichero php al que se llame, por razones de prueba.
Para realizar una Request usando post, también debemos componer la lista de de parámetros como quedaría en la URL:
campo1=valor
$campo2=valor
Por ejemplo:
'campo1='+document.getElementById('campo1').value
+ '&campo2='+document.getElementById('campo2').value
Posteriormente, debemos enviar esos valores mediante la función send del objeto request.
ajax.open ('POST', url, true);
ajax.onreadystatechange=funcion;
ajax.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
ajax.send(valores);
El setRequestHeader es útil en caso de que el Content-Type se quiera cambiar a XML en vez de dejarlo por defecto en el fichero php al que se llame, por razones de prueba.
Etiquetas:
ajax,
javascript,
php,
programación web
Sumario de AJAX
Qué constituye el corazón de AJAX y la diferencia con la programación tradicional de páginas web:
1) El usuario visita la página
2) El usuario escribe algo en una caja de texto, pulsa un botón o arrastra algo con el cursor
3) Lo que el usuario haga en el punto 2 provoca que JavaScript envíe una petición al servidor
4) El servidor procesa la petición (usando PHP, por ejemplo), devolviendo algún dato
5) JavaScript recibe la información y la usa para actualizar la página, sin cargarla otra vez
1) El usuario visita la página
2) El usuario escribe algo en una caja de texto, pulsa un botón o arrastra algo con el cursor
3) Lo que el usuario haga en el punto 2 provoca que JavaScript envíe una petición al servidor
4) El servidor procesa la petición (usando PHP, por ejemplo), devolviendo algún dato
5) JavaScript recibe la información y la usa para actualizar la página, sin cargarla otra vez
sábado, 14 de febrero de 2009
Palabras reservadas que pueden crear conflicto con PEAR
De momento he encontrado las siguientes:
GROUP
INT
La solución más sencilla es añadir a los campos con ese nombre un guión bajo al final.
GROUP
INT
La solución más sencilla es añadir a los campos con ese nombre un guión bajo al final.
Error de sintaxis en MySQL usando PEAR
Con el siguiente código:
function executeCommand( $sql, $args )
{
global $db;
$sth = $db->prepare( $sql );
if (PEAR::isError($sth)) {
die($sth->getMessage());
}
echo "
$res=& $db->execute( $sth, $args );
if (PEAR::isError($res)) {
die($res->getMessage());
}
print_r($res);
return $res;
}
Si devuelve un error como éste: 'DB Error: syntax error', puede darse el caso de que alguno de los campos de la tabla se llamen igual que una palabra reservada. En mi caso había un campo llamado group, que obviamente entraba en conflicto con la palabra reservada GROUP. Es bueno tenerlo en cuenta cuando parece que las cosas no van sin motivo alguno.
function executeCommand( $sql, $args )
{
global $db;
$sth = $db->prepare( $sql );
if (PEAR::isError($sth)) {
die($sth->getMessage());
}
echo "
$sth de la sql $sql
";$res=& $db->execute( $sth, $args );
if (PEAR::isError($res)) {
die($res->getMessage());
}
print_r($res);
return $res;
}
Si devuelve un error como éste: 'DB Error: syntax error', puede darse el caso de que alguno de los campos de la tabla se llamen igual que una palabra reservada. En mi caso había un campo llamado group, que obviamente entraba en conflicto con la palabra reservada GROUP. Es bueno tenerlo en cuenta cuando parece que las cosas no van sin motivo alguno.
Referencia al último ID creado por una consulta INSERT en MySQL
last_insert_id[ ]
Con paréntesis, que en caso contrario molesta a los scripts del blog.
viernes, 13 de febrero de 2009
Tabulación simple con CSS
|span style='margin-left:20px;'>
Sustituir la barra vertical del comienzo por < .
Sustituir la barra vertical del comienzo por < .
lunes, 9 de febrero de 2009
Convertir archivo de texto plano a string y guardarlo en memoria
// set file to read
$filename = "mindspace.txt";// read file into string
$data = file_get_contents($filename) or die("Could not read file!");
Funciones para seleccionar datos usando PHP y MySQL
Estas funciones facilitan la extracción de datos de una base de datos MySQL usando PHP.
function conectar(){
//Conecta y devuelve la variable conexión.
$conn = mysql_connect("localhost", tu_usuario, tu_password);
mysql_select_db(tu_db);
return $conn;
}
function escribeSelectSQL($campos,$tablas,$condicion){
$consulta="SELECT ";
//añado tantos campos como me haya enviado.
$limiteCampos=count($campos);
$limiteTablas=count($tablas);
for($contador=1;$contador<=$limiteCampos;$contador+=1){
$consulta=$consulta . $campos[$contador-1];
if ($contador<$limiteCampos){
//todavía quedan campos, así que habrá que añadir una coma.
$consulta=$consulta . ", ";
}else{
//añado un espacio, por si acaso.
$consulta=$consulta . " ";
}
} //fin del for para los campos.
$consulta=$consulta . " FROM ";
for($contador=1;$contador<=$limiteTablas;$contador+=1){
$consulta=$consulta . $tablas[$contador-1];
if ($contador<$limiteTablas){
//todavía quedan campos, así que habrá que añadir una coma.
$consulta=$consulta . ", ";
}else{
//añado un espacio, por si acaso.
$consulta=$consulta . " ";
}
} //fin del for para las tablas.
//Queda añadir la cláusula WHERE y la condición.
$consulta=$consulta . " WHERE " . $condicion;
//echo ("
$sql = mysql_query($consulta);
return $sql;
}
function devuelveRegistros($sql){
//pasada una SQL válida de selección, devolvemos los registros.
return mysql_fetch_array($sql);
}
function cierraConexion($conn){
mysql_close($conn);
}
function conectar(){
//Conecta y devuelve la variable conexión.
$conn = mysql_connect("localhost", tu_usuario, tu_password);
mysql_select_db(tu_db);
return $conn;
}
function escribeSelectSQL($campos,$tablas,$condicion){
$consulta="SELECT ";
//añado tantos campos como me haya enviado.
$limiteCampos=count($campos);
$limiteTablas=count($tablas);
for($contador=1;$contador<=$limiteCampos;$contador+=1){
$consulta=$consulta . $campos[$contador-1];
if ($contador<$limiteCampos){
//todavía quedan campos, así que habrá que añadir una coma.
$consulta=$consulta . ", ";
}else{
//añado un espacio, por si acaso.
$consulta=$consulta . " ";
}
} //fin del for para los campos.
$consulta=$consulta . " FROM ";
for($contador=1;$contador<=$limiteTablas;$contador+=1){
$consulta=$consulta . $tablas[$contador-1];
if ($contador<$limiteTablas){
//todavía quedan campos, así que habrá que añadir una coma.
$consulta=$consulta . ", ";
}else{
//añado un espacio, por si acaso.
$consulta=$consulta . " ";
}
} //fin del for para las tablas.
//Queda añadir la cláusula WHERE y la condición.
$consulta=$consulta . " WHERE " . $condicion;
//echo ("
DEBUG: la consulta formada es $consulta.
");$sql = mysql_query($consulta);
return $sql;
}
function devuelveRegistros($sql){
//pasada una SQL válida de selección, devolvemos los registros.
return mysql_fetch_array($sql);
}
function cierraConexion($conn){
mysql_close($conn);
}
Clase y números aleatorios en PHP
Digamos que queremos crear una clase en php para un juego de rol y pretendemos que sus abilidades se generen automáticamente, pudiendo valer de 8 a 18.
class cBeing{
var $IdBeing;
var $Nombre;
var $Apellidos;
var $Str;
var $Con;
var $Int;
var $Wis;
var $Cha;
function cBeing(){
//Constructor por defecto de Being.
$this->Str=12;
$this->Con=12;
$this->Int=12;
$this->Wis=12;
$this->Cha=12;
}
function rollAbilities(){
//Función que genera valores aleatorios para las cuatro abilidades principales.
$this->Str=devuelveAleatorio18();
$this->Con=devuelveAleatorio18();
$this->Int=devuelveAleatorio18();
$this->Wis=devuelveAleatorio18();
$this->Cha=devuelveAleatorio18();
}
function devuelveAleatorio18(){
$random = mt_rand(8,18);
return $random;
}
}
class cBeing{
var $IdBeing;
var $Nombre;
var $Apellidos;
var $Str;
var $Con;
var $Int;
var $Wis;
var $Cha;
function cBeing(){
//Constructor por defecto de Being.
$this->Str=12;
$this->Con=12;
$this->Int=12;
$this->Wis=12;
$this->Cha=12;
}
function rollAbilities(){
//Función que genera valores aleatorios para las cuatro abilidades principales.
$this->Str=devuelveAleatorio18();
$this->Con=devuelveAleatorio18();
$this->Int=devuelveAleatorio18();
$this->Wis=devuelveAleatorio18();
$this->Cha=devuelveAleatorio18();
}
function devuelveAleatorio18(){
$random = mt_rand(8,18);
return $random;
}
}
Suscribirse a:
Entradas (Atom)