Posts Tagged ‘PHP’

¿El fin de xAMP?

diciembre 11, 2013

Para no abandonar el vicio estoy haciendo algunas cositas en PHP.

Pero como adquirí vicios estoy tratando de evitar eso de mezclar lógica con renderizado de html. A lo que llegue fue a armar un html bien básico y jQuery y eventos mediante, circunscribo los pedidos al servidor en una capa javascript que gestiona los requests y renderiza el resultado de los response.

Del lado del servidor quedan unos scripts PHP muy sencillos que se concentran en ejecutar la lógica y devolverlos en un formato javascript friendly. Tan reemplazable con servlets + jaxb…

Hace poco compré un librito(sí… es vintage, pero no hay nada más lindo que recibir del correo tradicional el sobre marrón) de manning acerca de Single Page Web Applications. El libro tiene más o menos la misma arquitectura pero la variante que propone es node.js del lado del servidor reemplazando a PHP y jubilar a MySQL por la cada vez más ubicua MongoDB.

Es muy difícil en el mercado rioplatense vender una aplicación que confía sus datos a Mongo…DB, pero parece que las cosas van para ese lado.

¿será el fin de apache, MySQL y PHP?

Problemas con Charset y PHP

octubre 9, 2007

Los problemas de charset surgen de dos cuestiones:

  • Estoy abriendo una fuente utf-8 y mi salida se ve en iso-8859-1
  • o bien el opuesto: iso-8859-1 la fuente, salida utf-8

Vamos a “simular” que abrimos un archivo XML y tenemos problemas con el charset.

Primer caso

Diagnóstico: Por lo general el primer caso se da cuando veo en vez de eñes y acentos dos caracteres. Suelen ser un à y algo más. En el ejemplo el archivo XML estaría codificado en utf-8 (caso más común) y nuestra página se ve en iso-8859-1

Solución: La fuente está viniendo en utf8 y necesito pasarlo a Latin-1. Esto se hace con la función utf8_decode().

$origen = "http://algunblog/feed/";

//CURL mediante o file_get_contents
//En este caso hacemos la conversion de utf-8
//a iso-8859-1
$contenido = utf8_decode(file_get_contents($origen));

$xml = simplexml_load_string($contenido);
//"masajeamos" el contenido del XML

Segundo caso

Diagnóstico: En vez de caracteres especiales vemos unos signos de interrogación o cuadraditos con números. Esto significa que no puede traducir el caracter a alguno Unicode porque está “mal formado”.

Solución: Hay que convertir nuestra cadena a utf-8 mediante la función utf8_encode().

$origen = "http://algunblog/feed/";

//CURL mediante o file_get_contents
//En este caso hacemos la conversion de iso-8859-1
//a utf-8
$contenido = utf8_encode(file_get_contents($origen));

$xml = simplexml_load_string($contenido);
//"masajeamos" el contenido del XML

Estos son los dos casos básicos. Desde ya que esto tiene una explicación un poco más teórica, pero que vamos a abordar en otro post o tal vez le dediquemos una página. Por ahora con esto ya podemos solucionar muchos problemas.

Cuando trabajemos con bases de datos también tenemos que tener en cuenta estas consideraciones. Tenemos ventajas además, por lo general nos permite seleccionar el encoding de la conexión. El parámetro suele llamarse “charset”.

Mi intención es fundar la SALPICADA (Sociedad Argentina por la Lucha contra Problemas Indescifrables de Charset Accediendo a Datos y Archivos) para investigar el tema, capacitar y ofrecer ayuda. Evitemos que nuestras páginas terminen SALPICADAs por feos caracteres que hacen los textos menos legibles.

Cualquier duda, acá estoy.

Accediendo a XML con XPath y PHP5

septiembre 23, 2007

Bien, hasta ahora vimos como acceder al documento XML con PHP 5 accediendo a los nodos directamente e iterando colecciones.

Pero qué pasa si queremos acceder a un nodo en particular, sin tener que recorrer el documento.

Esto se puede hacer mediante XPath. XPath es un lenguaje de expresiones para acceder a partes de un documento XML. También permite hacer cálculos.

La base es considerar al documento como un arbol de directorios de unix donde cada nodo es un directorio. De esta manera si queremos acceder al título de un documento XHTML basta con consultar el elemento: “/html/head/title”. Si queremos acceder todas las entradas de un feed RSS. la consulta será a “entry”. Esto devolverá un array con todos los nodos de tipo entry donde cada elemento del array será un nodo.

