Gestor de copias de seguridad incrementales en Linux

No Comments

Extracto

@pedroruizhidalg― Ya escribimos sobre las copias de seguridad en Linux, otra estupenda opción es rsync. Este comando (https://rsync.samba.org/) de los creadores de samba, tiene, en principio, está pensado para la sincronía remota de directorios. No obstante, su funcionalidad es muy amplia y puede ser dedicado a otros usos.

Read More…

data mining: técnicas y procedimientos

No Comments
técnicas de data mining

@pedroruizhidalg― A principios de 2002, el director del FBI, John Aschcroft, anunciaba que el Departamento de Justicia comenzaría a analizar las bases de datos comerciales referentes a los hábitos de consumo y preferencias de compra de los consumidores estadounidenses. Expertos aseguran que la intención del FBI es aunar toda la información que dispongan en una mega base de datos con el fin de poder hacer el seguimiento ―en USA es casi sospechoso pagar con efectivo repetidas veces, siempre lo hacen con tarjeta― del reguero de información que vamos dejando en nuestro día a día.

Permitidme ilustrarlo con un ejemplo. Fulano de Tal se levanta un sábado y mira su Facebook, contesta a lo que le ha llamado la atención. Consulta su cuenta de Twitter y retuitea la cosa tan graciosa que ha visto. Luego mira su email. Tras esto desayuna, se ducha y se va en moto hacia una gasolinera para poner 10€ de carburante. Va a unos grandes almacenes, en la búsqueda mira una gorra, la fotografía y la envía a su novia a ver qué le parece; se compra un pantalón vaquero y una camiseta para la playa. En la esquina de siempre, le espera su novia, con la que van a tomar algo a un bar de moda. Fotografían ambos la tapa, la mandan a sus redes sociales, algunos amigos contestan con un «like» otros retwitean. Aquí paramos el ejemplo. Ahora vamos a verlo desde el punto de vista de las redes sociales y quien tenga acceso a ellas.

Cuando accedemos a una de nuestras redes sociales, se graba todo, se graba, por ejemplo, si accedemos con móvil, tablet u ordenador de sobremesa, la hora y el lugar desde el que accedemos, el sistema operativo que usamos, el tipo de navegador, el ancho de nuestra página, la última página que hemos visitado, y, desde luego, nuestra IP, por tanto, también se está grabando si accedemos desde wifi o por conexión directa 3 ó 4G. Así que puede reconstruirse la historia que antes he descrito desde la siguiente óptica:

Nuestro protagonista se conecta el sábado a las 8:35 desde una ubicación determinada ―su casa― accedió mediante la aplicación de Facebook que tenía en el móvil, contestó a su amigo de la primo ―nosotros somos quienes describimos las relaciones en facebook― algo relacionado con Messi ―sí, esto también es catalogado, pues es muy importante para los gurús del márketing―, en Twitter se hace eco del chiste del presidente de gobierno ―ya conocemos su tendencia política―, conocemos quienes le han escrito a su cuenta de Google y cuál ha sido su reacción ante ese mail. Ha puesto 10€ de gasolina 98 a las 9:43 ―llegado el caso la gasolinera tiene cámaras― y lo ha pagado con la tarjeta de crédito de su banco número tal. No ha ido al centro comercial por el camino más corto, lo sabemos por el GPS de su móvil, aparca en la puerta de un bar. Usa la talla XXL de camiseta y de pantalón la XL en lo que ha invertido 44.54€ en total, pero con su tarjeta de crédito ―que caduca el próximo enero― lo pagará el mes que viene. En la puerta del bar donde tiene aparcada la moto, se encuentra con su novia a las 11:17 horas, y tomaron unas patatas bravas con cerveza ―ellos mismos lo tuitearon― a su amigo, Fran ―el de Huelva― le gusta la foto de las patatas bravas.

Y así… podíamos seguir hasta obtener un perfil completo de ese Don Nadie, que si bien no nos aporta nada especial, sí que unido al ejército de «donnadies» que, es verdad, llevan vidas grises aburridas y previsibles, sí podemos coleccionar todos esos datos porque a las empresas de márketing les interesa muchísimo.

Clave pública @pedroruizhidalg.pub.key
#aboutpedroruizhidalgo
[polldaddy poll=9120832]
♻ miotroblogsite ahorra papel

manual de gpg (PGP)

No Comments

Extracto

@pedroruizhidalg― PGP,  fue considerada por el gobierno de Estados Unidos como el mayor de los secretos. Tan secreto como el código de lanzamiento de los misiles nucleares. En buena medida, los códigos de los misiles dependían del código PGP. Un día, alguien publicó este código en una web. Aunque hubieron sospechosos no se pudo determinar quien era el «culpable».  La historia es apasionante, y algo farragosa. GPG es un sistema multiplataforma de gestión de llaves utilizado para el cifrado y firma digital de mensajes y archivos. Es un software libre liberado bajo la licencia GPL e implementa el estándar OpenPGP. GPG puede comunicarse con la versión actual de PGP y con cualquier otro sistema que implemente el estándar OpenPGP. GPG es un software híbrido de cifrado que combina tanto criptografía simétrica o de clave privada y criptografía asimétrica o de clave pública.

Nomenclatura y abreviaturas usadas

Criptografía simétrica.
Criptografía asimétrica.
RSA: En criptografía, RSA (Rivest, Shamir y Adleman) es un sistema criptográfico de clave pública desarrollado en 1977. Es el primer y más utilizado algoritmo de este tipo y es válido tanto para cifrar como para firmar digitalmente.
GPG: GnuPG.

Descripción

GPG es un sistema de criptografía de clave pública. Su código es libre, abierto y gratuito. Es multiplataforma, puede ser instalado en Linux, Windows y otros sistemas. De facto viene instalado en la mayoría de las distribuciones Linux. La instalación, si fuera necesario, en ubuntu sería así:

$ sudo apt-get install gnupg
$ gpg < /dev/null

Esta última línea dará un error. Gracias a la ejecución con ese error se han creado los directorios y los archivos de configuración necesarios. Continuamos con la instalación:

$ cp /usr/share/gnupg/options.skel ~/.gnupg/gpg.conf
$ gedit ~/.gnupg/gpg.conf &

Esto debería abrir el archivo de configuración de nuestro usuario. Buscamos la línea keyserver-options auto-key-retrieve y eliminamos el símbolo «#» que debe tener a la izquierda. Si no lo tuviera lo dejamos tal cual. Guardamos y salimos.

Creación de la pareja de claves
$ gpg --gen-key
gpg (GnuPG) 1.4.16; Copyright (C) 2013 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Por favor seleccione tipo de clave deseado:
 (1) RSA y RSA (predeterminado)
 (2) DSA y Elgamal
 (3) DSA (sólo firmar)
 (4) RSA (sólo firmar)
¿Su selección?: 

Si nuestra intención es tan solo firmar, cualquiera de las opciones nos sirve. Si, como es lógico, ademas, queremos cifrar mensajes de forma que únicamente el receptor pueda descifrarlo y trabajar con el contenido que le enviamos, recomiendo la opción 1.

DSA keypair will have 1024 bits.
ELG-E keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)
Requested keysize is 2048 bits

