nov 22 2010

Problemas con mocks en PHPUnit

tatai

A petición de Mariotux, va este post sobre uno de los problemas que me he encontrado cuando he tenido que usar mocks en PHPUnit. Es uno de los errores ya reportados y se da al intentar comprobar llamadas a un método con distintos parámetros.

Supongamos que tenemos una clase como esta que queremos mockear:

class MyClass {
  public function check($param) {
    // Código
  }
}

En el caso concreto de querer comprobar si se realizan, por ejemplo, dos llamadas a esta función pasando $param = ‘one’ y una llamada con $param = ‘two’, es cuando nos encontremos el problema. Por ejemplo:

$mock = $this->getMock('MyClass');
$first = 'one';
$mock->expect($this->exactly(2))->method('check')->with($first);
$second = 'two';
$mock->expect($this->once())->method('check')->with($second);

Aunque la clase que programemos realice correctamente las llamadas, PHPUnit nos indicará que se esperaban 2 llamadas a check, pero se han realizado 3 y, por lo tanto, no pasará el test.

Esta misma semana comentaba con Carlos Ble y hay posibles soluciones, como es generar una clase intermedia que separe ambas llamadas, siempre teniendo en cuenta que podamos hacer ese código y quizás no sea tan sencillo con código legado o con mucho acoplamiento.

A ver si en los próximos releases de phpunit-mock-objects se soluciona este problema.


nov 17 2010

Configurar el fichero hosts de Android Emulator

tatai

Es posible que te encuentres en la situación (doy un par de ejemplos más abajo) en los que necesites que tu Android Emulator haga caso a tu /etc/hosts en vez de al DNS. Para este caso, lo que tienes que hacer es seguir estos dos sencillos pasos:

  1. Crear un fichero hosts en tu ordenador (o usar el que ya tienes en /etc/hosts)
  2. Remontar el emulador y copiar el fichero anterior

La necesidad de remontar viene porque si no, el dispositivo está como sólo lectura y por lo tanto es imposible escribir nada en él.

Supongamos que tenemos partimos de nuestro /etc/hosts, iríamos al directorio donde tenemos las tools del SDK y teclearíamos:

adb remount
adb push /etc/hosts /system/etc/

También es posible coger el fichero hosts que tiene el emulador (por ejemplo, copiandolo a nuestro directorio /tmp):

adb push /system/etc/hosts /tmp

¿Y en qué casos nos puede hacer falta? Bueno, yo en concreto lo he necesitado cuando estaba desarrollando una aplicación que se alimentaba de un webservice. Realizaba el desarrollo del webservice en paralelo y por lo tanto no estaba (todavía) en la máquina de producción. De esta forma, gracias al fichero hosts obligaba al emulador a buscar en mi entorno de desarrollo en vez de ir al de producción, haciendo que la aplicación tuviese un comportamiento transparente, en código, sobre dónde atacar.


nov 11 2010

Return no numérico en funciones bash

tatai

Por defecto en bash sólo se pueden retornar enteros. ¿Qué hay que hacer entonces para que retorne un valor no entero?

El truco está en hacer un echo del valor y asegurarnos en la llamada de la función que se asigna a una variable. Es decir, nuestra función sería:

function retorna_texto {
    echo -n "este es el valor a retornar"
}

Y la llamada:

VALOR=$( retorna_texto )

Ahora en ${VALOR} tendremos el texto tal y como queríamos


nov 8 2010

Mi configuraciones de vim (y II)

tatai

Como segunda parte del primer post sobre configuraciones de vim, voy a describir qué tengo ahora mismo en mi ~/.vimrc y plugins que uso. Esta configuración “está viva” y la cambio de vez en cuando. ¿Por qué? Pues porque tus gustos varían de vez en cuando y porque siempre descubres cosas nuevas que vas añadiendo o mejorando.

He colgado en github mi configuración al completo basandome en lo explicado en el anterior post. Puedes verlo aquí: https://github.com/tatai/vim

Como acabo de comentar, es posible que lo que haya ahora, es diferente de lo que explique aquí.

~/.vimrc

Vayamos por partes y poco a poco. Pese a que todas las líneas están comentadas, añadiré lo que crea que puede aclarar tras cada trozo de código.

Aclarar que estas opciones son personales y que espero que sean una guía para decidir cómo es tú configuración. Sólo probando encontrarás la combinación perfecta.

Muchas de las opciones se dehabilitan poniendo “no” delante de la opción o se habilitan quitando ese mismo “no”, como por ejemplo se puede ver en la primera de las líneas, con “set nocompatible” que indica que no sea compatible y con “set compatible” se hace que sea compatible.

set nocompatible

Obligatorio, debes tenerla como tu primera opción en .vimrc puesto que el funcionamiento de interno de vim y de muchos plugins varía. Se obliga a que vim no sea compatible con el antiguo “vi”.

" Pathogen
call pathogen#runtime_append_all_bundles()
call pathogen#helptags()

Llamadas para inicializar Pathogen (ver el primer post)

" UTF-8 by default
set fileencoding=utf-8

Forzamos que la codificación del documento sea utf-8

" Background will always be black
set background=dark

Me encanta la consola negra y así seguirá siendo :)

" Show ruler
set ruler

" Show current combination of keystrokes
set showcmd

Información sobre la posición, columna y posición del cursor en la página. Además, mostrar la combinación de teclas que estemos realizando.

" I like wrapping lines in vim
set wrap