También podemos acceder por los atributos. Supongamos que tenemos un documento XML en donde guardamos contactos. Cada nodo “contacto” tiene un atributo que se llama “tipo” y entre sus valores posibles están “Personales”, “Negocios”, etc. Si queremos listar todos los contactos de tipo “Personales”:

$xml = simplexml_load_file('contactos.xml');
$res = $xml->xpath("contacto[@tipo=Personales]");

foreach ($res as $contacto)
{
  //hacer algo con los contactos...
}

Es decir invocamos al método xpath de la clase SimpleXML pasándole por parámetro nuestra consulta XPath. Como queremos filtrar por atributos ponemos entre corchetes el atributo precedido por una @ e igualamos al valor que queremos filtrar. En el ej:[@tipo=Personales].

Esto es solo la punta del iceberg, ya que se pueden hacer cálculos, consultas complejas acceder a nodos relativos, por ejemplo, el nodo padre de los nodos que tengan cierto valor en cierto atributo.

Cualquier duda o comentario, pregunten. Saludos!

Leyendo xml con PHP 5

septiembre 12, 2007

Estoy necesitando parsear XML con PHP. La idea es ir armando una maqueta para un sitio que muestra artículos que obtiene de unos archivos XML.

Parsear XML en PHP4 era lento y poco práctico, razón por la cual siempre traté de evitarlo. Si hacía falta sacar algo de un archivo XML lo recorría como un archivo plano y extraía los datos con expresiones regulares.

Por otra parte entre las novedades PHP 5, el soporte para XML fue optimizado. Esto se basa en una nueva clase que envuelve la funcionalidad de una biblioteca que llama libxml: SimpleXML.

¿Por donde empezar?

La biblioteca es muy cómoda de utilizar. Acepta iteradores y permite acceder a los nodos hijos como atributos del nodo/objeto padre.


$archivo = 'entrada.xml';

//Caso 1: Directamente trayendo el archivo
$xml = simplexml_load_file($entrada);

$cadena = file_get_contents($entrada);

//Caso 2: Teniendo el contenido de texto
$xml = simplexml_load_string($cadena);

//Caso 3: O como instancia de la Clase SimpleXML
$xml = new SimpleXML($cadena);

En cualquiera de los 3 casos voy a tener un objeto $xml que representa al nodo raíz.

Supongamos que queremos mostrar links a los posts más recientes de un blog mediante feeds RSS. Mediante CURL o file_get_contents obtuvimos los datos en la variable $cadena.

$xml = new SimpleXML($cadena);

echo "Fuente :<a href=\\"".
$xml->channel->link ."\\">".
$xml->channel->title."</a>
\\n";

echo "
<ul>";
foreach ($xml->channel->item as $item)
{
echo "
	<li><a href=\\""
.$item->link ."\\">"
.$item->title."</a></li>
\\n";
}
echo "</ul>
";

Así de fácil podemos recorrer el RSS. Hay que tener encuenta que el objeto $xml es el elemento raíz de la cadena pasada (<rss> en este caso).

La próxima vez vamos a hablar de XPath, y de como acceder a los hijos y a los atributos del documento xml.

JsCalendar Helper para CakePHP

agosto 26, 2007

Necesitaba incluir el JsCalendar y me puse a buscar si estaba implementado el Helper, pero no. Lo más parecido era un controlador que se puede ver en este link.

No está nada mal, pero me resultaba un poco molesto tener que usarlo como controlador. Además el propio Pierpaolo invita a que lo mejoremos.

Yo decidí encararlo como Helper y que a la hora de imprimir el calendario en la vista sea lo más general posible.

El primer problema que se me presentó fue el de incluir los archivos .js y .css. Como estoy trabajando con 1.1.16.5421 necesitaba incluirlos en el layout. Googleando encontré que alguien ya había hecho algo para resolver este problema aquí. Hay que tocar el layout pero esto provee un Helper bastante bonito para lo que necesitaba.

Resuelto esto ya podía armar el Helper.