Una clave de 1024 es considerada como débil. 4096 puede ser lento. Mi clave personal es de 2048. Seguidamente nos reguntará acerca de la caducidad de la clave.

Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0)
Key does not expire at all
Is this correct? (y/N) y

Supongamos que se usa la clave para enviar trabajos de un curso que terminará en un año, nuestra respuesta sería 1y. 0 para que la clave no expire jamás.

Tras esto nos pedirá algunos datos personales. Es importante dar los correctos, ya que como veremos más adelante, nuestra clave terminará en servidores de claves a nivel mundial. Si nuestra clave no nos representa, simplemente no es confiable. En Linux, generalmente no vas a tener problemas. Si trabajas en Windows te recomiendo no usar acentos tanto en el nombre como en el resto de la información que suministres. Cuando suministres la información el programa te insta a que lo revises cuidadosamente. Así:

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
"Fulano De Tal (Mi empresa) <fulanodetal@miempresa.com>"
Real name: Fulano De Tal
Email address: fulanodetal@miempresa.com
Comment:
You selected this USER-ID:
"Fulano De Tal <fulanodetal@miempresa.com>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o

Podemos encontrar que en vez de pedir (O)kay pide (V)ale.

You need a Passphrase to protect your secret key.
Enter passphrase:
Repeat passphrase:

Si estamos trabajando desde un terminal gráfico, vuestro sistema os podría solicitar la contraseña en una ventana emergente. En cualquier caso, suministrar una contraseña que sea segura, que contenga números y símbolos, que no sea una palabra del diccionario, una fecha de nacimiento, o una matrícula. Esta palabra de paso es tu única defensa ante los posibles usos inadecuados. De ahí la importancia de que sea segura.

Ahora viene la parte que me gusta, GPG te invita a que hagas cosas con las ventanas, con el ratón con los discos duros, que abras carpetas, que mires fotos, compiles programas y cosas así. Es porque está calculando números aleatorios con nuestros procesos. Pudiera darse el caso que tengas que volver a repetir ver carpetas porque le falten datos aleatorios, tú simplemente sigue las instrucciones. Un comando que crea bastante entropía es:

$ ls / -laR

Ábrelo en otro terminal. Finalmente:

gpg: key E0CABB25 marked as ultimately trusted
public and secret key created and signed.
gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0 valid:
2 signed:
0 trust: 0-, 0q, 0n, 0m, 0f, 2u
pub
1024D/E0CBB25 2005-12-22
Key fingerprint = CEDB 1451 1F26 83D9 DB69 7ADA FFEE 1F18 E0CA 9E25
uid
Fulano De Tal <fulanodetal@miempresa.com>
sub
2048g/88885614 2016-12-31

Aquí es importante el número de usuario: E0CBB25, que es tu identidad en el anillo de claves. No te preocupes, siempre puedes volver a recuperarlo. No obstante también puedes usar como identidad tu correo o tu nombre.

¡IMPORTANTÍSIMO: Creación del certificado de revocación!

Seguidamente debes crear un certificado de revocación. Ya que en caso de que tus claves se vieran comprometidas, o tu contraseña averiguada (violada), debes tener las herramientas suficientes para revocar tus claves, tanto en tu propio ordenador con en los servidores de claves mundiales.

$ gpg --gen-revoke -armor --output revoke.key.asc E0CBB25

otra forma sería:

$ gpg --gen-revoke -armor --output revoke.key.asc fulanodetal@miempresa.com

y otra:

$ gpg --gen-revoke -armor --output revoke.key.asc 'Fulano de Tal'

Como resultado obtendrás un archivo llamado revoke.key.asc. La extensión asc es para indicarnos que la revocación la hemos creado en ascii y eso es debido a que hemos incluido en el comando el argumento –armor. Sin ese argumento la clave de revocación sería en formato binario, lo que nos supondría un problema para revocar mediante Internet, en caso de que nuestra clave esté en un servidor público.

Ya tenemos creada nuestro par de claves con el certificado de revocación.

Ejecución