Activamos que el texto no continúe más allá del borde derecho de la ventana (o split) en el que esté.

" 1 tab = 4 spaces
set tabstop=4

" Same for autoindenting
set shiftwidth=4

" Use tabs, not spaces for indenting
set noexpandtab

" Indenting
set autoindent
set smartindent
set copyindent

" Insert tabs on the start of a line according to shiftwidth, not tabstop
set smarttab

" Use multiple of shiftwidth when indenting with '<' and '>'
set shiftround

Uso de tabs en vez de espacios y definir que el espacio de un tab equivale a 4 espacios. Además, que la indentación sea “inteligente” y cuando por ejemplo usamos {, se indente automáticamente y al hacer escribir }, haga lo contrario.

" Show matching parenthesis
set showmatch

Ayuda a ver los bloques en códigos complicados. Además, pulsando % cuando estamos sobre uno de ellos, automáticamente salta al otro ;)

" Do not show line numbers (hate them)
set nonumber

No mostrar los números a la izquierda, en el lateral. Estoy muy acostumbrado a mirar al ruler y usar :n para ir a una línea. Además, es más cómo cuando copias seleccionando con el ratón y pegas en otro sitio.

" I like case-sensitive searching, but this is the best of both worlds:
" search is case-insensitive but it is not when using at least one capital
set ignorecase
set smartcase

Me gusta buscar y que distinga mayúsculas y minúsculas, pero activando estas dos opciones, por defecto busca sin distinguir, pero si cualquiera de las letras es mayúscula, entonces sí que hace distinción.

" Do not highlight searchs
set nohlsearch

Cuando buscas algo, no marcar los resultados. Me marea mucho que cuando busco algo, empiece a marcar toda la pantalla. En caso de necesitarlo, lo activo momentáneamente, pero me gusta desactivado.

" Commands to be rememebered
set history=500

Vim y su potencia de historial de comandos. Prefiero una lista más larga que los 20 por defecto, que no ocupa nada en disco.

" Undo levels
set undolevels=1000

Deshacer en un fichero “casi” infinito ;)

" Change terminal title
set title

Cambia el título del terminal para que muestre el path y fichero que se está editando. Comodidad.

" Like beeping
set novisualbell
set noerrorbells

Ni avisos visuales ni sonoros ante errores.

" Swap file save my work many times :) 
set swapfile

Crear el fichero de intercambio .[nombrefichero.ext].swp porque no es la primera vez que consigo recuperar mi trabajo gracias a él. A veces son molestos estos ficheros, pero podemos definir un directorio donde se crean todos, en vez de justo en el mismo sitio que el fichero.

" Disable folding
set nofoldenable

Prefiero ver el texto completo, sin recoger.

" Custom filetype configuration
filetype plugin indent on
autocmd filetype yaml set shiftwidth=2 tabstop=2 expandtab

Activamos indentaciones distintas según tipo de fichero y defino que los YAML tengan espacios en vez de tabs y con un tamaño de dos (así lo requiere el formato YAML)

" No syntax highlighting
syntax off

No me gusta el syntax highlighting. Y cuando te acostumbras a ello, luego todo te da igual y ves antes los errores (menos cuando te dejas un comentario sin cerrar, jeje)

" Use F2 when pasting to avoid applying indents
set pastetoggle=<F2>

Opción muy interesante cuando usamos indentación automática. Si pegamos texto (por ejemplo código), vim piensa que sabemos escribir muy muy rápido y si hemos definido, como efectivamente he hecho antes, que haga indentación automática, si el texto que estamos copiando también lo lleva, el efecto que provoca es bastante desagradable. Con esta opción, definimos que, pulsando la tecla de función F2 en modo INSERT, activamos el modo paste (pegar) de modo que deshabilita momentáneamente estos indentados. De esta forma, conseguimos que el texto se pegue como realmente queremos.

" When line wrapping is enabled this make that when pressing up or down goes
" the visual line up or down, not physical line
" I only enable it sometimes
"nnoremap j gj
"nnoremap k gk

Estas líneas no las tengo activadas, pero las guardo para acordarme. Vim considera que cuando le das hacia arriba, bien sea pulsando la k en modo comando o bien la tecla arriba si así lo tenemos mapeado, irá de línea en línea. Al estar activado “wrap lines”, líneas muy largas ocuparán visualmente varias líneas, pero no físicamente. Vim por defecto irá de línea física en línea física. Activando (descomentando) estas lineas, provocaremos un comportamiento más “natural” ya que al movernos entre líneas lo haremos entre las líneas visuales. No lo activo por costumbre ya que me parece más cómodo. Viene muy bien cuando editamos ficheros con pocos saltos de línea (dumps de SQL, csv, etc)

" Easy change between splits
map <C-h> <C-w>h
map <C-j> <C-w>j
map <C-k> <C-w>k
map <C-l> <C-w>l

Mapeos de teclas que uso mucho. Usando splits, para moverme entre ellos uso Control+[h|j|k|l] en vez de Control+w + [h|j|k|l]

" When you forget to sudo
" http://forrst.com/posts/Use_w_to_sudo_write_a_file_with_Vim-uAN
cmap w!! w !sudo tee % >/dev/null

Si alguna vez olvidas hacer sudo editando un fichero, para que no tengas que salir y volver a hacerlo ;)

" Mappings for FindFile & config
nmap , :FindFileSplit
nmap ; :FindFileCache .
let g:FindFileIgnore = ['*.o', '*.pyc', '*/tmp/*', 'cache_*', '*.swp']

