Funciones
Consumir WebServices JSon desde PHP
by P-los on Nov.14, 2009, under Funciones, Técnicas, Web
Hoy gracias a que estuve apoyando a un proyecto de unos amigos, les traigo un simple ejemplo de como consumir WebServices hechos con JSon desde PHP.
Para este ejemplo utilizaremos una búsqueda en Twitter, ya que cumple con estas características.
Primero tenemos que formar una dirección URL con la ubicación de nuestro WebService, que para nuestro caso sería:
$URL="http://search.twitter.com/search.json?q=" . $Busqueda;
donde $Busqueda es el término que vamos a buscar.
Primero vamos a abrir esta dirección como un archivo cualquiera y guardamos su contenido en una variable:
$archivo = fopen ($URL, "r");
$texto = fgets($archivo);
Ahora, aprovechamos una función de PHP 5.2.0 o superior, llamada json_decode() que nos regresa un objeto con el contenido del JSon, cuyas propiedades son los valores entregados por el WebService, y podremos mostrar su contenido:
$json = json_decode($texto);
echo "max_id=".$json->max_id;
echo "next_page=".$json->next_page;
Para este caso particular, Twitter nos entrega un arreglo con los resultados, que facilmente podemos meter en un foreach:
foreach($json->results as $valor)
{
echo "<img src='".$valor->profile_image_url."' style='width:60px;height:60px;' /><br />";
echo "<h1>".$valor->from_user."</h1><br />";
echo $valor->text."<br />";
}
y así de facil tenemos un cliente que muestra los resultados de busqueda en twitter desde PHP.
Widgets con PHP
by P-los on Sep.01, 2009, under Funciones, Técnicas
En este post voy a exponer un método para crear widgets. Como mencionaba al principio de este blog, parte de mi objetivo al escribir aqui es obtener retroalimentación de su parte con tal de que todos mejoremos en los desarrollos que hacemos.
Lo que estoy haciendo con esto utiliza una base de datos para gestionar que widgets estan disponibles, que paneles tenemos disponibles para mostrarlos y los parámetros que se utilizarán para cada instancia de los widgets. Las tablas tienen la siguiente estructura:
Widgets: Aqui se almacenan los widgets que tenemos disponibles
- IdWidget – Int – PK – Identificador del widget
- Nombre – varchar(30) – Nombre del Widget
- Archivo – varchar(30) – Nombre del archivo que contiene el widget. Incluir la extensión del archivo
- Clase – varchar(30) – Nombre de la clase que representará el widget. Se separa del nombre del archivo para el caso de que haya 2 o más widgets dentro de un mismo archivo de PHP
Paneles: Representa cada una de las zonas capaz de mostrar los widgets, por ejemplo, las columnas derecha e izquierda, un bloque al pie de la página, etc.
- IdPanel – Int – PK – Identificador del panel
- Nombre – varchar(30) – Nombre que tiene el panel
PanelWidget: Indica que widgets se muestran en cada panel
- IdPanelWidget – Int – PK – Identifica a cada uno de los widgets que se mostrarán
- IdPanel – Int – Id del panel al que se hace referencia
- IdWidget – Int – Id del tipo de widget que se utilizará
- Orden – Int – Indica el orden en que se mostrarán los widgets
ParametrosWidget: En caso de que los widgets que tengamos requieran algún tipo de parámetro, aqui es donde se almacenarán
- IdParametro – Int – PK – Identificador del parámetro
- IdPanelWidget – Int – Identifica la instancia del widget para el que se aplicará este parámetro
- NombreParametro – varchar(30) – El nombre del parámetro
- Valor – varchar(100) – El valor del parámetro
En todas estas tablas es posible agregar campos según sean requeridos para nuestra aplicación.
Ya estando en nuestra aplicación de PHP, crearemos una clase abstracta que nos servirá de molde para crear nuestros widgets que estará en un archivo llamado “absWidget.php”:
<?php
abstract class absWidget {
public $params;
public $idPanelWidget = 0;
function ObtenerParametros(){
global $mySql;
$this->params = new ArrayObject();
if($this->idPanelWidget!=0)
{
$res=$mySql->consulta("select NombreParametro, Valor from ParametrosWidget where IdPanelWidget= ".$this->idPanelWidget);
while($arr=$mySql->fetch_assoc($res)){
$this->params[$arr['NombreParametro']]=$arr['Valor'];
}
}
}
abstract function MostrarWidget();
}
?>
En esta clase se está utilizando una variable global llamada $mySql, esta es la clase para conextarse a MySql que expuse tiempo atras, y se crea desde antes, ya sea en el index, o donde se instancía el framework que estemos utilizando / creando).
A continuación sigue la creación del widget propiamente dicho. Como podran imaginarse, ésta hereda de la clase abstracta absWidget. He aquí un ejemplo sencillo:
<?php
require_once ('Framework/modulos/absModulos.php');
class modBuscar extends absModulos {
function MostrarModulo() {
?>
<h1>Buscar</h1>
<form id="modBusqueda" method="get" action="index.php" >
Buscar:<br />
<input type="text" name="busqueda" /><br />
<input type="submit" value="Buscar" />
</form>
<?php
}
}
?>
Este ejemplo lo que hace es solicitar una búsqueda. Ya depende de cada aplicación que se esté haciendo si se utiliza el método POST o el método GET para procesar la llamada al servidor, así como el nombre de las variables. Estos temas no son materia del presente post, así que no los tocaré por el momento.
Lo único que hacemos es crear una función que implemente a MostrarWidget() y lo que hace es, como su nombre lo indica, mostrar el widget que se está creando. Si recuerdan, cada ocasión que se muestra un widget puede tener diferentes parámetros. Para obtener estos parámetros de la base de datos, hay que hacer una llamada a $this->ObtenerParametros(). Una vez hecho esto, los parámetros los tendremos en el array asociativo $this->params[] y podremos utilizarlo a nuestro gusto.
Por último, nos queda llamar desde nuestra plantilla cada uno de los páneles que queremos. Para esto, he aquí una funcion (mal hecho, pero yo la tengo como una función global o estatica) para buscar en la base de datos cuales son los widgets que se mostraran en un panel y mostrarlos:
function MostrarPanel($nombrePanel)
{
global $mySql;
//Obtener los modulos correspondientes a este panel
$res=$mySql->consulta("SELECT idPanelWidget, archivo, clase
FROM paneles
INNER JOIN panelWidget ON paneles.idpanel = panelWidget.idpanel
inner join Widgets on panelWidget.idWidget = Widgets.idWidget
where descripcion = '$nombrePanel'
order by orden");
while($arr=$mySql->fetch_assoc($res))
{
//Instanciar las clases adecuadas
require_once("Framework/Widgets/".$arr['archivo']);
$widget = new $arr['clase']();
$widget->idPanelWidget = $arr['idPanelWidget'];
//Mostrar el contenido del módulo
$modulo->MostrarWidget();
}
}
Una vez teniendo esta, ya podemos llamarla mandandole como parámetro el nombre del panel que vamos a mostrar, por ejemplo:
MostrarPanel('IZQUIERDO');
Esto ya pudiera ser dentro de nuestra plantilla.
Lo único que quedaría pendiente, y lo dejo para cada quien, es un pequeño panel de control para administrar que widgets mostrar en cada panel, en que orden mostrarlos, y que parametros utilizará cada uno de ellos.
[VB.Net] Exportar DataSet a Excel
by P-los on Aug.30, 2009, under Funciones
Recientemente me solicitaron para un proyecto que los reportes se mandaran directamente a Excel. He aquí una pequeña función capaz de exportar cualquier DataSet a un archivo de Excel:
Public Sub ExportarArchivo(ByVal archivo As String, ByVal datos As DataSet)
Dim xl As New Microsoft.Office.Interop.Excel.ApplicationClass
Dim wBook As Microsoft.Office.Interop.Excel.Workbook
Dim wSheet As Microsoft.Office.Interop.Excel.Worksheet
wBook = xl.Workbooks.Add
wSheet = wBook.ActiveSheet
Dim colIndex As Integer = 0
Dim rowIndex As Integer = 0
For Each dc As System.Data.DataColumn In datos.Tables(0).Columns
colIndex = colIndex + 1
xl.Cells(1, colIndex) = dc.ColumnName
Next
For Each dr In datos.Tables(0).Rows
rowIndex = rowIndex + 1
colIndex = 0
For Each dc In datos.Tables(0).Columns
colIndex = colIndex + 1
xl.Cells(rowIndex + 1, colIndex) = dr(dc.ColumnName)
Next
Next
wSheet.Columns.AutoFit()
Dim blnFileOpen As Boolean = False
Try
Dim fileTemp As System.IO.FileStream = System.IO.File.OpenWrite(archivo)
fileTemp.Close()
Catch ex As Exception
blnFileOpen = False
End Try
If System.IO.File.Exists(archivo) Then
System.IO.File.Delete(archivo)
End If
wBook.SaveAs(archivo)
xl.Workbooks.Open(archivo)
xl.Visible = True
End Sub
Para que no cause errores, hay que agregar como referencia la siguiente:
Microsoft.Office.Interop.Excel
Espero les sea tan util como a mi!
Objetos dinámicos con PHP
by P-los on Jul.08, 2009, under Funciones, Técnicas
Con php utilizando OOP, existe una forma sencilla para utilizar la herencia y polimorfismo. La idea es instanciar un objeto teniendo el nombre de la clase en un string, ya sea constante o una variable. La forma típica de hacer esto (o al menos la unica que yo conocía) era la siguiente:
$objeto = new clase();
Si lo que queríamos es instanciar diferentes clases heredadas de una misma, o que implementen una interfase, lo que hacía era un switch para definir cual utilizar:
switch(condicion){
case 1: $objeto = new clase1(); break;
case 2: $objeto = new clase2(); break;
}
Sin embargo, despues de buscar mucho por internet, me encontré con que es posible instanciar un objeto en base a un string, esto es:
$objeto = new "clase1"();
Una vez que comprobé esto, probé con éxito el utilizar una variable para el mismo fin:
$objeto = new $nombreClase();
¿Para que puede servir esto? Estoy trabajando en un sistema para mostrar widgets, los cuales se cargan en base a la información guardada en una base de datos, con la intensión de facilitar la inclusión y administración de los mismos. El cómo lo pondré más adelante en un nuevo post, pero basicamente es lo siguiente:
<?php
function Mostrar($nombre){
require_once($nombre.".php");
$objeto=new $nombre();
$objeto->MostrarWidget();
}
?>
De esta manera, la función recibe el nombre de la clase que se desea mostrar, incluye el archivo correspondiente (suponiendo que la clase está en un archivo con el mismo nombre) y llama a una función específica.
[VB.Net] Obtener una imagen desde Web
by P-los on May.16, 2009, under Funciones, Web
Ahorita solo por gusto estoy haciendo un scrren saver que obtiene imagenes desde Internet. Para ello, modifiqué un poco una función encontrada aqui para que al darle a la función la dirección URL de la imagen que deseamos, nos regrese un objeto de tipo Image para hacer con ella lo que necesitemos:
Public Function LoadWebImage(ByVal ImageURL As String) As Image
Dim objImage As IO.MemoryStream
Dim objwebClient As System.Net.WebClient
Dim sURL As String = Trim(ImageURL)
Dim img As Image = Nothing
Try
If Not sURL.ToLower().StartsWith("http://") Then sURL = "http://" & sURL
objwebClient = New Net.WebClient()
objImage = New IO.MemoryStream(objwebClient.DownloadData(sURL))
img = Image.FromStream(objImage)
Catch ex As Exception
'Cargar una imagen que indique que no se pudo leer la imagen de Internet
img = new Bitmap("noimage.jpg")
End Try
Return img
End Function
Función Anti-Sql-Injection
by P-los on Apr.09, 2009, under Funciones, Web
He aquí una función en PHP para prevenir la inyección de código SQL desde los formularios Web:
function limpiar_sql($value){
$value = trim(htmlentities($value)); // Evita introducción código HTML
if (get_magic_quotes_gpc())
$value = stripslashes($value);
$value = mysql_real_escape_string($value);
return $value;
}
Aquí hay una explicación de lo que es esta vulnerabilidad: http://es.wikipedia.org/wiki/SQL_injection
Clase para conectar php con mysql
by P-los on Apr.09, 2009, under Funciones, Web
En estos dias libres de semana santa, me estoy dedicando a realizar un sistema de pre-registro de asistentes a un evento, y por costumbre inicié haciendo desde cero el código de conexion a una base de datos MySql, pero recordé algo:
“La gran mayoría de lo que necesitas, alguien más ya lo hizo”
Así que me puse a buscar un poco, y me encontré con el siguiente bloque de código en WebTutoriales:
Archivo mysql.php:
<?php class MySQL{
private $conexion;
private $total_consultas;
public function MySQL(){
if(!isset($this->conexion)){
$this->conexion = (mysql_connect("Servidor","usuario","password")) or die(mysql_error());
mysql_select_db("nombreBD",$this->conexion) or die(mysql_error());
}
}
public function consulta($consulta){
$this->total_consultas++;
$resultado = mysql_query($consulta,$this->conexion);
if(!$resultado){
echo 'MySQL Error: ' . mysql_error();
exit;
}
return $resultado;
}
public function fetch_array($consulta){
return mysql_fetch_array($consulta);
}
public function num_rows($consulta){
return mysql_num_rows($consulta);
}
public function getTotalConsultas(){
return $this->total_consultas;
}
}?>
Y para hacer uso de ella, el siguiente ejemplo:
include("mysql.php");
$db = new MySQL();
$consulta = $db->consulta("SELECT id FROM mitabla1");
if($db->num_rows($consulta)>0){
while($resultados = $db->fetch_array($consulta)){
echo "ID: ".$resultados['id']."<br />";
}
}
Para hacerlo un poco más flexible, añadí en un archivo de configuración los parámetros de conexión a la base de datos, quedando de la siguiente manera:
archivo de configuración:
$reg_server = "localhost";
$reg_user = "root";
$reg_password = "";
$reg_database = "tests";
Archivo mysql.php (solo cambia esta función, el resto permanece igual):
public function MySQL(){
require_once("reg_params.php");
if(!isset($this->conexion)){
$this->conexion = (mysql_connect($reg_server,$reg_user,$reg_password)) or die(mysql_error());
mysql_select_db($reg_database,$this->conexion) or die(mysql_error());
}
}
Según la pagina original, está hecho para trabajar bajo PHP 5, así que si lo vas a utilizar en una versión anterior de php, posiblemente te encuentres con que habrá algunas correcciones que hacer.
Hash MD5
by P-los on Mar.11, 2009, under Funciones
Una de los métodos para almacenar contraseñas en una base de datos se basa en la encripción utilizando el Hash MD5.
Private Function GetMD5Hash(ByVal input as String) as String
Dim x As New System.Security.Cryptography.MD5CryptoServiceProvider()
Dim bs() as Byte = System.Text.Encoding.UTF8.GetBytes(input)
bs = x.computeHash(bs)
For Each b As Byte In bs
s.Append(b.ToString(”x2″).ToLower())
Next
Dim output as String = s.ToString()
Return output
End Function
Esta utilidad también es utilizada al momento de hacer transmisiones de datos, para hacer una comparación entre el mensaje enviado y el mensaje recibido para verificar que sean exactamente iguales. Si el Hash no coincide, significa que ocurrió un error en la transmisión.