La primera acción a realizar sería proteger nuestro certificado de revocación. Como nunca sabemos en qué circunstancias vamos a tener que realizar la revocación, si desde nuestro ordenador, desde otro, con nuestro sistema operativo, con Windows… en fin, hablamos de una circunstancia futura. Vamos a crear un archivo zip al que vamos luego cifraremos de forma simétrica.

$ zip revoke.zip revoke.key.asc
$ gpg -c revoke.zip

Desgraciadamente, el cifrado simétrico es el más débil de los cifrados, se trata de un archivo con una clave. Quien sepa la contraseña tendrá acceso al contenido. Esto lo realizamos para guardar el archivo en un dispositivo seguro, un cd, un dvd, un pen drive… Algo al que no tenga acceso nadie.

Ahora debemos borrar nuestro archivo revoke.key.asc de forma cuidadosa. Ya que un simple borrado no nos garantiza la eliminación del contenido del archivo en disco. Tan solo, lo elimina de los índices, si bien la información sigue ―o puede seguir― estando ahí.

Difusión de la clave pública

Vamos a crear un archivo en ascii para la difusión de la clave pública. Mediante el siguente comando.

$ gpg -a --export --output mi.pkey.asc fulanodetal@miempresa.com

o bien listando las claves que existen en nuestro sistema y eligiendo el id de usuario. Así:

$ gpg --list-keys
$ gpg -a --export --output mi.pkey.asc E0CBB25

El archivo mi.pkey.asc es nuestra clave. Obviamente el nombre es arbitrario, puedes elegir otro que te guste o se adecúe mejor a tus nemotécnicos.

Ahora tenemos varias opciones:

  • Copiar el archivo en un CD para entregar en mano a nuestros contactos.
  • Enviar nuestro archivo como adjunto a nuestros contactos como adjunto en emails.
  • Publicar en nuestra web nuestra clave pública. Mira la mía.
  • Enviar la clave a un servidor de claves.
    • Yo uso pgp.rediris.es. Redirige a http://www.rediris.es/keyserver/
    • Si en la cadena de búsqueda introducís mi nombre ‘Pedro Ruiz Hidalgo’ aparecen dos entradas. Ambas son mías. La que corresponde a 6-9-2003 ya no me pertenece porque perdí la clave de revocación. Eso estará ahí por los siglos de los siglos.
    • El servidor de rediris, igual que otros, comunica todas las identidades a otros servidores. De esta forma es fácil identificarnos para poder enviarnos mensajes cifrados.
    • Podemos crear nuestra identidad copiando la totalidad de nuestro archivo de clave pública y enviarlo desde web. Otra forma sería así:
$ gpg --keyserver pgp.mit.edu --send-keys E0CABB25
gpg: sending key E0CABB25 to hkp server pgp.mit.edu

La mayoría de los servidores de claves están conectados entre sí. Siempre puedes revocar la clave con el certificado de revocación. Si lo perdieras, la clave deja de pertenecerte. Así de crudo.

Importar la clave de pública de un amigo a nuestro anillo de claves

Supongamos que Silvia me envía un certificado. La voy a incluir en mi anillo de claves, pero como no la conozco en persona no firmaré su clave.

$ gpg --import silvia.pkey.asc
gpg: key E02BF32C: public key "Silvia Pérez <silvia.perez@empresadesilvia.com>" imported
gpg: Total number processed: 1
gpg:
imported: 1

En todo esto hay un punto débil. Que sería fabricar una clave con una identidad falsa y hacerla circular. De forma que os recomiendo que hagáis un uso muy paranóico de la seguridad de las claves.

La huella digital

Cuando importemos el certificado, antes darle carta de credibilidad, usamos la huella digital. Esta huella digital es fácil ser leída por teléfono ―siempre que la llamada la efectuémos nosotros―, entregada en mano, o por cualquier «canal seguro» que no nos dé absoluta confianza.

Listar una huella digital:

$ pgp --fingerprint 'Silvia'
pub   2048R/E02BF32C 2015-10-17
      Huella de clave = AC9E F5FD 1888 5BDE 0C6A  CAB· CE69 CDEF 20BA 9950
uid                  Silvia (Para propósitos de encriptación del sistema) <silvia.perez@laempresade silvia.com>
sub   2048R/E02BF32C 2015-10-17

Si la huella de la clave, transmitida por un «canal seguro» es correcta (AC9E F5FD 1888 5BDE 0C6A CAB· CE69 CDEF 20BA 9950) podemos firmar la clave de Silvia. Así:

$ gpg --sing-key silvia.perez@laempresadesilvia.com

O bien con su ID de usuario. GPG nos mostrará en pantalla información de Silvia, si estamos seguros pulsamos “sí”, no obstante, aún gpg duda de que quien esté tratando de firmar la clave sea realmente el usuario de así que pedirá la palabra de paso de quien está firmando. A partir de este momento la clave de Silvia queda unida a la mía, y, si yo envío mi clave pública estaré también enviando la de Silvia.

Firmar un documento
$ gpg --sign midocumento.doc

Pedirá la clave del usuario. Esto genera un documento llamado “midocumento.doc.gpg”. Este archivo .gpg  podemos entregarlo. Para comprobar la firma:

$ pgp midocumento.doc.gpg
gpg: Signature made vie 23 feb 2015 19:00:43 CET using DSA key ID E0CAFE95
gpg: Good signature from "Fulano de tal <fulanodetal@miempresa.com>"

Tras la comprobación de la firma tenemos otra vez los dos documentos. El original y el firmado pues gpg lo ha separado.

Cifrado para un destinatario en concreto

Expresamos en el recipiente “-r” la identidad del destinatario, bien mediante su Id. de usuario, su correo o simplemente su nombre. Si quiero encriptar un documento para que sea leído exclusivamente por Silvia:

$ gpg --encript -r Silvia documento.doc
Cifrado para varios destinatarios determinados

Ahora, además de cifrar para Silvia, voy a hacer que Antonio tenga también una copia de ese documento cifrado, pues se lo enviaré a ambos por correo. Así:

$ gpg --encrypt -r Silvia -r Antonio [-r otro] documento.doc

Epílogo

Estas son las operaciones básicas con gpg (PGP). Incluyo un buen manual de José Luis Díaz, GnuPG, realizado en 2006.

Espero y deseo que este artículo haya sido de utilidad. Es muy importante para la continuación de trabajos de calidad recibir algún tipo de feedback por parte de los lectores: es decir, responde con comentarios, evalúa la calidad del trabajo con el sistema de estrellas, comparte con tus redes sociales, da me gusta, marca el blog como favorito. Son pequeños gestos que ayudan a mantener el trabajo de creación.

Clave pública: @pedroruizhidalg.pub.key

#aboutpedroruizhidalgo
[polldaddy poll=9120832]
♻ miotroblogsite ahorra papel

Controlador respondiendo a parámetros para Query

No Comments

Extracto

Controlador averigua si existe una tabla; si no existe, la crea e introduce datos de prueba; para, posteriormente, responder con datos dinámicos pasados como parámetro desde la URL.

Abreviaturas usadas

  • MVC, paradigma Modelo Vista Controlador
  • CI, CodeIgniter

Descripción

A través del grupo Code Igniter PHP Framework ESPAÑOL, al cual pertenezco, un miembro me pide ayuda por privado. Tras dos días de, materialmente, no poder atender su solicitud por falta de tiempo me pongo en contacto con él para indicarle que haría esta entrada.

Esta entrada es mejorable en cuanto a la pureza del MVC porque en esta entrada de blog no me atengo a ella, ya que no uso, como vistas dinámicas, ni un modelo. Sirva la excusa del tiempo que no tengo.

Archivo .htaccess

<ifmodule mod_rewrite.c>
    RewriteEngine On 
    RewriteCond %{REQUEST_FILENAME} !-f 
    RewriteCond %{REQUEST_FILENAME} !-d 
    RewriteRule ^(.*)$ ./index.php/$1 [L] 
</IfModule>
<ifmodule !mod_rewrite.c>
    ErrorDocument 404 /index.php 
</IfModule>

<ifmodule mod_gzip.c>
  mod_gzip_on Yes
  mod_gzip_dechunk Yes
  mod_gzip_item_include file .(html?|txt|css|js|php|pl)$
  mod_gzip_item_include handler ^cgi-script$
  mod_gzip_item_include mime ^text/.*
  mod_gzip_item_include mime ^application/x-javascript.*
  mod_gzip_item_exclude mime ^image/.*
  mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
</ifModule>


<ifmodule mod_expires.c>
  ExpiresActive On
  ExpiresDefault "access plus 1 seconds"
  ExpiresByType text/html "access plus 1 seconds"
  ExpiresByType image/gif "access plus 2592000 seconds"
  ExpiresByType image/jpeg "access plus 2592000 seconds"
  ExpiresByType image/png "access plus 2592000 seconds"
  ExpiresByType text/css "access plus 604800 seconds"
  ExpiresByType text/javascript "access plus 216000 seconds"
  ExpiresByType application/x-javascript "access plus 216000 seconds"
</ifModule>

archivo /config/database.php

$active_group = 'default';
$active_record = TRUE;

$db['default']['hostname'] = 'localhost';
$db['default']['username'] = 'usuario';
$db['default']['password'] = 'clavesupersecretadelaestrelladelamuerte';
$db['default']['database'] = 'blog';
$db['default']['dbdriver'] = 'mysql';
$db['default']['dbprefix'] = '';
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = TRUE;
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = '';
$db['default']['char_set'] = 'utf8';
$db['default']['dbcollat'] = 'utf8_general_ci';
$db['default']['swap_pre'] = '';
$db['default']['autoinit'] = TRUE;
$db['default']['stricton'] = FALSE;

