Algo de encriptación

abril 6, 2014

PHP tiene una fabulosa librería de encriptación llamada mcrypt. Si no tienes esta librería instalada en tu servidor, o eres de esos paranoicos que desea ver en todo momento como se generan los mensajes codificados, aquí tienes un sencilla librería. Puedes usarla por ejemplo, para encriptar cookies o pequeños mensajes entre usuarios.

La librería tiene 3 funciones útiles:
libreta_de_un_solo_uso($texto) que genera una clave aleatorio con la misma longitud que el texto. Mas información en la wikipedia.
encripta($texto,$llave) y desencripta($texto,$llave)
Encripta y desencripta un texto.La llave puede ser una frase (cuanto mas larga mejor) o puedes generar una libreta de un solo uso con la primera función.
-Hay una cuarta función, cipher, que es en realidad la que hace el trabajo duro.

Leer el resto de esta entrada »

Unas de las preguntas del test de ejemplo de la certificación ZEND es similar a:

1:function f(){
2: $g= 20;
3: global $g;
4: echo $g;
5:}
6:$g=30;
7:f(); //

Para responderla correctamente tienes que entender que el ámbito de global no es la función entera, sino la que empieza en la linea 3. La variable local creada en la linéa 2, es sobre-escrita la línea 3, como una referencia a $GLOBALS['g']. El resultado es “30”;
Parece fácil, pero ¿cuál es el resultado de?


1:function f(){
2: $g= 20;
3: global $g;
4: unset($g);
5:}
6:$g=30;
7:f();
8:echo $g;

¿un error? ¿20 ?
El resultado es 30, ya que la línea 4, no destruye la variable global $GLOBALS['g'] sino $g.
Si dentro de una función quieres destruir una variable global debes poner:

function foo(){
..
unset($GLOBALS['NOMBRE_DE_LA_VARIABLE_A_BORRAR']);
..
}

Y que pasa si dentro de una función creamos y destruimos una variable global

function f(){
global $g;
$g=20;
unset($g);
}
f();
echo $g;

¿el resultado es un error o 20? Global es una construcción del lenguaje que equivaldría mas o menos a:

if ( !isset($GLOBALS['g']) {
$GLOBALS['g']= NULL;
}
$g= &$GLOBALS['g'];

Así que el resultado es, 20.

Si quieres conocer certificarte en PHP, deberías saber:
– empty evalúa una variable y nos dice si esta vacía: es 0, “0”, “” (cadena vacía), null, o un array vacío. (boolean) evalúa expresiones del mismo modo que empty, aunque al revés: devuelve true para cualquier valor que no sea 0,”0″,””, NULL, o un array vacío.
– is_null devuelve true si la expresión es NULL, igual que isset que evalua si la variable es null, o no ha sido inicializada.

Lo interesante:
– empty no es una función. Es un construcción del lenguaje; admite un único parámetro que debe ser una variable, la clave de un array o una propiedad.
– isset tampoco es una función, pero la gente olvida que puede aceptar mas de un parámetro, aunque todos deben ser variables (como empty).
– empty e isset no generan error al evaluar una variable inexistente.
– is_null y (boolean) si generan un error al evaluar una variable inexistente.

Resumiendo:

empty(20); // GENERA ERROR
empty(UNA_CONSTANTE); // GENERA ERROR

isset(E_WARNING) ; // GENERA_ERROR
isset($a,$b[1],$c->p) ; // es valido!!

is_null($a) // GENERA un warning si $a no existe.
(boolean) $a+10; // GENERA un warning si $a no existe.

Aquí tenéis dos funciones para la manipulación y análisis de sentencias SQL SELECT.
La función “sql_select2clauses” extrae en un array las clausulas SQL de un sentencia. Podéis cambiar una de ellas y volver a obtener la sentencia con la función inversa “sql_clauses2select”.

Por ejemplo:
– podéis cambiar el orden de la sentencia.
– añadir un limite.
– obtener la sql para contar los registros.

Códigos de ejemplos:
// para contar los registros de una SQL
$clausulas = sql_select2clauses("SELECT id,name FROM users WHERE tipo=1");
$clausuas["SELECT"] = "count(id)";
$sql = sql_clauses2select($clausulas);

// cambiar la pagina
$clausulas = sql_select2clauses("SELECT id,name FROM users WHERE tipo=1 LIMIT 2,25");
$clausuas["LIMIT"] = "3,25";
$sql = sql_clauses2select($clausulas);

// cambiar el orden
$clausulas = sql_select2clauses("SELECT id,name FROM users WHERE tipo=1 LIMIT 2,25");
$clausuas["ORDER BY"] = "name DESC";
$sql = sql_clauses2select($clausulas);

Ahora, las librerias


function sql_clauses2select ($clauses) {
	$orderedClauses = array("SELECT","FROM","WHERE", "GROUP","HAVING","ORDER BY","LIMIT");
	$parts=array("SELECT"=>"SELECT *");
	foreach ($orderedClauses as $clause){
		if ( isset($clauses[$clause]) ){
			$parts[$clause] = $clause . " " . $clauses[$clause];
		}
	}
	return implode(" ",$parts);
}


function sql_select2clauses($sql){	
	$state = 0;	//0=normal 1=over quote 2=over double quote
	$token ="";	
	$clauses = array("FROM","WHERE", "GROUP","HAVING","ORDER BY","LIMIT");
	$founds=false;	
	$previous="";
	
	$sql= trim($sql);
	if ( stripos($sql,"SELECT")!==0 ){
		return false;
	}
		
	for($i= strlen($sql)-1;$i>=0;$i--){
		$char= $sql[$i];
		if ( $state==0 ){
			if ( $char==" " || $char=="," ) { 			
				$token = strtoupper($token);								
				if ($token == "BY" && strtoupper(substr($sql,$i-5,5))=="ORDER") {
					$i -= 5; //5 = length order
					$founds["ORDER BY"]= trim(substr($previous,2)); // 2 length of "BY;
					$previous="";				
				} elseif ( in_array($token,$clauses)) {
					$founds[$token]= trim(substr($previous,strlen($token))); //extract $token;
					$previous="";				
				}				
				$token ="";
			} else {
				$token = $char .$token;
			}
			
		} elseif ( ($state==1 && $char=="'") OR ($state==2 && $char=='"') ){
			$state=0;
		}
		$previous = $char . $previous;
	}
	$founds["SELECT"] = trim(substr($previous,7)); 	
	
   return array_reverse($founds);
}

Si necesitas una función para clonar registros, aquí tienes unas. La idea es sencilla: usar SQL para clonar un registro. En esencia es algo así:


INSERT INTO tabla (SELECT * FROM tabla WHERE id=..)

El problema es que la SQL anterior no funciona si tienes un campo clave (99% de las tablas, o un campo único). Así que toca refinar mas la función.


function mysql_clonar_registro ( $tabla, $clave ) {

   // limpieza parámetros
   $tabla= mysql_real_escape_string($tabla);
   $clave= mysql_real_escape_string($clave);

   // obtener lista de campos, no únicos
   $rsCampos = mysql_query("SHOW COLUMNS FROM $tabla");
   $campos= array();
   $campoClave ="";
   while ( $campo = mysql_fetch_array($rsCampos) ){

       if ( $campo["Key"] == "PRI" ){
           $campoClave = $campo[0];
       }
       $campos[] =  $campo["Key"] == "PRI" || $campo["Key"] == "UNI" ? "NULL":    $campo[0];
   }
   mysql_free_result ( $rsCampos );

   // clonar el registro mediante una SQL
   if ( $campoClave && count($campos)>0 ) {
       $SQL = sprintf( "INSERT INTO $tabla ( SELECT %s FROM $tabla WHERE %s='%s' )",
           implode(",",$campos),
           $campoClave,
           $clave );
       mysql_query ($SQL);
       return mysql_affected_rows();
   }
   return false;
}

Pretty-urls en PHP

marzo 23, 2011

Usar las llamadas pretty-url o url elegantes es útil para dos cosas:
– hace más usables las direcciones de nuestras páginas web. Eso es importante cuando la gente guarda la página es sus marcadores, o en del.icio.us, o al reenvíar a un amigo.
– las leyendas urbanas dicen que así se mejora el ranking para buscadores. En realidad, los buscadores escarban igual en una web con pretty-url que si ella (bueno, parece que ahora en 2014 google puntua mejor a las web con url amigables).
Lo que si resulta más fácil es revisar los informes de google: ¿que te dice que la página mas vista es http://www.example.org?id=100.

Para implementar estas URL solo hay que:
– definir el fichero .htaccess adecuadamente
– añadir un poco de programación.
Leer el resto de esta entrada »

Existen miles ( y cada día aparecen más) editores de texto, a menudo demasiado parecido unos a otros. Pero todavía hay cosas que me sorprenden. Bookwrite es un editor minimalista, que sirve en principio para escribir libros. Su novedad: el tratamiento del contexto. Cuando escribimos en un procesador de texto, la enorme cantidad de opciones para el formato, la página, la vista previa, el menú, etc, simplemente nos distraen. Pasamos mas tiempo ajustando la tipografía que pensado, escribiendo o leyendo. Bookwrite elimina todo el contexto, y tras pulsar F11, tu pantalla se reduce a un folio blanco, con un pequeño menú lateral (que también se puede ocultar), donde puedes escribir tu texto, en una columna central de unos 50 caracteres.

John Maeda, probablemente estaría a favor de este programa. Al simplificar todo, al quitar todos los elementos superfluos, concentra toda la atención y valor en lo que escribimos, no su forma.

Lo he probado, y funciona. Es como apagar el ordenador y ponerte a escribir sobre un papel: estas mucho mas concentrado y el arranque inicial es mucho mas rápido.

Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.