Mapeos y configuración de FindFile. La coma para buscar fichero, punto y coma para que indexe y añado que no indexe fichero que empiecen por cache_ ni terminen en .swp

Plugins

Algunos plugins de vim que considero bastante útiles. Iré añadiendo más en posteriores posts.

Pathogen

Creo que queda poco por añadir. Plugin que te permite organizar el resto de tus plugins de modo que cada plugin ocupa una carpeta distinta dentro de ~/.vim/bundle/ en vez de juntarlos todos en sus correspondientes carpetas en la carpeta raíz ~/.vim/

De esta forma, añadir o quitar plugins consta simplemente de añadir o quitar toda una carpeta.

FindFile

Este plugin permite recopilar todos los ficheros y poder abrir ficheros usando autocompletado. A partir del directorio donde nos encontramos, le decimos a FindFile (usando :FC) que rastree todos los ficheros y que guarde una relación de todos ellos con el lugar exacto donde se encuentran. Entonces, usando :FS o :FF (dependiendo si queremos que el fichero lo abra en un nuevo split horizontal o no) podremos ir escribiendo el nombre del fichero y automáticamente nos dará todas las posibilidades.

Lo primero que tenemos que tener en cuenta es estar en el directorio adecuado. Para ello, nos ayudaremos de unos comandos cuya funcionalidad es igual a la de la consola:

  • :pwd nos dice el directorio en el que nos encontramos
  • :cd para cambiar de directorio. Tenemos que indicar el directorio al que queremos ir. El autocompletado mediante tab ayudará mucho

Yo tengo mapeada la tecla ; (punto y coma) a :FC y , (coma) a :FS para trabajar con más rapidez.

Este plugin tiene un par de limitaciones que me parecen bastante importantes y hay que tener en cuenta.

La primera es que el autocompletado funciona letra a letra desde el principio del nombre del fichero. No valen comodines. No es muy crítica, pero algunas veces viene muy bien poder hacerlo.

La segunda es que no guarda el resultado de :FC en ningún sitio y hay que ejecutarlo cada vez que usamos vim. Esto es un engorro si hay muchos ficheros ya que estaremos varios segundos hasta que podamos empezar a trabajar.

NERDTree

Si te gusta el sistema de ficheros, tanto directorios como ficheros con forma de árbol, este es tu plugin. Tecleando :NERDTree abrirá un split vertical a la izquierda a todo lo alto mostrando los directorios y ficheros al estilo :Sex, pero con la diferencia de poder abrir y cerrar los directorios en vez de entrar a navegar por ellos. Usando la tecla o sobre cualquier fichero, lo abrirá en la ventana que teníamos activa antes de abrir NERDTree y si usamos la i, lo hará en un split horizontal distinto, de modo que la antigua ventana siga disponible.

En cualquier momento podemos cerrar este árbol y volverlo a abrir. Además, puede sustituir a :Sex sin ningún problema y es realmente cómodo.

snipmate

Para poder insertar snippets en vim. Tan sencillo como escribir una palabra clave y al pulsar tab, insertará el snippet. Flexible y potente. Además, se definen zonas de modo que, tras insertar el snippet, usando el tab podemos ir de uno a otro y así completar toda la información. Cada zona tiene un texto por defecto.

El vídeo demo os aclarará completamente su funcionamiento.

Gracias a que el plugin se encuentra en github, en vez de usar directamente este plugin, lo que he hecho ha sido hacer un fork del proyecto en mi cuenta y usar este como plugin. Esto me permite cambiar y añadir snippets manteniendo siempre el repositorio original como referencia. Realizando un simple merge, puedo actualizar todos los cambios del plugin original. Esto evidentemente añade un paso más a todo el proceso explicado en el post anterior ya que primero tengo que actualizar mi fork con el repo oficial y segundo, actualizar el submodule, pero a cambio obtengo independencia total y compatible a cambios con el repo original.

sparkup

Este plugin me ha parecido muy curioso y potente, pese a que no escribo mucho HTML. Para explicarlo, es más fácil ver el vídeo demo, pero rápidamente diré que permite definir con una sintaxis muy sencilla el código HTML a generar y él se encargará automáticamente.

Por ejemplo, escribiendo:

ul.menu > li*2 > a > span < < <

y pulsando Control+e, generará:

<ul class="menu">
  <li>
    <a href="#">
      <span></span>
    </a>
  </li>
  <li>
    <a href="#">
      <span></span>
    </a>
  </li>
</ul>

Y muchas más opciones. Además, podremos ir editando cada una de las zonas de forma sencilla usando tab.

<li><a href=”#”><span></span></a></li>


nov 3 2010

Mis configuraciones de vim (I)

tatai

Hace ya algún tiempo que quiero recopilar todas las configuraciones de vim que tengo repartidas en un montón de cuentas con la intención de centralizarlas de alguna forma y hacerlo todo mantenible que pudiese y ha llegado el momento. Era una de esas cosas que procastinaba constantemente pese al uso bastante intensivo que hago de vim. Y lo peor es que no había pensado completamente en la forma de hacerlo. Tenía claro que quería usar versionado y git tenía muchas papeletas en vista de todo lo que he visto, aprendido y gozado con este DSCM, pero poco más.

La solución ha llegado tras ver este post en vimcasts.com (recomiendo encarecidamente ver el screencast) que me ha parecido tan sencillo y tan potente. En este primer post voy a explicar este método y en el siguiente contaré cuál es mi configuración actual (aunque irá evolucionando, pero bueno, que sirva de ayuda).