archivo /controllers/parametro.php

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Parametro extends CI_Controller {

 public function __construct()
 {
  parent::__construct();   // heredo clases y funcionalidades de Parent
  $this->load->database();   // cargo la clase base de datos según config/database.php
  $this->load->library('table');  // cargo la clase table
 }

 /**
  * Esto es un ejemplo de controlador 
  * para pasar parámetros a las consultas
  * @pedroruizhidalg
  * http://phpdehoy.blogspot.com
  */


 public function index()
 {
  $this->echo_parametro();    // compruebo que funciona el index
  $this->load->dbforge();     // cargo la clase dbforge para crear tablas dinámicamente, y otras cosas...
  if(!$this->existe_table('parametro')); // compruebo la existencia de la tabla
 }

 public function autor($nombre_autor)
 {
  echo "buscando las entradas del blog cuyo autor es '$nombre_autor'";
  echo $this->busca_autor($nombre_autor);
 }

 /**
 *
 * PRIVATE FUNCTIONS 
 *
 **/

 private function existe_table($tabla)
 {
  echo utf8_decode("Estoy probando existencia de la tabla '$tabla'
");
  if(!$this->db->table_exists($tabla))
  {

   echo 'necesario crear tabla
';
   $campos = array(
    'blog_titulo' => array(
    'type' => 'VARCHAR',
    'constraint' => '100',
    ),
    'blog_autor' => array(
    'type' =>'VARCHAR',
    'constraint' => '100',
    'default' => 'Batman',
    ),
    'blog_descripcion' => array(
    'type' => 'TEXT',
    'null' => TRUE,
    ),
   );
   $this->dbforge->add_field('id',TRUE); // creo el ID (TRUE=primary, auto_increment);
   $this->dbforge->add_field($campos);  // añado la estructura de la tabla del array $campos
   $this->dbforge->create_table($tabla); // creo la tabla
   echo 'tabla creada
';
   $this->insert_dummy($tabla);
   return TRUE;
  } else {
   echo "No es necesario crear la tabla '$tabla', ya estaba creada
";
   return FALSE;
  }
 }

 private function insert_dummy($tabla)
 {
  echo "Introduciendo datos de prueba en tabla '$tabla'
";
  $data  = array(
   'blog_titulo'  => 'titulo Primero',
   'blog_autor'  => 'Pedro',
   'blog_descripcion' => 'descripcion del titulo Primero'
   );
  $this->db->insert($tabla,$data);

  $data  = array(
   'blog_titulo'  => 'titulo Segundo',
   'blog_autor'  => 'Antonio',
   'blog_descripcion' => 'descripcion del titulo Segundo'
   );
  $this->db->insert($tabla,$data);

  $data  = array(
   'blog_titulo'  => 'titulo Tercero',
   'blog_autor'  => 'Pedro',
   'blog_descripcion' => 'descripcion del titulo Tercero'
   );
  $this->db->insert($tabla,$data);

  $data  = array(
   'blog_titulo'  => 'titulo Cuarto',
   'blog_autor'  => 'Antonio',
   'blog_descripcion' => 'descripcion del titulo Cuarto'
   );
  $this->db->insert($tabla,$data);

  echo 'datos de prueba introducidos
';
 }

 private function echo_parametro()
 {
  echo utf8_decode('Parámetro

');
 }

 private function busca_autor($nombre_autor)
 {
  $consulta  = "select * from parametro where blog_autor='$nombre_autor'";

  $qry  = $this->db->query($consulta);
  if($qry->num_rows() > 0)
  {
   $tmpl = array ( 'table_open' => '<table border="1" cellpadding="2"cellspacing="1" class="mytable">' );
   $this->table->set_template($tmpl);
   foreach ($qry->result() as $row) 
   {
    $this->table->add_row(array($row->blog_titulo,$row->blog_autor,$row->blog_descripcion));
   }
   return $this->table->generate();
  } else { // si no hay datos
   echo "
sin datos";
  }
 }

}

/* End of file parametro.php */
/* Location: ./application/controllers/parametro.php */

Ejecución

  1. Asegúrate que tu instalación de CodeIgniter esté funcionando.
  2. Copia a sus respectivos directorios los archivos /config/database.php y /controllers/parametro.php.
  3. Copia el archivo .htaccess a la raiz de tu instalación de CI.
  4. Dirígete a tu ubicación así http://miservidor/parametro.
  5. Comprueba que la tabla parametro existe y tiene datos
  6. Ejecuta la dirección http://miservidor/parametro/autor/pedro
  7. comprueba que recibes datos dinámicos
  8.  http://miservidor/parametro/autor/antonio
  9. ejecuta el paso 7 otra vez.

Epílogo

Espero que os sirva de ayuda. En cualquier caso estaré encantado de poder atender vuestros comentarios. Tampoco estaría mal que hiciérais +1… 😉
Categories: codeigniter, instalaciones, php

CodeIgniter de un vistazo

No Comments

Extracto

Ver algunas de las funcionalidades de CodeIgniter junto con sus características principales.

CodeIgniter es un framework de aplicación

CI es un conjunto de herramientas para construir aplicaciones web usando PHP. Su objetivo es permitir desarrollar proyectos más rápido de lo que lo harías si empezaras de cero. CI provee un rico conjunto de librerías para las tareas más comunes, como también, una interfaz y estructura lógica para acceder sin limitaciones a esas librerías. CI te permite focalizar tu esfuerzo en el desarrollo de tu aplicación minimizando el código necesario para ello. CI es libre y publicado bajo la licencia Apache/BSD-style de Código Abierto, por lo que puedes usarlo dónde y para lo que te plazca.

CodeIgniter es Ligero

Realmente ligero. El core requiere sólo un par de pequeñas librerías. Esto contrasta con otros frameworks que necesitan significativamente más recursos. Adicionalmente las librerías son cargadas dinámicamente según requerimiento, basado en tus necesidades y dependiendo de tus procesos. En su web retan a encontrar otro framework más rápido… Aunque yo no quiero entrar en eso.

CodeIgniter usa el modelo M-V-C

CI usa el enfoque Modelo-Vista-Controlador, que permite una auténtica y verdadera separación entre la lógica de nuestra aplicación y su presentación. Esto es especialmente importante para proyectos que son acometidos entre desarrolladores y diseñadores. Más adelante describiré Modelo-Vista-Controlador con todo lujo de detalles.

CodeIgniter genera URL limpias (amigables)

Las URLs generadas por CI son limpias y amigables para los motores de búsqueda. Mejor dicho, usa el estándard “query string” para la sintaxis de su URL y sus procesos simétricos en el sistema.
Por ejemplo:
mi_servidor.com/cliente/pedido/345

Paquetes de una sola tacada

CI viene con una importante cantidad de librerías, que son comúnmente necesarias, como abstracción de acceso a bases de datos, envío de mails, validación de formularios, mantenimiento de sesiones, manipulación de imágenes, trabajo con datos XML-RPC y más…

CodeIgniter es extensible

El sistema es fácilmente extensible por el programador para usar sus propias librerías. Trataremos esto más adelante.

CodeIgniter no requiere un motor de plantillas

Aunque CI trae un sistema de plantillas para la interpretación de variables y bucles, el framework no te fuerza a usarlas. Haciendo que las vistas sean a su vez ficheros php y aprovechando la potencia de todo el lenguaje. Generalmente esto no es necesario ya que podemos afirmar que con la correcta arquitectura de programación PHP ya viene de fábrica con su propio motor de plantillas. Como veremos más adelante.
Por ejemplo:
<ul>
<?php foreach ($addressbook as $name):?>
<li><?=$name?></li>
<?php endforeach; ?>
</ul>

y compáralo con

<ul>
{foreach from=$addressbook item="name"}
<li>{$name}</li>
{/foreach}
</ul>
Categories: codeigniter, instalaciones, php Tags: Etiquetas: , ,

Instalación de CodeIgniter

No Comments

Extracto

CodeIgniter es un fantástico framework PHP para el desarrollo de aplicaciones sobre tecnología web. Permite desarrollar mucho más rápido nuestros proyectos proporcionándote un entorno de trabajo muy probado y aportando un soporte que preferirás al empezar tú todo desde cero.
  • Su ejecución es excepcionalmente rápida.
  • Áltamente configurable.
  • No requiere que uses la línea de comandos.
  • No tienes por qué aprender un lenguaje de plantillas (aunque está disponible si así lo deseas).
  • Evitas la complejidad ofreciendo soluciones simples y modulares a problemas más complejos que se irán ensamblando con su clara arquitectura.

Historia, pero muy rápidamente

CodeIgniter ha sido propiedad de EllisLab que abandonó el desarrollo del proyecto por tenerlo ya amortizado. Ahora el proyecto de desarrollo está en manos de British Columbia Institute of Technology, quien está en fase de desarrollo de la versión 3.x, a la que no acudiré hasta que se dé por terminada esta release.

Descarga de la versión 2.2.0 (estable)

Esta es la actual versión estable del framework. La primera 2.x fue publicada en enero de 2011, sufrió una importante actualización en otoño de 2011 y será abandonada por parte de EllisLab en julio de 2014, pero como he comentado en la historia toma el testigo la BCIT.

Instalación

  1. Desempaqueta el archivo zip. Si tu servidor te permite mediante el panel de control desempaquetar archivos zip, no lo desempaquetes, lo subes a tu servidor comprimido y lo descomprimes en tu carpeta remota.
  2. Sube los archivos y carpetas del contenido del zip a tu servidor o lo desempaquetas arriba como he descrito en el apartado anterior.
  3. Con un editor de textos abre el archivo application/config/config.php. Aquí pondremos la base URL, lo describo con más detalle más bajo.
  4. Si necesitas usar una base de datos, abre el archivo application/config/database.php con un editor de textos para la configuración de la base de datos. Lo describo con más detalle más abajo.

application/config/config.php

Muestro mi propio archivo de configuración. Más adelante explicaré la traducción a los distintos idiomas de momento me quedo con inglés.
Importante:
  • linea 17 base_url.
  • línea 227 encription_key. Te recomiendo que no la cambies una vez establecida.
<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

/*
|--------------------------------------------------------------------------
| Base Site URL
|--------------------------------------------------------------------------
|
| URL to your CodeIgniter root. Typically this will be your base URL,
| WITH a trailing slash:
|
| http://example.com/
|
| If this is not set then CodeIgniter will guess the protocol, domain and
| path to your installation.
|
*/
$config['base_url'] = 'http://ladirecciondemiservidor.com';

/*
|--------------------------------------------------------------------------
| Index File
|--------------------------------------------------------------------------
|
| Typically this will be your index.php file, unless you've renamed it to
| something else. If you are using mod_rewrite to remove the page set this
| variable so that it is blank.
|
*/
$config['index_page'] = 'index.php';

/*
|--------------------------------------------------------------------------
| URI PROTOCOL
|--------------------------------------------------------------------------
|
| This item determines which server global should be used to retrieve the
| URI string.  The default setting of 'AUTO' works for most servers.
| If your links do not seem to work, try one of the other delicious flavors:
|
| 'AUTO'   Default - auto detects
| 'PATH_INFO'  Uses the PATH_INFO
| 'QUERY_STRING' Uses the QUERY_STRING
| 'REQUEST_URI'  Uses the REQUEST_URI
| 'ORIG_PATH_INFO' Uses the ORIG_PATH_INFO
|
*/
$config['uri_protocol'] = 'AUTO';

/*
|--------------------------------------------------------------------------
| URL suffix
|--------------------------------------------------------------------------
|
| This option allows you to add a suffix to all URLs generated by CodeIgniter.
| For more information please see the user guide:
|
| http://codeigniter.com/user_guide/general/urls.html
*/

$config['url_suffix'] = '';

/*
|--------------------------------------------------------------------------
| Default Language
|--------------------------------------------------------------------------
|
| This determines which set of language files should be used. Make sure
| there is an available translation if you intend to use something other
| than english.
|
*/
$config['language'] = 'english';

/*
|--------------------------------------------------------------------------
| Default Character Set
|--------------------------------------------------------------------------
|
| This determines which character set is used by default in various methods
| that require a character set to be provided.
|
*/
$config['charset'] = 'UTF-8';

/*
|--------------------------------------------------------------------------
| Enable/Disable System Hooks
|--------------------------------------------------------------------------
|
| If you would like to use the 'hooks' feature you must enable it by
| setting this variable to TRUE (boolean).  See the user guide for details.
|
*/
$config['enable_hooks'] = FALSE;


/*
|--------------------------------------------------------------------------
| Class Extension Prefix
|--------------------------------------------------------------------------
|
| This item allows you to set the filename/classname prefix when extending
| native libraries.  For more information please see the user guide:
|
| http://codeigniter.com/user_guide/general/core_classes.html
| http://codeigniter.com/user_guide/general/creating_libraries.html
|
*/
$config['subclass_prefix'] = 'MY_';


/*
|--------------------------------------------------------------------------
| Allowed URL Characters
|--------------------------------------------------------------------------
|
| This lets you specify with a regular expression which characters are permitted
| within your URLs.  When someone tries to submit a URL with disallowed
| characters they will get a warning message.
|
| As a security measure you are STRONGLY encouraged to restrict URLs to
| as few characters as possible.  By default only these are allowed: a-z 0-9~%.:_-
|
| Leave blank to allow all characters -- but only if you are insane.
|
| DO NOT CHANGE THIS UNLESS YOU FULLY UNDERSTAND THE REPERCUSSIONS!!
|
*/
$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-';


/*
|--------------------------------------------------------------------------
| Enable Query Strings
|--------------------------------------------------------------------------
|
| By default CodeIgniter uses search-engine friendly segment based URLs:
| example.com/who/what/where/
|
| By default CodeIgniter enables access to the $_GET array.  If for some
| reason you would like to disable it, set 'allow_get_array' to FALSE.
|
| You can optionally enable standard query string based URLs:
| example.com?who=me&what=something&where=here
|
| Options are: TRUE or FALSE (boolean)
|
| The other items let you set the query string 'words' that will
| invoke your controllers and its functions:
| example.com/index.php?c=controller&m=function
|
| Please note that some of the helpers won't work as expected when
| this feature is enabled, since CodeIgniter is designed primarily to
| use segment based URLs.
|
*/
$config['allow_get_array']  = TRUE;
$config['enable_query_strings'] = FALSE;
$config['controller_trigger'] = 'c';
$config['function_trigger']  = 'm';
$config['directory_trigger'] = 'd'; // experimental not currently in use

/*
|--------------------------------------------------------------------------
| Error Logging Threshold
|--------------------------------------------------------------------------
|
| If you have enabled error logging, you can set an error threshold to
| determine what gets logged. Threshold options are:
| You can enable error logging by setting a threshold over zero. The
| threshold determines what gets logged. Threshold options are:
|
| 0 = Disables logging, Error logging TURNED OFF
| 1 = Error Messages (including PHP errors)
| 2 = Debug Messages
| 3 = Informational Messages
| 4 = All Messages
|
| For a live site you'll usually only enable Errors (1) to be logged otherwise
| your log files will fill up very fast.
|
*/
$config['log_threshold'] = 0;

/*
|--------------------------------------------------------------------------
| Error Logging Directory Path
|--------------------------------------------------------------------------
|
| Leave this BLANK unless you would like to set something other than the default
| application/logs/ folder. Use a full server path with trailing slash.
|
*/
$config['log_path'] = '';

/*
|--------------------------------------------------------------------------
| Date Format for Logs
|--------------------------------------------------------------------------
|
| Each item that is logged has an associated date. You can use PHP date
| codes to set your own date formatting
|
*/
$config['log_date_format'] = 'Y-m-d H:i:s';

/*
|--------------------------------------------------------------------------
| Cache Directory Path
|--------------------------------------------------------------------------
|
| Leave this BLANK unless you would like to set something other than the default
| system/cache/ folder.  Use a full server path with trailing slash.
|
*/
$config['cache_path'] = '';

/*
|--------------------------------------------------------------------------
| Encryption Key
|--------------------------------------------------------------------------
|
| If you use the Encryption class or the Session class you
| MUST set an encryption key.  See the user guide for info.
|
*/
$config['encryption_key'] = 'frase super secreta muy secreta secretísima';

/*
|--------------------------------------------------------------------------
| Session Variables
|--------------------------------------------------------------------------
|
| 'sess_cookie_name'  = the name you want for the cookie
| 'sess_expiration'   = the number of SECONDS you want the session to last.
|   by default sessions last 7200 seconds (two hours).  Set to zero for no expiration.
| 'sess_expire_on_close' = Whether to cause the session to expire automatically
|   when the browser window is closed
| 'sess_encrypt_cookie'  = Whether to encrypt the cookie
| 'sess_use_database'  = Whether to save the session data to a database
| 'sess_table_name'   = The name of the session database table
| 'sess_match_ip'   = Whether to match the user's IP address when reading the session data
| 'sess_match_useragent' = Whether to match the User Agent when reading the session data
| 'sess_time_to_update'  = how many seconds between CI refreshing Session Information
|
*/
$config['sess_cookie_name']  = 'ci_session';
$config['sess_expiration']  = 7200;
$config['sess_expire_on_close'] = FALSE;
$config['sess_encrypt_cookie'] = FALSE;
$config['sess_use_database'] = FALSE;
$config['sess_table_name']  = 'ci_sessions';
$config['sess_match_ip']  = FALSE;
$config['sess_match_useragent'] = TRUE;
$config['sess_time_to_update'] = 300;

/*
|--------------------------------------------------------------------------
| Cookie Related Variables
|--------------------------------------------------------------------------
|
| 'cookie_prefix' = Set a prefix if you need to avoid collisions
| 'cookie_domain' = Set to .your-domain.com for site-wide cookies
| 'cookie_path'   =  Typically will be a forward slash
| 'cookie_secure' =  Cookies will only be set if a secure HTTPS connection exists.
|
*/
$config['cookie_prefix'] = "";
$config['cookie_domain'] = "";
$config['cookie_path']  = "/";
$config['cookie_secure'] = FALSE;

/*
|--------------------------------------------------------------------------
| Global XSS Filtering
|--------------------------------------------------------------------------
|
| Determines whether the XSS filter is always active when GET, POST or
| COOKIE data is encountered
|
*/
$config['global_xss_filtering'] = FALSE;

/*
|--------------------------------------------------------------------------
| Cross Site Request Forgery
|--------------------------------------------------------------------------
| Enables a CSRF cookie token to be set. When set to TRUE, token will be
| checked on a submitted form. If you are accepting user data, it is strongly
| recommended CSRF protection be enabled.
|
| 'csrf_token_name' = The token name
| 'csrf_cookie_name' = The cookie name
| 'csrf_expire' = The number in seconds the token should expire.
*/
$config['csrf_protection'] = FALSE;
$config['csrf_token_name'] = 'csrf_test_name';
$config['csrf_cookie_name'] = 'csrf_cookie_name';
$config['csrf_expire'] = 7200;

/*
|--------------------------------------------------------------------------
| Output Compression
|--------------------------------------------------------------------------
|
| Enables Gzip output compression for faster page loads.  When enabled,
| the output class will test whether your server supports Gzip.
| Even if it does, however, not all browsers support compression
| so enable only if you are reasonably sure your visitors can handle it.
|
| VERY IMPORTANT:  If you are getting a blank page when compression is enabled it
| means you are prematurely outputting something to your browser. It could
| even be a line of whitespace at the end of one of your scripts.  For
| compression to work, nothing can be sent before the output buffer is called
| by the output class.  Do not 'echo' any values with compression enabled.
|
*/
$config['compress_output'] = FALSE;

/*
|--------------------------------------------------------------------------
| Master Time Reference
|--------------------------------------------------------------------------
|
| Options are 'local' or 'gmt'.  This pref tells the system whether to use
| your server's local time as the master 'now' reference, or convert it to
| GMT.  See the 'date helper' page of the user guide for information
| regarding date handling.
|
*/
$config['time_reference'] = 'local';


/*
|--------------------------------------------------------------------------
| Rewrite PHP Short Tags
|--------------------------------------------------------------------------
|
| If your PHP installation does not have short tag support enabled CI
| can rewrite the tags on-the-fly, enabling you to utilize that syntax
| in your view files.  Options are TRUE or FALSE (boolean)
|
*/
$config['rewrite_short_tags'] = FALSE;


/*
|--------------------------------------------------------------------------
| Reverse Proxy IPs
|--------------------------------------------------------------------------
|
| If your server is behind a reverse proxy, you must whitelist the proxy IP
| addresses from which CodeIgniter should trust the HTTP_X_FORWARDED_FOR
| header in order to properly identify the visitor's IP address.
| Comma-delimited, e.g. '10.0.1.200,10.0.1.201'
|
*/
$config['proxy_ips'] = '';


/* End of file config.php */
/* Location: ./application/config/config.php */

application/config/database.php

<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/*
| -------------------------------------------------------------------
| DATABASE CONNECTIVITY SETTINGS
| -------------------------------------------------------------------
| This file will contain the settings needed to access your database.
|
| For complete instructions please consult the 'Database Connection'
| page of the User Guide.
|
| -------------------------------------------------------------------
| EXPLANATION OF VARIABLES
| -------------------------------------------------------------------
|
| ['hostname'] The hostname of your database server.
| ['username'] The username used to connect to the database
| ['password'] The password used to connect to the database
| ['database'] The name of the database you want to connect to
| ['dbdriver'] The database type. ie: mysql.  Currently supported:
     mysql, mysqli, postgre, odbc, mssql, sqlite, oci8
| ['dbprefix'] You can add an optional prefix, which will be added
|     to the table name when using the  Active Record class
| ['pconnect'] TRUE/FALSE - Whether to use a persistent connection
| ['db_debug'] TRUE/FALSE - Whether database errors should be displayed.
| ['cache_on'] TRUE/FALSE - Enables/disables query caching
| ['cachedir'] The path to the folder where cache files should be stored
| ['char_set'] The character set used in communicating with the database
| ['dbcollat'] The character collation used in communicating with the database
|     NOTE: For MySQL and MySQLi databases, this setting is only used
|      as a backup if your server is running PHP < 5.2.3 or MySQL < 5.0.7
|     (and in table creation queries made with DB Forge).
|      There is an incompatibility in PHP with mysql_real_escape_string() which
|      can make your site vulnerable to SQL injection if you are using a
|      multi-byte character set and are running versions lower than these.
|      Sites using Latin-1 or UTF-8 database character set and collation are unaffected.
| ['swap_pre'] A default table prefix that should be swapped with the dbprefix
| ['autoinit'] Whether or not to automatically initialize the database.
| ['stricton'] TRUE/FALSE - forces 'Strict Mode' connections
|       - good for ensuring strict SQL while developing
|
| The $active_group variable lets you choose which connection group to
| make active.  By default there is only one group (the 'default' group).
|
| The $active_record variables lets you determine whether or not to load
| the active record class
*/

$active_group = 'default';
$active_record = TRUE;

$db['default']['hostname'] = 'localhost';
$db['default']['username'] = 'nombre_de_usuario';
$db['default']['password'] = 'shhhh calla calla';
$db['default']['database'] = 'Nombredelabasededatos';
$db['default']['dbdriver'] = 'mysql';
$db['default']['dbprefix'] = '';
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = TRUE;
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = '';
$db['default']['char_set'] = 'utf8';
$db['default']['dbcollat'] = 'utf8_general_ci';
$db['default']['swap_pre'] = '';
$db['default']['autoinit'] = TRUE;
$db['default']['stricton'] = FALSE;


/* End of file database.php */
/* Location: ./application/config/database.php */
Categories: codeigniter, instalaciones, php