You are currently browsing the category archive for the ‘PHP’ category.

El operador de igualdad se usa para dos conceptos diferentes en los lenguajes de programación: la identidad y la equivalencia. En este artículo quiero aclarar estos conceptos y dar ejemplos como algunos lenguajes de programación los implementan.

Los conceptos

Habitualmente se denomina igualdad al operador == (o = en algunos lenguajes como Pascal o Visual Basic). Pero hay dos conceptos de lo que puede ser igual: la entidad que contiene un valor (identidad) o el valor que contiene (equivalencia).

Decimos que las dos variables a = 5 y b = 5 son iguales en sentido matemático porque contienen el mismo valor 5. Sin embargo, a y b son dos variables distintas en sentido informático si se guardan en dos direcciones distintas en la memoria. En el último caso hablamos de identidad: las variables a y b son iguales cuando hacen referencia a la misma entidad. En el primer caso hablamos de equivalencia. Las variables pueden hacer referencia a una memoria diferente, pero contienen el mismo valor.

Es obvio que la identidad es un criterio más estricto. Dos objetos distintos pueden tener el mismo valor o no, pero el mismo objeto comparado a si mismo siempre es igual.

El uso en los lenguajes

Implementación de identidad y equivalencia
Significado de igualdad
Equivalencia
(mismo valor)
Identidad
(mismo objeto)
Lenguajes compiladas (“antiguas”) Operador == Operador == entre punteros
Lenguajes interpretadas (“modernas”) Método equals Operador ==

Los lenguajes de programación más antiguas como C o Fortran suelen interpretar la igualdad como equivalencia. Para esto puede haber varias razones. Primero la equivalencia es el concepto más matemático (Fortran viene de formula translation). Luego no existía el concepto de objeto cuando se crearon estos lenguajes. Los tipos de variables eran los básicos como caracteres, números enteros y números de coma flotante. Los compiladores convertieron las expresiones a == b a una comparación entre los valores de dos direcciones de memoria. Para comprobar identidad se podían comparar los punteros a estas memorias. No extraña que se sobrecarga el operador == en C++ con un significado de equivalencia hasta hoy en día.

El asunto se cambió con los lenguajes orientado a objetos en que no existen punteros como C#, Java o PHP. En estos lenguajes, no son las variables que guardan los objetos sino el intérprete. La variable de objeto guarda meramente un identificador. Por lo tanto, una comparación entre dos variables es una comparación entre identificadores y no valores. En consecuencia la igualdad tiene la conotación de identidad.

También cabe señalar que estos lenguajes no permiten sobrecarga el operador == como en C++. No es posible crear un operador == que compare el contenido. Tampoco conviene que el intérprete realice una comparación binaria entre dos objetos. La representación binaria depende de la plataforma y un lenguaje como Java se creó justamente para no depender de ella.

Clases inmutables

Ninguna regla sin excepción. En Java o C#, sí, se pueden comparar los valores de dos strings con el operador ==. Esto es posible ya que estas clases son inmutables (o constantes según la jerga de C++): Sus instancias ya no se pueden modificar una vez creadas. Los intérpretes – la máquina virtual de Java o el framework de .NET, respectivamente – aprovechan esta característica. Si initializo una instancia de string con un valor ya existente en otra instancia, entonces no se crea un nuevo valor, sino la nueva instancia apunta al valor existente. Por esto, la nueva variable contiene una referencia a la misma instancia que la variable antigua. Ambas apuntan al mismo objeto y, por lo tanto, son idénticos.

Las clases inmutables tienen más características interesantes. Por ejemplo, no hace falta copiar sus contenidos. En una copia profunda de una clase (deep copy en inglés) debo crear constructores de copia para cada subobjeto de una clase, pero no para un string. La copia causa que una variable de clase string apunta a otro objeto guardado en el intéprete, pero el valor del objeto en si no se modifica ya que es inmutable. Operaciones sobre cadenas de texto reasignan referencias, pero no tiene por qué crear nuevas cadenas.

Conclusión

Hemos visto que existen dos conceptos de igualdad: la identidad y la equivalencia. La equivalencia es el concepto implementado en los lenguajes más tradicionales, mientras la identidad se ha impuesto en los lenguajes más recientes – entre otros motivos por razones técnicas. Los lenguajes que implementan el operador == como equivalencia suelen comparar identidades mediante punteros. Los lenguajes que implementan la identidad para el operador == suelen propicionar un método equals para la equivalencia.

Enlaces de interés

HTML tiene un elemento SELECT que permite el atributo multiple para poder seleccionar más que una opción a la vez. (Las selecciones mútliples se hacen normalmente pulsando la tecla Control mientras se seleccionan las opciones con el ratón.) El atributo multiple no tiene valor. Si no está, entonces el elemento SELECT sólo permite seleccionar una opción. Este artículo explica como puedo obtener múltiples opciones seleccionadas en un programa PHP.