La idea es muy sencilla: crear un repositorio de git (que centralizaremos en github.com) que clonaremos en nuestro directorio ~/.vim y, gracias a un par de trucos, extenderlo a todas las cuentas que tengamos de forma sencilla. Nadie nos quita tener que actualizar cada una de nuestras cuentas, pero bueno, podemos tirar de un cron que lo haga automáticamente :)

Usando pathogen

Este plugin para vim es un must-have si usas muchos plugins o, aunque uses únicamente uno, para poder tener todo bien organizado. Cada plugin de vim, en función de sus necesidades, puede estar repartido en múltiples carpetas dentro del raíz de nuestro ~/.vim. Es decir, un plugin nos puede obligar a esta estructura de directorios:

  • ~/.vim
    • doc/
      • plugin.txt
    • plugin/
      • plugin.vim
    • syntax/
      • plugin-syntax.vim

Si multiplicamos esto por varios plugins, teniendo en cuenta que hay más directorios posibles, añadir o quitar plugins es un engorro. Gracias a pathogen, en vez de tener repartidos los ficheros de cada plugin, podremos tenerlos todos juntos, los del mismo plugin en una carpeta, algo que es tremendamente cómodo ya que añadir o quitar un plugin es cuestión de añadir o quitar una carpeta. Muy sencillo.

Con el ejemplo anterior, nos quedaría:

  • ~/.vim
    • bundle/
      • nombre-plugin/
        • doc/
          • plugin.txt
        • plugin/
          • plugin.vim
        • syntax/
          • plugin-syntax.vim

Lo único que tenemos que hacer es descargarnos pathogen.vim y colocarlo en la carpeta ~/.vim/autoload/ (comprobar lo que dice el autor, es posible que esto cambie en el futuro) y añadir estas dos líneas en nuestro ~/.vimrc:

call pathogen#runtime_append_all_bundles()
call pathogen#helptags()

Enlazar ~/.vimrc

Como he explicado al principio, la principal idea es versionar el directorio ~/.vim/. Entonces, ¿qué pasa con ~/.vimrc? Efectivamente, este fichero (y ~/.gvimrc si usas gvim) se quedarían fuera y no los podríamos versionar, teniendo el gran inconveniente de que no podríamos guardar toda nuestra configuración.

Para solucionar este problema, lo que se propone en vimcasts.com es renombrar este fichero a ~/.vim/vimrc (atentos que no se llamaría .vimrc sino vimrc y, por lo tanto, sería visible) y crear un enlace simbólico. Es decir:

mv ~/.vimrc ~/.vim/vimrc
ln -s ~/.vim/vimrc ~/.vimrc

Esto nos permite versionar también este fichero con el punto extra añadido que volvemos al fichero visible y más cómodo de localizar.

Submodules en git

Por último, y no menos importante, trabajar con submodules de git en un repositorio. Partiendo de un repositorio de git ya creado, con los submodules podemos indicar a ese repositorio que los datos de un directorio se extraen de un repositorio git externo a ese. En subversion, sería el hermano mayor de svn:external.

Muchos de los plugins de vim se han ido migrando a git y no sólo eso, sino que también los repositorios mantienen la estructura necesaria del plugin dentro de la carpeta ~/.vim y, por lo tanto como he explicado, gracias a pathogen podremos agrupar ese plugin en una carpeta muy fácilmente.

Vamos a dividir en dos partes. La primera en la que le decimos a nuestro repositorio cuál es el plugin externo (vía submodule) y hacemos el commit & push y la segunda en la que clonamos nuestro repositorio en otra máquina e inicializamos y actualizamos los submodules.

Definiendo el repositorio externo

Supongamos que queremos instalar NerdTree que se encuentra git://github.com/scrooloose/nerdtree.git y ponerlo en bundle/nerdtree

git submodule add git://github.com/scrooloose/nerdtree.git bundle/nerdtree
git add .
git commit -m "Install NerdTree.vim as submodule."
git push origin master 

Notar que tendremos que estar en el directorio donde se encuentra el directorio .git/ y que la configuración del submodule se guarda en .gitmodules (al mismo nivel que .git/)

Clonando y actualizando

Suponiendo que nuestro repositorio se encuentra en git://github.com/tatai/vim.git, lo que haremos primero será clonar el repositorio en nuestra carpeta ~/.vim y posteriormente inicializar y actualizar los submodules:

cd ~
git clone git://github.com/tatai/vim.git ~/.vim
cd ~/.vim
git submodule init
git submodule update

Si todo ha ido bien, si entramos en vim tendremos disponible toda nuestra configuración y plugins que hallamos subido.

A partir de este momento, si queremos actualizar uno de los submodules, tendremos que ir a su directorio y usar git pull. Por ejemplo, usando el ejemplo anterior de nerdtree:

cd ~/.vim/bundle/nerdtree
git pull

Ventaja de usar git

Una de las ventajas añadidas que tiene usar git es que, en cualquier momento, puedes crear tu propia versión de un plugin sin perder de vista el código original ni que nuestras configuraciones pierdan sincronización.

Voy a poner un ejemplo concreto con snipmate del que hablaré en el siguiente post más tranquilamente. Resumiendo, este plugin permite que, en función de ciertas palabras clave, definir snippets. Es una gran utilidad y todas las plantillas se encuentran en la misma carpeta del plugin.