Tomé la clase PHP que viene con la distribución del JsCalendar. adapté el constructor al esquema de CakePHP. Desde el constructor se selecciona el look, el idioma, el directorio relativo a js, css e img de CakePHP. A su vez se setean otras opciones por defecto. Además tuve que agregar dos parámetros. Uno ‘align’=>”, porque con MSIE salía por cualquier lado. El otro es ‘width’=>’240px’ porque el ancho iba hasta el borde derecho de la pantalla.

El método de carga de los scripts fue modificado para trabajar con HeadHelper.

Por último modifiqué “make_input_field” para que funcione con un input, una image y un link del HtmlHelper. También valida que no se haya invocado el método de carga mediante una variable de instancia. Con eso ya tenía el calendario funcionando como un helper.

¿Cómo lo uso? Cargo el helper en el controlador con la variable $helpers.

<?php
echo $jsCalendar->make_input_field( 'Proyecto/inicio', #tagName del input
array(), #opciones del calendario(*)
array(
'name'=>'data[Proyecto][inicio]', #campo
'value'=>$html->tagValue('Proyecto/inicio' ) #valor inicial
); ?>

(*) se puede ver la documentación del jsCalendar.

No hace falta usar tantas líneas, la idea es usarlo como cualquier otro widget de Html.

Los scripts js del calendario se deben poner en webroot/js/calendar/. Los css en webroot/css/calendar/ y las imágenes en webroot/img/calendar/. En caso de usar Skins deben estar los archivos distribuidos en los directorios de los css y las imágenes.

Se puede descargar el helper con el esquema de directorios.

Bueno, espero que sea útil como me resultó a mí y si quieren mejorarlo, bienvenidos sean.

PHP 4 se discontinúa

agosto 5, 2007

Según el sitio de PHP la versión 4 se discontinúa a fin de año, después de más de 7 años de buen y leal servicio. Se seguirán haciendo fixes críticos hasta el 08/08/08.

Para empezar a ponerse en tema acá hay una guía de migración a la versión 5.

Por lo que pude ver de la versión 5, además del modelo de objetos mejorado, la inclusión de iteradores, SQLite, manejo de excepciones, trae mejoras en las funciones del tratamiento de strings y unicode. Si bien esto no se anuncia con bombos y platillos, es muy util para nosotros, que estamos fuera del charset ASCII.

Las aplicaciones que se ven más afectadas son aquellas que hacen uso del -tan vapuleado- modelo de objetos de PHP4. La ventaja es que el modelo actual es muy parecido al de java, permitiendonos aprovechar nuestra experiencia en el lenguaje de Sun. Sin embargo hay una directiva para mantener la compatibilidad con el modelo anterior.

Así las cosas, habrá que ponerse a actualizar y revisar lo programados.

Saludos!

Instalando CakePHP en public_html

agosto 3, 2007

Bueno, estoy haciendo una aplicación en CakePHP y quiero subirla a un sitio que tengo hosteado en Allytech. Como estoy teniendo problemas de configuración con ese servidor (¡no puedo acceder por SSH!) tuve que hacer mil piruetas (un script que hace el tar xvzf del archivo, después moverlos mediante el soft de control) hasta tener un orden de carpetas:

/
   /miapp               -> aplicación cake
   /cake                -> distribución cake
   /public_html         -> raíz del sitio

Según la documentación de CakePHP debía hacer los siguientes cambios en la versión 1.1.16.5421 (cambiando las cosas para mi estructura de carpetas):

//archivo: public_html/misitio/index.php
if (!defined('ROOT'))
{
define('ROOT', DS.'www'.DS.'doc'.DS.'miweb.com.ar');
}

if (!defined('APP_DIR'))
{
define ('APP_DIR', 'miapp');
}

if (!defined('CAKE_CORE_INCLUDE_PATH'))
{
define('CAKE_CORE_INCLUDE_PATH',
DS.'www'.DS.'doc'.DS.'miweb.com.ar'.DS.'cake');
}

Esto funcionaba, pero me mostraba un warning:

Warning: file_exists() [function.file-exists]: open_basedir restriction in effect. File(/www/docs/miweb.com.ar/lib//cake/libs/view/templates/errors/home.thtml) is not within the allowed path(s): (/www/docs/miweb.com.ar/) in /www/docs/miweb.com.ar/cake/cake/basics.php on line 1077

¡Me quiero volver chango!

Busqué en google y por errores similares recomendaban apagar los warning. Lujo que no me podía dar porque estaba en desarrollo.

El problema surgía de buscar en el directorio /www/docs/miweb.com.ar/lib/, que era el ‘include_path’ configurado por el hosting. Entonces me dije, saquemos eso y veamos qué pasa. ¡El warning desapareció!

Pero había que tocar el código, cosa que me parecía monstruosa. Además, ¿qué pasaba si yo usaba ese directorio para guardar bibliotecas de mi sitio?

Lo volví a poner, pero en otro orden. De vuelta el warning.

Me puse a hacer otra cosa y se me pasó el día. Después de unas horas vuelvo. Esta vez pruebo crear un directorio /www/docs/miweb.com.ar/lib/. ¡El warning ya no está más!

La moraleja es que si estamos instalando CakePHP y en “include_path” tenemos una ruta que no existe(en este caso la referenciamos “gracias” al hosting) mejor que la volemos porque vamos a tener ese bonito warning. Y si no la podemos volar, ya que yo no tengo acceso al php.ini, creemos el directorio y todos contentos.

Curioso lo sensible que se puede poner esto. Ahora voy a seguir con mi pequeña aplicación.

Gracias, vuelvan prontos

CakePHP: Bake y ACL

julio 7, 2007

Siguiendo con CakePHP me encontré con una serie de tutorials muy interesantes que se pueden seguir acá registrándote o bien por acá si no querés registrarte en otro sitio más. El último link es a un sitio llamado scribd que merece de por sí solo un post. De entrada podemos decir que se propone ser la biblioteca abierta de documentos más grande del mundo.

Habiendo corregido el tema de scaffold, pude seguir haciendo pruebas y cada vez me gusta más. Pero como bien indica la documentación, el scaffold (andamios) no son más que eso, andamios. Son una base para ir haciendo algo y después ir extendiendo uno y dándole a la aplicación el uso original para el que estaba diseñada. Sin embargo es un buen andamiaje para la obra.

Es posible “exportar” el código del sacffold mediante una herramienta de línea de comandos llamada Bake. Esta se encuentra en cake/scripts/bake.php. Se pueden exportar los modelos, las vistas y el controlador. De esta manera ya tenemos el esqueleto de la aplicación con su index (listado) y un abm. Ahí podemos modificar las views al estilo y funcionalidad que queramos. Hay que tener cuidado de no sobreescribir el trabajo que hayamos hecho en los controladores, por eso es recomenrable hacer primero esta exportación y después trabajar sobre los controladores particulares de nuestra aplicación.

Contento ya con esto, vi otra funcionalidad: las Access Control Lists (ACL o listas de control de acceso) que nos ofrecen un modelo de control de acceso a objetos. La idea es sencilla: por un lado tenemos objetos (usuarios y grupos de acceso) que quieren acceder a otros objetos(artículos, productos, cualquier cosa que queremos regular su acceso). A estos que quieren acceder se los llama ARO u Access Request Objects. Es posible también definir una estructura de arbol que nos permite crear grupos de acceso. A los objetos a los que se quiere acceder se los llama ACO u Access Control Objects. Con estas dos entidades podemos definir un sistema de control de acceso asociando los ARO con los ACO. Esta es una relación muchos a muchos y permite hasta agregar niveles de acceso a determinadas funciones (read, update, create y delete) .

Para el que siga el tutorial de IBM, con la versión 1.1.15.5144 tuve los siguientes problemas:

  • En el código del form de registro de usuarios el tutorial usa para verificar que se haya envíado el form un if y la condición es : (!empty($this->params[‘form’])) y también intenta grabar el objeto con $this->params[‘form’]. Eso no me anduvo. Reemplazando en todos los casos eso por $this->data la cosa sale como trompada de loco.
  • Cuando quise dar de alta los ARO con la herramienta de línea de comandophp acl.php create aro 1 null Users

    sale un error. Esto se corrige reemplazando el null por 0. No es lo más elegante pero funciona. Ya que no debería haber referencia a un item 0.

    php acl.php create aro 1 0 Users

Bueno, con esas dos salvedades, el tutorial es muy recomendable. Hasta la próxima.

CakePHP y django

julio 6, 2007

Estoy haciendo las primeras pruebas con CakePHP y viene bastante bien. Si bien muchas cosas ya las había visto en django, CakePHP no tiene nada que envidiarle.

Ambos son dos frameworks basados en MVC. Al parecer ambos muy parecidos a Rails, aunque todavía no he tenido el gusto de jugar con este.
MVC significa, muy por arriba, Modelo Vista Controlador. Si bien django se declara MTV, variante Modelo Template View, la idea es muy similar.

Ambos manejan Modelo como un ORM. Respecto al Modelo CakePHP se basa en extender una clase llamada AppModel que nos provee las funcionalidades CRUD. Esto es similar a los Models de django que heredan de models.Model. Lo más cómodo de CakePHP es que interpreta solo las tablas de la base de datos, si seguimos cierta nomenclatura. También me gusta más la manera que se definen las relaciones. Por otra parte, django tenía las factories de campos y generaba las tablas a partir de cómo había armado el “Modelo”. No digo que una cosa sea mejor que la otra, digo que me gusta más trabajar así.

Los controladores ya no tan son parecidos. Los controladores de django las “views” eran funciones que recibían el request y los parámetros. Para que estos views funcionaran había que asociarlos con una regla de rewrite (idénticas a las de Apache), requería definir a mano un dispatcher (siempre que no se usen genéricos). Estos retornaban un review e indicaban el template al que se asociaban. En CakePHP por cada modelo tengo que definir una clase que hereda de una clase AppController. Definiendo un método para esta clase ya tengo hecho el despacho. Estos métodos se llaman actions.

Las vistas son tal vez el punto más divergente. Es que django tiene su propio sistema de Templates (o Maquetación). Este era un poco extraño al principio, pero con un par de pruebas se terminaba manejando. CakePHP tiene un sistema de Templates que es medio un no-sistema de templates: son tags php los cuales utilizan variables y objetos que se le pasan desde el controlador. No es que en django no pase algo similar, sino que esto es casi como programar los templates en php. En esto me recuerda bastante a este artículo donde se charla acerca de la utilidad de los templates. Así que no hay nada raro en el sistema de templates, los tags y los foreach para iterar listas.

Lo que se extraña es el admin de django. Y estoy medio frustrado porque todavía no pude hacer andar los scaffolds (andamios). Al parecer son como los generics views de django.

Otra cosa que me gusta más de django es el concepto de aplicación bien esquematizado por directorios namespaces. Y de ahí vienen las ventajas de django de estar basado en python que es mucho más elegante como lenguaje orientado a objetos que php. CakePHP utiliza un árbol de directorios donde guardo las vistas en un directorio, los modelos en otro y los controladores en otro más. Si bien hay maneras de separar, esta todo apilado.

Pero irónicamente, la fortaleza de CakePHP es estar desarrollado en php. Y encima compatible con php4 y php5. No voy a entrar en la gran discusión acerca de las ventajas y las limitaciones de php y su relación con los objetos.

Acá en Argentina es mucho más sencillo encontrar hostings que soporten php que python. De hecho prácticamente todos soportan php. El despliegue de django en cambio requiere modificar la configuración de Apache y cargar un módulo más, cosa que pone los pelos de punta de los proveedores de hostings.

Y a nivel global, php sigue siendo el lenguaje web más extendido, no sé si por su flexibilidad o su sencillez, pero creo que tiene mucho que ver la gran comunidad que lo respalda y trabaja con él. La documentación es amplia, todo lo que te puede pasar ya le pasó a alguien. En eso CakePHP me parece que tiene mucho campo para crecer.

SPIP

junio 28, 2007
Un poco de historia. SPIP es un sistema de publicación de sitios webs en internet. Es lo que se llama un CMS y permite abstraer adecuádamente el diseño de la lógica de negocio. Esto lo hace mediante un sistema de templates. A su vez cuenta con mecanismos para extender su funcionalidad. Por un lado la balizas dinámicas, por otro los plugins.
Al principio su API parece poco amigable, pero a medida que se ve el código se lo va entendiendo y resulta muy cómodo.
El sitio de Libres del Sur está hecho con esta herramienta y fue mi primer trabajo en la plataforma. El de la Comisión de Recursos Naturales del Mercosur también.
Lo realmente bueno de SPIP es que permite que la diseñadora gráfica trabaje independientemente y el programador por otra parte trabaje sobre la lógica de negocio y luego integre el diseño mediante el sistema de templates / maquetación de SPIP, llamado esqueletos.
En próximos posts voy a explicar como hice algunas cosas con SPIP. Hasta entonces.