PHP devuelve los datos enviados desde un formulario en la variable “súperglobal” $_REQUEST. La variable $_REQUEST es una unión de las variables súperglobales $_GET, $_POST y $_COOKIE. Por lo tanto, su contenido no depende si hemos recibido los datos via un “GET” o un “POST”. Es decir, es una buena opción en general.

La variable $_REQUEST es un array asociativo, donde los índices son los valores de los atributos id o name de los elementos de entrada en el formulario HTML enviado. A cada índice se asigna el contenido del elemento correspondiente. En un SELECT simple se devolvería la opción seleccionada si hay.

Por ejemplo, consideramos el siguiente SELECT de selección simple (nótese la ausencia del atributo multiple):

<SELECT id="mi_select">
    <OPTION value="hola mundo">Hola mundo</OPTION>
</SELECT>

Si hubiéramos seleccionado la opción “Hola mundo”, entonces, en PHP, la expressión $_REQUEST['mi_select'] tendría el valor 'hola mundo'. (El valor del atributo value del elemento OPTION.)

Sin embargo, si el elemento SELECT tuviera puesto el atributo multiple, entonces sólo obtendríamos el valor de la última opción seleccionado. Para obtener todas las opciones, el valor de $_REQUEST['mi_select'] debería ser un array. Esto conseguimos cambiando el id del elemento SELECT a mi_select[]. (Esto es el mismo nombre más los corchetes [].)

<SELECT id="mi_select[]" multiple>
    <OPTION value="hola mundo">Hola mundo</OPTION>
</SELECT>

Este pequeño truco causa que $_REQUEST['mi_select'] es un array. Ahora puedo hacer un bucle sobre todas las opciones seleccionadas.

foreach ($_REQUEST['mi_select'] as $option_value)
{
    // Haz algo con el valor de la opción seleccionada $option_value
}

En corto: Asigna un nombre terminado en corchetes “[]” a un elemento SELECT cuando tiene puesto el atributo multiple para poder extraer todas las opciones seleccionadas desde PHP.

Referencias

Se puede acceder a una base de datos Firebird/InterBase desde PHP de forma directa. Sin embargo, considera usar una conexión ODBC, ya que hace el programa más independiente de la base de datos usado. Si quieres conectarte directamente desde PHP, primero debes habilitar la extensión php_interbase.dll. De otra forma, PHP te devuelve un error “Call to undefined function”. Puedes establecer la conexión con

// Una base de datos en un PC con dirección IP
$host = "127.0.0.1:C:\\usr\\my database.fdb";

// El administrador de la base de datos
$username='SYSDBA';

// La contraseña pricipal
$password='masterkey';

// El rol no es requerido si ya soy un sysdba
$role = 'sysdba';

// El comando de conexión
$conn = ibase_connect($host,
                      $username,
                      $password,
                      NULL,
                      0,
                      NULL,
                      $role);

Se cierra una conexión con ibase_close.

Referencias

Qué es

Lo que javadoc es para Java, phpDocumentor es para PHP: Una herramienta para generar documentación a partir del código fuente. (Ver artículo sobre
Documentación automatizada.)

Por ser dos proyectos separados, phpDocumentor no es automáticamente compatible con una nueva versión de PHP. Por ejemplo, yo tuve problemas con phpDocumentor 1.4.3 cuando instalé PHP 5.3 y volví a la versión 1.4.2 que funcionaba aunque con muchas advertencias.

Una alternativa a phpDocumentor es Doxygen que puede también documentar código PHP. Una diferencia es que doxygen es un programa, mientras phpDocumentor es una colección de código en PHP. Es decir, genera la documentación con el mismo PHP que usas para ejecutar tu propio código PHP. Por eso necesitas tener también PHP en tu máquina para poder usar phpDocumentor. Sin embargo, no necesitas instalar un servidor web.

Como instalar

phpDocumentor no es un programa sino un código fuente y, por eso, no tiene instalador. Es un archivo que descomprimes en un directorio. Para usar phpDocumentor debes abrir el fichero phpdoc.bat (en Windows) y especificar la ruta a php.exe en la variable phpCli. Por ejemplo

SET phpCli=C:\Program Files\PHP\php.exe

Como usar

Para un proyecto en concreto conviene crearse un script en que especificas todas las opciones de phpdoc.

El siguiente script es un ejemplo. Lo he utilizado para generar la documentación del mismo phpDocumentor. Antes de usarlo hay que ajustar los directorios de entrada y salida y de la instalación de PHP.

echo Generate automatic documenation for phpDocumentor
echo Version from 12.6.2009