¿Qué ocurriría si queremos añadir más snippets o cambiar el formato de alguno de ellos, por ejemplo porque no se adapta a nuestro estilo de programar? Evidentemente, si usamos el código original del autor sólo podremos enviarle un patch-request que aceptará si quieres o no.

Lo que podemos hacer en estos casos es hacer un fork, como por ejemplo he hecho yo en http://github.com/tatai/snipmate.vim. Un fork nos permite tener una versión propia del repositorio de otro usuario, considerándola como una fuente más de nuestro código, lo que nos permite no sólo reportar errores o mejoras al autor, sino también añadir lo que nosotros creamos más conveniente.

Así pues, a la hora de añadir el submodule, en vez de usar el repositorio original del autor:

git submodule add git://github.com/msanders/snipmate.vim bundle/snipmate

Usaremos como origen el nuestro propio:

git submodule add git://github.com/tatai/snipmate.vim bundle/snipmate

Esto claramente nos añade un paso más, ya que no bastará con actualizar los nuestros directorios ~/.vim sino también mantener este otro repositorio.


nov 2 2010

Slides and links from PHPConference 2010

tatai

Polling #pbc10 at Twitter during PHPConference and Googling later on I have compile all these links from each talk, trying to find at least twitter account, blog and slide links from each talk and presenter.

I know it is not complete, but it will be as soon as I can.

If you know any other source or find a broken link, please comment post or  tweet me and I will update this list.

Hope it is useful.

Hidden features of PHP by Ilia Alshanetsky

APC & Memcached the High Performance Duo by Ilia Alshanetsky

A new approach to object persistence in PHP by Stefan Priebsch

Split A/B Testing Database-driven PHP Web Applications by Kuassi Mensah

‘In search of…’ – integrating site search systems by Ian Barber

How to scale PHP applications by Enrico Zimuel

Cloud computing with PHP and Azure by David Salgado

Design patterns… revisited for PHP 5.3 by Fabien Potencier

PHP in the Enterprise: Develop and Deploy Mission Critical Applications by Kuassi Mensah


Graphs in the database: RDBMS in the social networks age by Lorenzo Alberton

Cómo involucrarse con PHP by Yago Ferrer

Real-time Communication Techniques with PHP by Scott Mattocks

Demystifying PostgreSQL by Asher Snyder

Database version control without pain by Harrie Verveer

PHP for Android: Scripting PHP en Android by Ivan Mosquera

Scaling Magento by Fernando Palomo

Continuous Improvement in PHP projects by Thorsten Rihnne

iPhone Websites with PHP by Markus Franz (speaker could not arrive on time, this talk took place instead:)
PHP Code audits by Damien Seguy

Distributed Source Code Management by Hugh Gilmour

Varnish in action by Thijs Feryn

Architecture and testability by Giorgio Sironi

Comet: By Pushing Server Data, We Push the Web Forward by Philip Ross

Doctrine 2.0 by Juozas Kaziukenas

Lemur Framework by Javier Linares & Paulo Oliveira

Service Oriented Architecture: a good thing to do by Jan Willem Eshuis

Mondongo, un ODM para PHP y MongoDB by Pablo Díez

SCRUM al detalle: Revisión práctica y perversiones humanas by Carlos Buenosvinos

MySQL client caching by Johannes Schlüter

Desarrollo de aplicaciones para Facebook en PHP by Victor Castell

PHP Team organisation by Damien Seguy

PHP through the eyes of a hoster by Thijs Feryn

High Performance WebApps Faster & Easier with NOLOH by Asher Snyder



oct 31 2010

PHP Conference 2010. Día 2

tatai

Y como todo lo bueno siempre se acaba, la PHP Conference 2010 ha dado cerrojazo.

No sin polémica ya que el ganador de la XBOX del sorteo general se llevó también el iPad del sorteo de emagister… la suerte está mal repartida :p (hay que aclarar que el sorteo ha sido legal y a la vista de todos, hay poco que añadir a parte de que la mecánica pueda -posiblemente- cambiarse para el año que viene y unir ambos sorteos).

Y esta fue la elección para el segundo día. Creo que bastante más acertada que el primer día, aunque con alguna decepción:

  • Graphs in the database: RDBMS in the social networks age by Lorenzo Alberton
  • APC & Memcached: the high performance duo by Ilia Alshanetsky
  • Database version control without pain by Harrie Verveer
  • Continuous Improvement in PHP projects by Thorsten Rihnne
  • PHP Team organisation by Damien Seguy

Seguidamente, un resumen de cada una de ellas.

Graphs in the database: RDBMS in the social networks age by Lorenzo Alberton

De nuevo, tras haber ya asistido el año pasado a otra charla magistral, otra interesantísima chala de Lorenzo sobre grafos, árboles y bases de datos. Esta vez centrada en dos puntos, las CTE (Common Table Expressions) y Window Functions.

Pese a ser una charla compleja debido a que la presentación se basa en ejemplos SQL y en la teoría, Lorenzo realiza un esfuerzo inhumano para hacerlo entendible desde un primer momento. Además, este año mostró ejemplos reales y concretos que todos conocíamos en la web y que nos destripó a nivel de base de datos.

