La cuestión normalmente suele ser la contraria: “Quiero que en mi blog salgan feeds de RSS externos”, pero aquí lo que trataremos es el caso contrario:
¿Cómo parseo un feed de un site creado en WordPress en mi página PHP?

Lo primero que cualquier programador piensa es “menuda chorrada, usas SimpleXmlElement o DOMDocument y arreando”. Sí, pero no.
Veamos, lo normal cuando usas estas 2 clases es  algo así:


<?php
$xml = file_get_contents("http://www.lawebquemeinteresa.com/?feed=rss2");
$domd = new DOMDocument('1.0', 'utf-8');
$domd->loadXML($xml);
print_r($domd);

?>

o


<?php

$file = file_get_contents("http://www.lawebquemeinteresa.com/?feed=rss2");
$xml=SimpleXmlElement($file);
print_r($xml);

?>

Bueno, pues si hacemos esto la mayoría de urls de feeds generados por WordPress nos devolverán algo tan feo como esto:

PHP Warning:  DOMDocument::load() [<a href='domdocument.load'>domdocument.load</a>]: I/O warning : failed to load external entity &quot;http://www.lawebquemeinteresa.com/?feed=rss2&quot; in **************/feedtrss.php on line **

o

PHP Warning:  simplexml_load_file() [<a href='function.simplexml-load-file'>function.simplexml-load-file</a>]: I/O warning : failed to load external entity

La razón es que generalmente la URL del feed no es apunta a un archivo real sino una redirección “seo-friendly”, y entonces el file_get_contents no recibe las cabeceras, se lía y el script pega un petardazo.
Entonces ¿como podemos solucionarlo? La solución es el famoso cURL de PHP
Si el método del file_get_contents no os funciona tendreis que emplear esta librería, que es mucho más flexible con los encabezados, redirecciones dinámicas y demás jaranas.
Por ejemplo utilizar el SimpleXMLElement mediante cURL vendría a ser algo como esto:


<?

$curl= curl_init("http://www.lawebquemeinteresa.com/?feed=rss2") or die("Este servidor no soporta cURL!!!!");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, 0);
$feed = curl_exec($curl);
curl_close($curl);
$xml= new SimpleXmlElement($feed, LIBXML_NOCDATA);
print_r($xml);

?>

Y así debería parsearos e imprimiros en pantalla el objeto $xml sin mayor problema. Ah! Ojo que no todos los hostings tienen la librería cURL instalada

Y como este es un post muy útil pero muy aburrido:

Tags: ,

Posted by Cesar - 30/03/12 - 0 comments

 

A veces tenemos que hacer llamadas desde flash a archivos externos en un servidor y esto es un solor de cabeza a la hora de depurar. Si estos archivos son estáticos y  no hay problema, pero ¿ que pasa cuando tienes que hacer pruebas atacando a archivos php o asp en un servidor local y luego cambiar dicho servidor?
Habría que modificar todas las rutas de absoluta a relativa  cada vez que quieras testear en el server local, y eso es un tostón y pérdida de tiempo importante .


Pero hay una forma fácil de conseguir que cuando estemos testeando con el IDE de Flash (o Flash Develop o el que sea): la propiedad playerType de la clase flash.system.Capabilities. Esta propiedad puede devolvernos:

  • StandAlone, si se está reproducciendo en un reproductor ejecutable.
  • External, si se reproduce desde el IDE o desde el reproductor de flash del sistema.
  • PlugIn, si se trata de un plugin de navegador.
  • ActiveX, si se ejecuta mediante el control Active X de Internet Explorer

Vamos a poner un ejemplo, yo tengo que hacer una llamada absoluta dentro del entorno de mi programa de desarrollo para que los phps que pido me funcionen, pero cuando lo suba y pruebe desde navegador quiero que la llamada sea relativa a donde esté alojado.

La idea es declarar antes de la llamada una variable de host, que variará dependiendo de si el flash se reproduce desde el entorno de pruebas  o no

Por ejemplo:

var host:String;
if(Capabilities.playerType == "External"){
		host="http://localhost/mipagina/";
	}else{
		host="";
	}
var request:URLRequest=new URLRequest(host+"datos.php");

De esta forma no tendremos que andar cambiando las llamadas cada 2 por 3, que hacerlo en un archivo es facil, pero en un sitio completo en flash con varios .swf  puede ser un suplicio

Tags: , ,

Posted by Cesar - 31/05/11 - 0 comments

 

A veces tenemos que generar listados de datos almacenados en un servidor sql en un formato que sea importable a algún software del tipo Excel o similares.
A partir de PHP 5.1 disponemos de la función putcsv, que nos falicita esta tarea, pero ¿qué pasa si nuestro servidor corre con un PHP 4 o 5.0?
Esto me ha ocurrido hace unos minutos, he tenido que dar un par de vueltas para generar dicho archivo y que sea descargable y no se imprima directamente en el navegador.
La solución es sencilla