rem Directory list must be without spaces between the coma
set phpdoc_dir="C:\opt\PhpDocumentor"
set source_dir="C:\opt\PhpDocumentor"
set target_dir="C:\doc\phpDocumentor"
set title="phpDocumentor Documentation"
set projects=phpDocumentor
rem set output="HTML:frames:default"
rem set output="HTML:frames:earthli"
rem set output="HTML:frames:l0l33t"
 set output="HTML:frames:phpdoc.de"
rem set output="HTML:frames:phpedit"
rem set output="HTML:frames:phphtmllib"
rem set output="HTML:frames:DOM/default"
rem set output="HTML:frames:DOM/earthli"
rem set output="HTML:frames:DOM/l0l33t"
rem set output="HTML:frames:DOM/phpdoc.de"
rem set output="HTML:frames:DOM/phphtmllib"
rem set output="HTML:frames:DOM/phphtmllib"
rem set output="HTML:Smarty:default"
rem set output="HTML:Smarty:HandS"
rem set output="HTML:Smarty:PHP"
rem set output="CHM:default"
rem set output="PDF:default"

cd %phpdoc_dir%
call phpdoc -d %source_dir% -t %target_dir% -ue on -ti %title% -pp off -po %projects% -o %output% -s off
rem pause
exit

rem These are comments, but they will not be executed because the scripts exists before
rem use phpdoc -h to see this

  -f    --filename                name of file(s) to parse ',' file1,file2.
                                  Can contain complete path and * ? wildcards

  -d    --directory               name of a directory(s) to parse
                                  directory1,directory2

  -ed    --examplesdir            full path of the directory to look for
                                  example files from @example tags

  -tb    --templatebase           base location of all templates for this
                                  parse.

  -t    --target                  path where to save the generated files

  -i    --ignore                  file(s) that will be ignored, multiple
                                  separated by ','.  Wildcards * and ? are ok

  -is    --ignoresymlinks         ignore symlinks to other files or
                                  directories, default is off

  -it    --ignore-tags            tags to ignore for this parse.  @package,
                                  @subpackage, @access and @ignore may not be
                                  ignored.

  -dh    --hidden                 set equal to on (-dh on) to descend into
                                  hidden directories (directories starting with
                                  '.'), default is off

  -q    --quiet                   do not display parsing/conversion messages.
                                  Useful for cron jobs on/off default off

  -ue    --undocumentedelements   Control whether or not warnings will be shown
                                  for undocumented elements. Useful for
                                  identifying classes and methods that haven't
                                  yet been documented on/off default off

  -ti    --title                  title of generated documentation, default is
                                  'Generated Documentation'

  -h    --help                    show this help message

  -c    --useconfig               Use a Config file in the users/ subdirectory
                                  for all command-line options

  -pp    --parseprivate           parse @internal and elements marked private
                                  with @access.  Use on/off, default off

  -po    --packageoutput          output documentation only for selected
                                  packages.  Use a comma-delimited list

  -dn    --defaultpackagename     name to use for the default package.  If not
                                  specified, uses 'default'

  -dc    --defaultcategoryname    name to use for the default category.  If not
                                  specified, uses 'default'

  -o    --output                  output information to use separated by ','.
                                  Format: output:converter:templatedir like
                                  "HTML:frames:phpedit"

  -cp    --converterparams        dynamic parameters for a converter, separate
                                  values with commas

  -ct    --customtags             custom tags, will be recognized and put in
                                  tags[] instead of unknowntags[]

  -s    --sourcecode              generate highlighted sourcecode for every
                                  parsed file (PHP 4.3.0+ only) on/off default
                                  off

  -j    --javadocdesc             JavaDoc-compliant description parsing.  Use
                                  on/off, default off (more flexibility)

  -p    --pear                    Parse a PEAR-style repository (package is
                                  directory, _members are @access private)
                                  on/off default off

  -ric    --readmeinstallchangelogSpecify custom filenames to parse like
                                  README, INSTALL or CHANGELOG files

You can have multiple directories and multiple files, as well as a combination
of both options

En la carpeta HTML nuevamente generado debes abrir el fichero index.html para ver la página principal de la documentación. La más práctico es crearse un enlace fuera del directorio con un nombre significativo como “Documentación de bla bla”.

Puedes usar letras con acentos y otras letras no ASCII si guardas el fichero fuente (con el código) con la codificación UTF-8 (con BOM). En general no es mala idea guardar tu código como UTF-8 en lugar del habitual ISO-8859 si quieres usar otros idiomas que el inglés en los comentarios, porque phpDocumentor (y también doxygen) codifican su salida HTML en UTF-8.