Tras una breve introducción a los gráficos y sus componentes nos mostró diversas soluciones posibles a la hora de plantear una estructura de árbol en una base de datos a la que seguro que todos nos hemos enfrentado alguna vez. Tras unos consejos básicos de rendimiento y eficiencia y demostrar como realizar cualquier tipo de consulta que abarcara más de un nivel (por ejemplo coger los hijos hasta n niveles), mostró las CTE gracias a WITH (y WITH RECURSIVE). Como si de una función o proceso almacenado se tratase pero viviendo únicamente en el momento de la ejecución, con sus partes bien diferenciadas (inicialización, recursividad y llamada), nos mostró ejemplos desde la clásica sucesión de Fibonacci hasta cómo se pueden encontrar combinaciones de vuelo o transporte mediante varios saltos, los grados de separación en LinkedIn, cómo encontrar los contactos (de camino mínimo) entre tú y otra persona o los “quizás conozcas”. Todos estos últimos ejemplos usando Transitive Closures.

También nos mostró como a veces técnicas como esta pueden ser un embrollo y un simple INTERSECT puede solucionar el problema de una forma muy sencilla y rápida.

El segundo caso, las Window Functions (SQL-2003) que nos permiten agrupar cierto número de filas que tienen una relación y extraer datos concretos (por ejemplo, una media de salarios por departamento) y usar ese dato para cada fila, pero sin agruparlas ya que perderíamos cada usuario, es decir, sin usar un GROUP BY. La sintaxis es bastante liosa en un inicio y mucho más potente de lo que a primeras aparenta pero sin duda, gracias a ciertas funciones complementarias, con aplicaciones muy interesantes como poder extraer en una misma petición lo datos completos de venta un día y también agrupados por usuario o los datos agrupados y paginados de los contactos telefónicos.

Por último nos llamó a la reflexión ante qué debe ser bueno ejecutar sobre base de datos y que no ya que se puede ver con los ejemplos como podemos quitar carga de procesado en la parte de aplicación, eliminando conexiones y RTT entre la base de datos y la aplicación, pero que ello conlleva sobrecargar la base de datos.

APC & Memcached: the high performance duo by Ilia Alshanetsky

La charla empezó la charla dando cuál iba a ser el slogan: “Slide motto: not everything has to be real-time”. Y lo siguiente en darme cuenta fue que es realmente un crack y que su trepidante velocidad y conocimiento hace que perderte unos segundos escribiendo algo en el portátil puede hacer que te pierdas gran parte de un slide.

La estructura de la charla en mi opinión fue perfecta: breve introducción de las aplicaciones y cómo instalarlas (que estoy seguro que eran conocidas para la amplia mayoría de los asistentes) y tras esto, una serie de consejos, buenas prácticas y trucos de cada una de ellas. Eso sí, yo creo que el oxígeno se lo inyectaba, porque no creo que le diese tiempo a respirar entre frase y frase, jeje.

En cuanto a APC, lo primero a tener en cuenta es que tenemos el cacheo propio y transparente que hace de los opcodes, con la consecuente mejora de rendimiento que conlleva y que además podemos usar para cachear datos en shared memory. Y lo más importante, lo que se cachea no es el valor, sino el propio opcode. La ventaja de este método es radical ya que si comparamos con un método trandicional de cacheo mediante serialización de datos (aunque sea binario), siempre hay que realizar la propio acción de serialización y deserialización, desmaterializando y materializando los objetos, mientras que APC cachea el propio opcode, el dato en sí, algo que es mucho más rápido y efectivo.

Otros trucos: cómo saber cuando apc_fetch nos ha devuelto información o no y es gracias a un segundo parámetro que tenemos que pasar por referencia ya que lo que se retorna es el dato y puede ser cualquiera de los valores posibles (null, true, false, array, objeto…) por lo tanto necesitamos un punto de referencia.

Y como consejo muy importante, evitar todo lo posible el borrado de caché: “Don’t delete: deleting from cache is expensive as it may need to re-structure internal hash tables”. A veces el mejor borrar todos los datos de un usuario que un dato concreto debido a todo el proceso que puede desencadenar.

Como contra, APC es un sistema de cache única y exclusivamente para PHP, nadie más puede usarlo y es local, no distribuído, lo que limita su radio de acción.

En cuanto a memcached, lo primero que nos hizo notar fue la necesidad de usar la extensión de Andrei Zmievski y no la otra existente que no lleva d al final ya que la diferencia y mejoras es notable: serialización binaria mediante igbinary, compresión fastlz, interface multiservidor y soporte ante fallos de caídas.

Con esta extensión, tenemos (entre otras muchas cosas, a destacar):

  • getResultCode() para saber si hemos recuperado un ejemplo o no (comparándolo con MemCached::RES_SUCCESS)
  • podemos asignar y recuperar varios valores simultáneamente con [get|set]Multi()
  • se pueden añadir varios servidores son prioridad o balanceo usando addServers() y el tercer parámetro para cada servidor
  • podemos segmentar información indicando el servidor concreto donde se almacenará (sin dejar que memcached decida) gracias a [add|get|set|delete]ByKey()
  • segmentar varios datos a la vez [add|get|set|delete]MultiByKey()
  • utilizar contadores atómicos increment() y decrement()

Y por último, destacar el hecho de poder pedir datos de forma retardada (delayed fetch) de modo que nuestra aplicación no tenga que esperar, sino que puede hacerlo más tarde, continuando con la ejecución de nuestra aplicación. Lo que hay que tener muy en cuenta es que la información es probable que no venga en orden.

Database version control without pain by Harrie Verveer

Tengo que decir que esta charla me defraudó mucho. Con un título tan potente ante un tema que realmente da muchos quebraderos de cabeza, no esperaba que diese el quid que solucionase completamente el problema (algo que parece que sí dice el título o eso esperábamos todos los presentes), pero sí que parecía algo importante.