header("Cache-Control: public"); 

header('Content-Type: text/csv; charset=utf-8');
 // definimos el tipo MIME y la codificación 

header('Content-Disposition: attachment; filename=Usuarios.csv');
// Forzamos que el archivo se descargue con un nombre definido 

mysql_connect("localhost","*****","****");
//conectamos con la base datos 

mysql_select_db("*****"); // etc,etc
$query="SELECT email,name,surnames,id FROM  usuarios order by surnames";
$q=mysql_query($query) or die("Error de consulta");
 //consultamos la BBDD 

echo "email;nombre;apellidos;clave\n";
//primera fila del CSV 

while($r=mysql_fetch_array($q)){

 echo $r['email'].";".$r['name'].";".$r['surnames'].";".$r['key']."\n";
//imprimimos la línea de datos separada por ";" o lo que se tercie 

 }

Tan simple como eso, acordaros de saltar las línea con \n , o el archivo aparecerá en una sola línea

Tags: , ,

Posted by Cesar - 12/05/11 - 0 comments

 

Hoy he me he embarcado en un interesante proyecto donde tendré que volver a mi plataforma favorita: Flash, y además con bastante libertad creativa, ya que tengo que desarrollar un microsite de minijuegos basados en dibujos animados con estética futurista, lo cual hace que mi cabeza gire a miles de revoluciones pensando en efectos de luz, movimiento, físicas , etc… las típicas cosas que te encanta hacer y jugar con ellas, trasteas y te empollas cientos de páginas sobre experimentos, pero que luego nunca vas a usar en un proyecto real… o sí!

Hoy he empezado por recordar todo lo referente a partículas, bitmapdata y este tipo de cosas con las que hacía meses…o años… que no lidiaba.
El primer experimento ha sido crear una transición de imágenes en las que estas explotan en píxeles. No voy a colgar la demo aún ya que aunque la explosión va fluidísima (incluso con imágenes grandes) la implosión ya no va tan bien, por lo que tengo que darle más vueltas.
De todas formas lo que me importaba era generar una clase de explosión de enemigos para un shoot’em up….

Y el segundo ha sido un efecto de partículas de luz para la esfera de energía de la homepage.
Sinceramente no tengo demasiado tiempo, pero tampoco me gusta utilizar código de otros si lo que quiero hacer entra dentro de mis posibilidades, por lo que este ha sido el resultado rápido y resultón:

This movie requires Flash Player 9

El código de la class es el siguiente, hecho bastante rápido, pero con un rendimiento bastante bueno, al menos en mi máquina.
Si la cosa se ralentiza siempre se pueden modificar el número de partículas (he puesto 5000, a lo bravo) o reducir el desenfoque del BlutFilter.


package xcx{
import flash.display.*;
import flash.events.*;
import flash.utils.*;
import flash.filters.GlowFilter;
import flash.filters.BlurFilter;
public class BMPEnergy extends MovieClip {
var bmp:Bitmap;
var bmpdata:BitmapData;
var main:MovieClip;
var particulas:Array=[];
var numparts:Number=5000;
var velocidad:Number=.6;
var maxvida:int=50;
var r:uint;
var g:uint;
var b:uint;
var a:uint;
var c:uint;
var glow:GlowFilter;
var blur:BlurFilter;
var limiteanillo:Array=[100,90];


function randomNumber(low:Number=0, high:Number=1):Number {
return Math.floor(Math.random() * (1+high-low)) + low;
}


function anima() {
for (var p:int=0; p
if (particulas[p].vida
particulas[p].x+=Math.sin(particulas[p].rot)+particulas[p].velx;
particulas[p].y+=Math.cos(particulas[p].rot)+particulas[p].vely;
particulas[p].vida++;
} else {
particulas[p].x=particulas[p].x0;
particulas[p].y=particulas[p].y0;
particulas[p].vida=0;
particulas[p].rot+=randomNumber(-1,1)
}
}
dibuja();
}


function dibuja() {
bmpdata.lock();
bmpdata.fillRect(bmpdata.rect, 0);
for (var i:int=0; i
bmpdata.setPixel32(particulas[i].x, particulas[i].y, particulas[i].color);
}
bmpdata.unlock();
}


public function init() {
bmpdata=new BitmapData(500,500,true);
bmpdata.fillRect(bmpdata.rect, 0);
for (var i:int=0; i
//color: 83d547
r=0x83;
g=0xD5;
b=0x47;
a=(Math.random())*0xFF;
c=((a << 24) | (r << 16) | (g << 8 ) | b); var p:Object={color:c,x:(Math.sin(i)*limiteanillo[0]/2)+limiteanillo[0],y:(Math.cos(i)*limiteanillo[1]/2)+limiteanillo[1],x0:(Math.sin(i)*limiteanillo[0]/2)+limiteanillo[0],y0:(Math.cos(i)*limiteanillo[1]/2)+limiteanillo[1],rot:i,muerte:randomNumber(maxvida)+5,vida:0}; if (Math.cos(i)>0) {
p.vely=randomNumber(1,velocidad);
} else {
p.vely=randomNumber(- velocidad,-1);
}
if (Math.sin(i)>0) {
p.velx=randomNumber(1,velocidad);
} else {
p.velx=randomNumber(- velocidad,-1);
}
particulas.push(p);
}
dibuja();
bmp=new Bitmap(bmpdata);
addChild(bmp);
setInterval(anima,40);
}


public function BMPEnergy() {
init();
glow=new GlowFilter(0x65af2f,2,6,6,2)
blur=new BlurFilter(1.6,1.6,2)
this.filters=[blur,glow]
}
}
}