phpDocumentor tiene diferentes convertidores. Cada uno compila la documentación en un formato y tema diferente (HTML, PDF, CHM). La página web de phpDocumentor muestra ejemplos de los diferentes temas visuales que permite la documentación en HTML.

Crear la documentación de phpDocumentor y tutoriales

Como ya he mencionado más arriba, phpDocumentor puede crear su propia documentación. Los ficheros fuente de esta documentación están en una subcarpeta “tutorials”. Sin embargo, debes especificar el directorio raíz de phpDocumentor como directorio de entrada a phpdoc, para que se compilen estos tutoriales. (phpDocumentor no procesa documentación en “tutorials” que no esté vinculado a algún código fuente. No puedes compilar sólo tutoriales.) Como proyecto debes especificar “phpDocumentor”. (Ver ejemplo abajo.)

Esta subcarpeta “tutorials” es también un ejemplo de como escribir documentación que no está directamente vinculada a algún objeto dentro del código. Estos tutoriales están escrito en un formato reducido de DocBook. Los elementos DocBook que se compilan están listado en la sección [ppage] del fichero options.ini que viene con cada convertidor. Por ejemplo, mi tema favorito “HTML:frames:earthli” está configurado por el fichero Converters/HTML/frames/templates/earthli/options.ini. Cada convertidor/tema tiene su fichero de configuración options.ini en una carpeta diferente.

Conclusión

phpDocumentor es una herramienta potente para crear documentación a partir de código fuente PHP. El formato de comentarios de documentación es fácil de aprender por ser muy parecido al formato de javadoc. (Ver lista de características de phpDocumentor.)

Una desventaja es que cuesta hacer phpDocumentor funcionar. Es un problema que desaparece una vez familiarizado con la herramienta, pero que puede causar frustración al principio. También existe una interfaz gráfica para generar la documentación pero que requiere un servidor web propiamente configurado. No está mal pero no quita el problema de tener que leer mucha documentación antes del primer éxito. En comparación el wizard de doxygen es bastante más fácil de usar.

Además, doxygen entiende varios lenguajes de programación, aunque no es capaz de ofrecer diferentes temas. Aún así vale la pena reflexionar sobre qué herramienta usar.

Referencias

  • phpDocumentor – la herramienta descrita en este artículo
  • Doxygen – una alternativa a phpDocumentor
  • javadoc – un sistema de documentación para Java.
  • PHP – el lenguaje de programación que phpDocumentor documenta.
  • DocBook – un formato para escribir textos sin especificar su aparencia y que phpDocumentor usa para la documentación libre (tutoriales).

El lenguaje PHP viene con un instalador que se integra bien con el servidor web Apache bajo un entorno Windows. Sin embargo, es posible que el servicio de Apache ya no arranca después de la instalación de PHP. Recibes errores como “PHP Warning: PHP Startup: Unable to load dynamic library” en el fichero error.log del servidor Apache o cuando ejecutas php -i.

Esto es obviamente un error de PHP y podemos esperar que no todas las versiones presentan este problema. Yo lo observé con PHP 5.2. Este problema se debe a que algunos componentes (librerías DLL) tienen incompatibilidades.

Por esto motivo conviene sólo instalar los paquetes que realmente se usan. Esto se puede hacer de dos formas:

  1. Cambiar la instalación de PHP: Ir al panel de control, agregar o quitar programas, y cambiar/quitar la instalación de PHP. En el diálogo del instalador deshabilitar todos los componentes que no se usan.
  2. Editar el fichero php.ini. Buscar la cadena “extenstion=” y comenta todos los modulos que no necesitas.  Procura editar el fichero php.ini en el directorio correcto. En la configuración del servidor Apache httpd.conf encuentras (normalmente al final del fichero) el atributo PHPIniDir que indica la ruta al directorio de PHP.

Después de cambiar la instalación de PHP debes rearrancar el servidor web para hacer efectivo los cambios.

No todos los módulos causan problemas, pero cuando menos quedan mejor. Sin embargo, también arriesgamos correr en el problema contrario. Si PHP muestra un error “Call to undefined function“, entonces no tenemos cargado el módulo necesario que contiene esta función.

Busca esta función en el manual de PHP y comprueba en qué módulo se encuentra. Cuando tienes la página de la función abierta pulsa el enlace “Up” (hacía arriba) para encontrar en la tabla de contenidos la sección de instalación. Puedes habilitar un módulo en las dos formas mencionadas arriba: por el instalador de Windows o descomentando la línea “extenstion=” correspondiente en el fichero php.ini.

Escribe tu dirección de correo electrónico para suscribirte a este blog, y recibir notificaciones de nuevos mensajes por correo.

Únete a otros 56 seguidores

Archivos

diciembre 2019
L M X J V S D
« Nov    
 1
2345678
9101112131415
16171819202122
23242526272829
3031