Pero más allá de la realidad,  nos dio varias de las herramientas que actualmente existen y que intentan facilitar el trabajo y declarar que el problema es muy importante y hay que llevarlo con cautela. Sí que me quedo con una frase que me parece muy importante: “Never modify a patch file once it is version control”. Es decir, en caso de que hagas un patch file y tenga un error, no debes corregir ese, sino crear “el patch del patch” que lo solucione.

Estas son las herramientas recomendadas:

En las preguntas finales: el propio ponente declaró que su estrategia es un “homebrew script” aunque otros equipos en su empresa usan DB deploy y parecen estar muy contentos.

Continuous Improvement in PHP projects by Thorsten Rihnne

En esta charla en primer lugar se mostró cómo un código que se mejora constantemente funciona mucho mejor, demostrando además como técnicas ágiles y la integración continua van de la mano. Tras mostrar estos conceptos muy relacionados principalmente con scrum, se mostraron una serie de herramientas desarrolladas en su empresa (o mejoradas) que ayudan a la hora de controlar un proyecto e intentar que mejore.

Las aplicaciones que se mostraron fueron:

PHP Team organisation by Damien Seguy

De manos del genial Damien Seguy asistimos a una charla sobre cómo realizar gestión de equipos, mejorar su implicación y como gestionar impedimentos. Fueron muchos los consejos, pero podemos resumirla en la siguiente lista que se explica por sí sola:

  • Weekly meeting
    • Discussion of future stuff
    • Specific training on tools, methods
    • Read indicators (audits, PI, ec)
    • Review reference documents
    • One question each (helps prepare for the meeting
  • Name domain gurus
    • Create domain experts
    • Specific domain
    • Unit test, IHM, database
    • Willing team member
    • Name it after he has taken the responsability
  • Healthy competition
    • Number of unit tests
    • Lines of codes
    • Number of methods
    • Number of commits
  • Learn to say no
  • 5 minutes meeting daily
  • Short cycles
  • References
  • PHP Mantra: short version of conventions
  • Evangelize
  • Name your teams/projects
  • Tag your code
  • Cross audits

oct 29 2010

PHP Conference 2010. Día 1

tatai

Tras terminar el primer día, voy a dar un pequeño repaso de las charlas en las que he estado. De entre todas las charlas disponibles, yo he elegido estas:

  • Doctrine 2.0 by Juozas Kaziukenas
  • Distributed Source Code Management by Hugh Gilmour
  • Varnish in action by Thijs Feryn
  • PHP in the Enterprise: Develop and Deploy Mission Critical Applications by Kuassi Mensah
  • Desarrollo de aplicaciones para Facebook en PHP by Victor Castell
  • Architecture and testability by Giorgio Sironi
  • Comet: by pushing server data, we push the web forward by Philip Ross

De primeras, con lo que he visto y he podido leer en twitter, tengo que decir que parece que he cogido las más “divulgativas” y yo he venido con bastantes ganas de ver cosas nuevas o por lo menos ver código y aplicaciones.

Ahora, un breve resumen de cada una de ellas.

Doctrine 2.0 by Juozas Kaziukenas

Un repaso por lo que va a ser Doctrine 2.0, tanto por las nuevas características que tendrá como por comparación con Doctrine 1.x. La versión actual de Doctrine, pese a ser lento, tener un alto uso de memoria (principalmente por un uso cíclico de referencias), su “magia” y otros problemas como la dificultad de ejecutar “raw” SQL, sigue siendo el mejor ORM para PHP hoy en día y por ello Doctrine 2 tendrá esas funcionalidades (y más) aunque cambiará la forma de hacerlo.

Reescrito completamente para PHP 5,3, con una nueva API simplificada y muchas mejoras de rendimiento es la tarjeta de visita de esta nueva versión.

Además, se divide en 4 módulos: Common, DBAL (DB Abstraction Layer), ORM y ODM (Object Document Layer). Este último permitirá trabajar con motores NoSQL, otra de las nuevas características.

Una interesante charla de introducción a lo que va a ser Doctrine 2.

Distributed Source Code Management by Hugh Gilmour

La charla tuvo dos partes diferenciadas, la primera fue una revisión del distinto software usado a lo largo del tiempo para realizar control de código y la segunda fue una comparación entre git, bazaar y mercurial.

Desde mi punto de vista, la parte más interesante fue la segunda, aunque fue algo particular ya que no se basaba únicamente en compararlos desde el punto de vista de cómo se realizan las revisiones, o las características de los branches y merges, sino también dio las herramientas que se usan para todos ellos, soporte de IDEs e incluso bugtrackers e integración contínua. Muy interesante para analizar estas diferencias que en más de un caso, pueden ser muy importantes.

De todas formas, me quedo con perlas dichas por Hugh como “Simplest option is always the best” y “Work at the level of the least technical person in the project”. La primera porque es una máxima que creo que hay que seguir siempre, sobre todo en el desarrollo de software como buen principio y la segunda porque a la hora de elegir cualquier opción, el factor humano y profesional debe tenerse en cuenta, que no quiere decir que haya que poner lo más simple (que no sencillo), sino lo que se adapte mejor, hay que buscar lo mejor.

Varnish in action by Thijs Feryn

Presentación que muestra las posibilidades de Varnish, aunque sin profundizar demasiado en el producto. Se muestran muchas de los comandos y configuraciones que nos permiten configurar la aplicación considerando que la principal aplicación de Varnish es la de caching.

Creo que aunque se intentaba mostrar toda la potencia del servicio, que realmente parece muy potente, a la vista de cómo es la configuración, principalmente mediante comandos y subrutinas en ficheros, realmente esconde un entorno bastante complicado de configurar.

Una charla muy rápida (casi 100 transparencias en 50 minutos) a nivel visual fue difícil de seguir debido al ritmo tan trepidante impuesto por Thijs que aclaró desde un primer momento que no tenía perfil técnico, algo que se echó de menos en algunos momentos.

PHP in the Enterprise: Develop and Deploy Mission Critical Applications by Kuassi Mensah

Charla muy marcada por la presencia de Oracle (recordemos que el Platinum partner) en la que se mostraba algunas de las características que provee Oracle como base de datos en los cambios entre entornos, facilitando distintas aplicaciones y el cambio.

Desarrollo de aplicaciones para Facebook en PHP by Victor Castell

Esta charla/taller estaba dividida en dos (algo que no estaba muy claro en el programa ya que tan sólo estaba en dos sesiones separadas por uno de los descansos largos) y sólo pude asistir a la primera parte.

La idea era buena puesto que se quería mostrar cómo realizar una aplicación en PHP para Facebook y de hecho, para avanzar en el proceso y hacerlo más sencillo, creo que la forma de realizarla no estuvo nada organizada, lo que provocó que en los 50 minutos que estuve en la charla, apenas se dieron los conceptos básicos, haciendo principal hincapié en las condiciones de uso de Facebook, los problemas que tiene el desarrollo en Facebook (latencias, caídas, cambios en la API, etc) y en que hay que buscar la aplicación que se interesante para el cliente. Pero el tiempo empleado por ejemplo en dar de alta la aplicación en Facebook (pudieron ser tranquilamente 3o minutos) me pareció excesiva y poco fructífera ya que, exceptuando un par de conceptos que sí que es necesario explicar y aclarar, el resto se podía suponer de una forma bastante clara.

Si a todo esto unimos que la sala estaba realmente hasta arriba y era la pequeña pequeña (estaríamos unas 60 personas de pie), pues no pude probar nada y esperaré a que cuelguen el enlace y la presentación para poder trastear algo. Algo más de organización hubiese venido muy bien y al menos salvaron los problemas técnicos que no tuvieron que ver con ellos de forma magistral.

Architecture and testability by Giorgio Sironi

Interesante conferencia a manos de Giorgio sobre la importancia del buen código y del testeo. Se centró en estos cuatro puntos principalmente: “Do dependency injection”, “Avoid static methods”, “Law of Demeter” y “Singleton vs. Factory”.

Aunque creo que se extendió demasiado para explicar algunos conceptos que se veía que controlaba y haber dado más ejemplos creo que le hubiese ayudado más.

Sin lugar a dudas, me quedo con estas dos perlas: “Easy to test means easy to maintain” y “When tests are difficult to write, change the design to ease testing (listen to your tests)”

Comet: by pushing server data, we push the web forward by Philip Ross

Excelente presentación de la gente de NOLOH sobre las ventajas de comet, aunque desde un punto de vista muy superficial. Me ha gustado bastante la parte en la que han hecho especial énfasis en la historia de la tecnología y su futuro por ejemplo con WebSockets, aunque los navegadores pondrán muchas trabas a no ser que mejore el asunto.

Debido a problemas técnicos iniciales y a la saturación de la conexión a internet, la charla fue más corta de lo esperado y sin ejemplos prácticos que se echaron en falta.

Finalmente mostraron algo de NOLOH Framework aunque nos quedamos con las ganas de ver más cosas interesantes.

Update: continúa leyendo el día 2


oct 29 2010

PHPConference 2010

tatai

Y de nuevo este año me he venido el 29 y 30 de octubre a disfrutar de la PHPConference a Cornellà, Barcelona. Tras el muy buen sabor de boca del año pasado, era necesario repetir porque las conferencias no pintan nada mal. Quizás menos “grandes nombres” en el cartel, pero ni mucho menos parece que va a desmerecer.

En breve lo comprobaremos.

Mis reviews del año pasado:

Update: ya disponible el review del primer día

Update: y el del segundo

Update: y el listado de slides y datos de conferenciantes


oct 22 2010

Porque wordpress pide datos de conexión cuando actualizamos automáticamente

tatai

Me he encontrado al intentar actualizar unos plugins de un nuevo wordpress que al hacerlo me pedía los “datos de conexión”, algo que me ha parecido raro porque generalmente no suele hacerlo.

Tras bucear un poco en el código me he dado cuenta que en la función get_filesystem_method() de wp-admin/includes/file.php (que se llama desde wp-admin/includes/plugin.php, encargada de actualizar el plugin cuando se lo pedimos) se comprueba que el fichero que se está ejecutando tiene el mismo identificador de usuario que el proceso que está ejecutando la petición.

Esto es así en la amplia mayoría de los casos y no dará problemas, sobre todo si trabajamos con un hosting preparado. Pero si esto ocurre, la opción más rápida sería cambiar el uid de usuario de todos los ficheros de vuestro wordpress al usuario con el que se ejecuta apache. Es decir, partiendo de que el usuario de apache es www-user y vuestro wordpress está en /var/www/wordpress, sería usar el comando:

chown -R www-user /var/www/wordpress