Tags: , ,

Posted by Cesar - 07/02/11 - 2 comments

 

La verdad es que poca gente de la que conozco que se dedica a desarrollar en flash conoce la existencia o se ha interesado en indagar en las posibilidades de JSFL (JavaScript Flash) y la cantidad de tiempo que puede ahorrarnos.
En general es debido a que el JSFL es más útil para personas que utilizan más la interfaz gráfica del programa que no a los que se dedican a programar todo en Classes.
Os voy a mostrar 2 scripts que a mí me ayudan bastante, sobretodo cuando tengo que generar banners y cosas así, que requieren de la utilización de muchos objetos (assets) y tiene que ser una cosa rápida.
Por ejemplo: Imagínaos que tengo un montón de símbolos en la librería que he de mover al escenario, y controlarlos mediante actionscript. Habría que ir dando un nombre a cada instancia, y eso se hace pesado, sobretodo porque seguramente ese nombre sea casi igual al del símbolo.
La solución en este caso es crear un archivo .jsfl (con cualquier editor de texto) con este script:

for(i in fl.getDocumentDOM().selection){
var libname=fl.getDocumentDOM().selection[i].libraryItem.name
fl.getDocumentDOM().selection[i].name =libname.toLowerCase();
fl.getDocumentDOM().selection[i].name =
fl.getDocumentDOM().selection[i].name .replace(/\s/g,"") ;
fl.trace("Instancia de "+libname+" renombrada como :"+
fl.getDocumentDOM().selection[i].name); }

Y una vez ejecutadp automáticamente todos los movieclips anónimos tendrán un nombre de instancia

Quizás esto se quede corto y lo que necesitemos sea importar un montón de objetos al escenario y convertirlos todos en movieclips. Para ello he creado este otro script que va seleccionando cada objeto del escenario y pidiendo un nombre para convertirlo en MovieClip,guardarlo en librería y renombrar la instancia como en el ejemplo anterior. Bastante más cómodo que andar dándole al F8, añadir nombre, y cambiar el nombre de instancia a mano.

var elementos= fl.getDocumentDOM().getTimeline().layers[0].frames[0].elements ;
for(i in elementos ){
fl.getDocumentDOM().selectNone();
elementos[i].selected = true;
if(typeof(fl.getDocumentDOM().selection[0].libraryItem)=="object"){
var simbolo = prompt("Escribe un nombre de símbolo para la selección");
if(simbolo==null){break;}
simbolo=simbolo.charAt(0).toUpperCase() + simbolo.slice(1);
var Movieclip = fl.getDocumentDOM().convertToSymbol("movie clip", simbolo, "top left");
fl.trace("Nuevo MovieClipcreado:" +simbolo);
fl.getDocumentDOM().selection[0].name =
fl.getDocumentDOM().selection[0].libraryItem.name.toLowerCase();
fl.getDocumentDOM().selection[0].name =
fl.getDocumentDOM().selection[0].name.replace(/\s/g,"_") ;
fl.trace("Instancia de "+ fl.getDocumentDOM().selection[0].libraryItem.name
+ " renombrada como :"+fl.getDocumentDOM().selection[0].name);
}
}

Una de los mayores problemas que encontramos es a la hora de guardar los archivos .jsfl de forma que aparezcan en el menú Comandos de la UI de Flash y no tener que llamar a mano al script mediante “ejecutar comando”. Lo “lógico” sería guardarlo en C:\Program Files\Adobe\Adobe Flash CS4\es\First Run\Classes (o algo parecido dependiendo del sistema operativo), pero no es así, en Vista/W7 la carpeta de comandos almacenados es C:\Users\usuario\AppData\Local\Adobe\Flash CS4\idioma\Configuration\Commands



Tags: ,

Posted by Cesar - 28/01/11 - 1 comment