Magento vs PrestaSHOP

Aunque mi experiencia con CMS para tiendas on-line no es muy amplio es habitual tener la duda a la hora de desarrollar una sobre cual utilizar, por lo que creo interesante hablar de estos dos gestores: Magento y PrestaSHOP. De OSCommerce no he visto mucho, pero algún camarada me lo ha puesto a parir por ser demasiado farragoso.

Así que toca hablar de los puntos fuertes de los dos:

Magento: Magento es el Rolls Royce de las tiendas on-line: permite versión para teléfono móvil (no se si PrestaSHOP ya lo permite, pero cuando yo lo utilicé todavía no), organizar nuestra tienda online en varias vistas y sitios web (se decía que PrestaSHOP 1.5 ya integraría esto, pero tampoco lo trabajé con esa versión), tiene una gestión de los atributos de los productos cojonuda, una cantidad de módulos impresionante (eso sí, la mayoría de pago y algunos muy caros) y su integración con ERP’s es muy buena.

PrestaSHOP: Su gestión de estadísticas es muy completa, incorpora infinidad de herramientas de marketing (que en Magento son módulos de pago), es más usable para el usuario (bueno, aquí no necesariamente, pero suele serlo), permite una mejor comunicación entre administradores y usuarios por su CRM ligero y tiene una comunidad de usuarios mayor (clave a la hora de solucionar problemas).

Claro, dicho así uno se pregunta ¿por qué voy a usar PrestaSHOP si Magento es más potente? Ahora llegamos al punto principal. Sí, Magento es mucho más potente pero tiene los siguientes handicaps:

  • Desarrollo: Magento tiene una estructura compleja, requiere «tocar» muchas cosas para hacer modificaciones, tiene una curva de aprendizaje muy pronunciada y requiere que el programador conozca bastante bien el modelo EAV y Zend Framework, y puede llevarle un par de meses dominar Magento. En cambio, cualquier programador PHP puede estar trabajando con PrestaSHOP sólo en un par de semanas.
  • Rendimiento: Si tienes los creo que 15.000 $ que cuesta la licencia de pago de Magento, lograrás que este no le envidie nada a PrestaSHOP en agilidad. Pero como hablamos de las versiones gratuitas, en este campo también barre PrestaSHOP. Se recomienda tener el back office de Magento en un servidor distinto al del resto de la tienda para lograr un rendimiento decente… con esto te digo todo. El cambio, cualquier hosting profesional mueve PrestaSHOP sin problemas.
  • Administración: Ya hemos dicho que Magento tiene más módulos y más opciones en su back office. Pero claro ¿qué implica esto? Mayor dificultad a la hora de aprender a utilizar la tienda. La curva de aprendizaje para el administrador es más pronunciada que en PrestaSHOP.

Entonces ¿cual es la mejor opción? Pues si tienes una tienda pequeña y no esperas que el negocio crezca mucho lo normal, suponiendo que esto implicará que no quieres/puedes invertir mucho en la tienda, tu opción es PrestaSHOP. Si tu negocio ya es muy grande (hablamos de tiendas que oferten una cantidad muy grande de productos y con varios miles de visites al día) entonces tendrás que meter más pasta e invertir en Magento.

Número aleatorios en C

No es tan extraño verse en la situacion de tener que generar números aleatorios en C. Mi primer programa en C no «académico» era un programilla de consola que generaba fichas de PNJ’s aletorios para Runequest. Elegías una criatura y un «nivel» (criatura flojilla, del montón, poderosa y fuckin’ master) y te mostraba sus características mediante números aleatorios. No es muy habitual que en un programa corporativo o una aplicación del sistema tengamos que usar números aleatorios, pero sí lo puede ser a la hora de programar un juego, una aplicación de sonido (lista de reproducción aleatoria, algún efecto se sonido psicodélico) o una para tratar imágenes (para un filtro artístico).

La función rand() nos devuelve un número entre 0 y el número más alto que pueda generar el sistema. Como lo habitual es que no queramos un rango tan alto, podemos reducirlo utilizando la operación de módulo. Por ejemplo, para obtener un número entre 0 y 10 haríamos x = rand() % 11, y para uno entre 0 y 100 x = rand() % 101.

Si te estás parando a leer esto supongo que tienes ciertas inquietudes al respecto de la programación, por lo que ya sabes que el ordenador no puede inventarse un número al azar. Hasta la actualidad (y por suerte, como sabemos todos los amantes del género cyberpunk) los ordenadores no pueden crear por si mismos. Para la generación de valores aleatorios se necesita pasarle un valor a la función rand() que funcione como semilla, un primer número que permita generar el resto a partir de él. Usando un valor constante el programa siempre generaría los mismos valores, así que la raíz tiene que ser algo cambiante. Una opción suele ser coger el número de proceso del sistema (tiene un fallo, porque si haces varias llamadas a la función principal sin cerrar el programa será como usar una constante), aunque lo mejor suele ser coger los datos del reloj del sistema, ya que al ir ajustado hasta la milésima de segundo es muy poco probable que se coja el mismo valor dos veces seguidas. Para definir la semilla utilizaremos la función srand(), pasándole como parámetro la función time().

Para usar las funciones rand() y srand() debes incluir la librería stdlib en la cabecera de tu proyecto, y para time() la librería time. En el siguiente ejemplo podréis ver cómo generar aleatoriamente un número entre 6 y 12.

#include stdio.h
#include stdlib.h
#include time.h

main(){
int numero; // el número a imprimir

srand(time(0));
numero = (rand() % 7)+6;

printf("El número a imprimir es %d\n",numero);

}

Punteros en C

Uno de los conceptos más complejos del lenguaje C, por lo abstracto de los mismos, es el de los punteros. Su principal utlidad está en que nos permiten hacer una asignación dinámica de memoria.

Un puntero realmente no es más que una dirección de memoria, que normalmente lleva asociado un tipo de datos. Por ejemplo un puntero a entero, que será una dirección de memoria donde podemos almacenar un entero. Para designar un puntero sólo tenemos que poner, en la declaración, un asterisco (*) entre el nombre de la variable y el tipo de datos, tal que así:

int *primero; //declaramos un puntero a entero
int* segundo; //el asterisco puede ir en cualquiera de los dos lados
float *tercero; //y podemos declarar flotantes, caracteres, ficheros...

Para reservar la memoria necesaria utilizaremos la función malloc, abreviatura de memory allocation, pasando como parámetros el tamaño que queremos reservar. La función sizeof() nos puede ayudar mucho, ya que por ejemplo sizeof(int) nos devolverá el tamaño de un entero. Ojea este ejemplo, donde decimos que en la dirección apuntada por el puntero primero vamos a guardar la cantidad de enteros definida en la variable cantidadX:

primero = (*int) malloc(cantidadX*sizeof(int));

Para usar malloc debemos incluir la librería stdlib.h al principio del código. Después de usar malloc se debe usar free para liberar la memoria asignada dinámicamente.

El siguiente es un ejemplo del manual de introducción a C de Nacho Cabanes que ilustra un poco todo esto:

/*---------------------------*/ 
/*  Ejemplo en C nº 73:      */ 
/*  c073.c                   */ 
/*                           */ 
/*  Manejo básico de         */ 
/*  punteros                 */ 
/*                           */ 
/*  Curso de C,              */ 
/*    Nacho Cabanes          */ 
/*---------------------------*/ 
 
#include <stdio.h> 
#include <stdlib.h> 
 
main() { 
  float n1;           /* Primer número, estático */ 
  float *n2, *suma;   /* Los otros dos números */       
   
  n1 = 5.0;           /* Damos un valor prefijado a n1 (real) */ 
  n2 = (float *) malloc (sizeof(float)); /* Reservamos espacio para n2 */ 
  *n2 = 6.7;          /* Valor prefijado para n2 (puntero a real) */ 
   
  suma = (float *) malloc (sizeof(float)); /* Reservamos espacio para suma */ 
  *suma = n1 + *n2;   /* Calculamos la suma */ 
   
  printf("El valor prefijado para la suma era %4.2f\n", 
    *suma); 

printf("Ahora es tu turno: Introduce el primer número "); 
  scanf("%f",&n1);   /* Leemos valor para n1 (real) */ 
   
  printf("Introduce el segundo número "); 
  scanf("%f",n2);    /* Valor para n2 (puntero a real) */   
 
  *suma = n1 + *n2;  /* Calculamos nuevamente la suma */ 
   
  printf("Ahora la suma es %4.2f\n", *suma); 
 
  free(n2);          /* Liberamos la memoria reservada */ 
  free(suma); 
} 

A la hora de meternos en la aritmética de punteros cabe destacar que, en estos casos, los operadores unarios de incremento y decremento no funcionan como una variable estática. Por ejemplo, si tenemos un puntero i y ejecutamos i++, el valor de i no se incrementará en uno, lo que ocurrirá es que la dirección a la que apunta el puntero se incrementará, apuntando hacia el siguiente elemento (Por ejemplo, si i es un entero y apunta a la posición 1000, i++ le hará apuntar a la posición 1004 en un sistema de 32bits, donde un entero ocupa 4bytes). Si queremos incrementar el valor almacenado en el puntero i debemos acceder a él, por lo que deberíamos haber usado (*i)++. Hay que tener cuidado con esto, porque si movemos accidentalmente la posición del puntero podríamos apuntar a una posición de memoria sin reservar que haga romper el programa.

En la página de Nacho Cabanes que os cité antes, y de la que saqué el ejemplo, tenéis un manual muy bueno y claro de introducción a C. No dudéis en descargarlo o en consultarlo on-line cuando lo necesitéis, porque es muy bueno.

Convertir fechas de formato MySQL a español en PHP

Uno de los problemas al recuperar una fecha desde MySQL es que te la devuelve en formato aaaa-mm-dd, el cual tiene su lógica a la hora de hacer comparaciones de fechas, pero es un pelín engorroso y raro mostrarlo así en pantalla. Antaño usaríamos una expresión regular para arreglarlo pero en PHP 5 hay una solución mejor, por lo que he actualizado el artículo (por eso y porque en la solución antigua usaba ereg que actualmente es una función obsoleta), ya que con un objeto DateTime se acaba el mamoneo:

/////////////////////////////////////////////////// 
//Convierte fecha de mysql a español 
//////////////////////////////////////////////////// 
function cambiaf_mysql($fechadb){
//vamos a suponer que recibmos el formato MySQL básico de YYYY-MM-DD
//lo primero es separar cada elemento en una variable
   	list($yy,$mm,$dd)=explode("-",$fechadb);
//si viniera en otro formato, adaptad el explode y el orden de las variables a lo que necesitéis
//creamos un objeto DateTime (existe desde PHP 5.2)
   	$fecha = new DateTime();
//definimos la fecha pasándole las variabes antes extraídas
        $fecha->setDate($yy, $mm, $dd);
//y ahora el propio objeto nos permite definir el formato de fecha para imprimir que queramos       
   	echo $fecha->format('d-m-Y');
}

Como podéis ver la cosa es sencilla. Sobre todo para el tema de insertar fechas desde PHP a MySQL. Porque si vuestra cuita es mostrar en pantalla la fecha formateada, también podéis pedir que MySQL os la devuelva con el formato que queráis. Basta con usar la función date_format() en la query de la select. En el ejemplo vamos a pedir que nos devuelva la fecha con el formato español ya:

SELECT DATE_FORMAT(campo_fecha,'%d/%m/%Y') FROM tabla

Ale, artículo actualizado para vuestro gozo y disfrute.

Instalar JBoss en Linux.

El servidor de aplicaciones Java JBoss es uno de los más populares y utilizados. Su instalación en Linux no plantea demasiados problemas siguiendo unos sencillos pasos:

Lo primero es descargar JBoss desde su página oficial. Tenéis que tener en cuenta qué versión del JDK de Java tienes instalado, para saberlo basta con ejecutar java -version en el terminal, y nos devolverá la información sobre la versión de Java instalada. Recuerda, la versión del JDK y la de JBoss han de ser compatibles entre sí.

Luego debes desempaquetar el .zip descargado en algún directorio donde tengas permisos de
lectura y escritura.

Tras descomprimir el zip queda ajustar las variables de entorno, más concretamente que la variable JBOSS_HOME apunte al directorio de instalación de JBoss. En el archivo .bashrc localizado en el home agrega la sentencia: export JBOSS_HOME= seguida del fichero donde descomprimieras el .ZIP en el paso anterior. También tienes que comproba que JAVA_HOME esté apuntando al directorio de instalación del JDK.

Si vas a utilizar el API de persistencia de Java (JPA), tendrás que instalar el archivo jar del driver JDBC en el directorio $JBOSS_HOME/server/default/lib; donde default es la configuración utilizada por JBoss.

A la hora de arrancar JBoss tenéis varias opciones (all, default, minimal, standard, web). Por defecto arranca en default, pero para iniciar JBoss con una configuración distinta a esta se debe ejecutar: $JBOSS_HOME/bin/run.sh -c, seguido de la opción (por ejemplo $JBOSS_HOME/bin/run.sh -c all).

Usando librerías .dll de .NET en SQL-Server2008

Aunque normalmente no se recomiende tener la lógica de negocio en el lado del servidor de la base de datos, en algunos casos puede resultar interesante el hacerlo. Microsoft, en su empeño (por otra parte loable) de lograr una integración total entre sus servicios, nos permite utilizar nuestras .dll creadas en .NET (sea en VB.NET o en C#.NET o en C++) dentro de nuestra base de datos SQL-Server como «código gestionado».

Iré construyendo poco a poco un ejemplo para que veáis, paso a paso como se realiza esto. Lo primero es activar clr para que nos permita la integración con .NET tal que así:

USE [basedatosdeejemplo]
go
sp_configure 'clr enabled', 1
go
reconfigure
go

Seleccionamos la base de datos a utilizar, configuramos clr como ‘enabled’ (armado, activado) con el parámetro 1 y ejecutamos reconfigure para que el cambio tenga efecto. Acuérdate de poner el parámetro (en este caso 1) y de ejecutar reconfigure.

El primer paso está realizado. Lo siguiente es crear el ensamblado para la librería, definiendo el esquema y el tipo de permisos.


CREATE ASSEMBLY [Utilidades]
AUTHORIZATION [dbo]
FROM 'C:\LibreriaEjemplo.dll'
WITH PERMISSION_SET = SAFE
GO

Creamos el ensamblado con el nombre «Utilidades» (podemos darle el que queramos mientras no sea una palabra reservada), con el esquema dbo (podríamos haber utilizado cualquiera de los disponibles), en FROM le especificamos la dirección del archivo en disco mediante una cadena de texto con la ruta y finalmente los permisos, en este caso SAFE.

SAFE es el permiso más restrictivo que hay, el más «seguro» para nuestro equipo pues limita mucho lo que pueda hacer la librería. En caso de que uses liberías de terceros es el permiso que te reportará más seguridad. Existe también el permiso EXTERNAL_ACCESS, que permite que el código acceda a ciertos recursos externos (registro, archivos, red) y el permiso UNSAFE, que da control sin restricciones a la librería sobre los recursos de la máquina. Si usas una librería propia puedes usar UNSAFE, pero si usas una de un tercero piensa que pueden entrañar riesgos de seguridad.

Con lo puesto ya tenemos la librería disponible en nuestra base datos. ¿Y ahora qué? Ahora simplemente puedes usar las clases y métodos de dicha librería en tu base. Puedes crear tus tipos de datos propios usando sus objetos, incluir sus métodos en procedimientos o triggers. En este ejemplo vamos a suponer que la librería importada tiene una clase Point que guarda las coordenadas de un eje X y un eje Y junto a un valor booleano, y tiene también una función GetCoordsAsText que muestra un mensaje largo con las coordendas. Vamos a crear un tipo de datos Point, usarlo en una tabla, acceder a los valores y usar el método GetCoordsAsText en una función. Pondré comentarios para ir explicando el proceso

--Creamos el tipo de datos Point como un objeto de la clase Point.
--Para acceder a la clase point tenemos que usar el método external name de SQL-Server
--accediendo a la clase mediante el nombre del assembly que creamos antes y el namespace de la clase (en 
--este caso point)
create type Point
external name Utilidades.Point 
go

--Creamos la tabla

create table dbo.Points
(
	id int identity primary key,
	valor Point
);
go

--Para acceder a los datos de la tabla debemos usar un método que nos devuelva
--los valores almacenados dentro del objeto en forma de texto (en este caso .X para el valor X, .Y para 
--el valor Y o .ToString() para sacar ambos en una columna como texto).

select id,
			valor.X as X,
			valor.Y as Y,
			valor.ToString() as Completo
from dbo.Points

--Si intentáramos acceder al objeto a pelo, como voy a poner debajo, nos devolvería el valor del objeto
--sin convertir (un churrazo con la dirección de memoria del puntero)

select valor from dbo.Points --así nos saldría un churo tipo 0x0000000100020000303000000

--También podríamos usar los métodos de la librería en una función, trigger, función de agregado,
--cursor... En este caso haremos una función que acceda a GetCoordsAsText (que está en la clase 
--UserFunctions)

create function dbo.CoordenadasComoTexto
returns nvarchar(50)
as
    external name Utilidades.UserFunctions.GetCoordsAsText

Y con esto tendríais la función que simplemente ejecuta el método definido en la dll y un tipo de datos igual al objeto. Las posibilidades de esto son muy grandes, así que podéis ir profundizando.

Encriptando en MD5 con java

Todavía no he buceado mucho en JavaSE7, pero que yo recuerde JSE6 no incluía ninguna función que encriptara en MD5, y a la hora de trabajar con contraseñas (a nivel de seguridad web, por ejemplo) este algoritmo es muy útil. Normalmente en mis desarrollos en PHP suelo encriptar en el cliente usando una función md5 en Javascript, pero en Java podréis hacerlo con el siguiente código. Se trata de una función que recibe una cadena y devuelve su hash md5.

Bueno, primero tendréis que incluir estas dos librerías:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

En todo caso, si usáis Eclipse o NetBeans para programar en Java ya os pedirá que importéis dichas librerías al añadir referencias a ellas en el código. La función es la siguiente:

        public static String cryptMD5(String textoPlano)
	{
		try
		{
		   private static final char[] HEXADECIMALES = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' };

		   MessageDigest msgdgt = MessageDigest.getInstance("MD5");
		   byte[] bytes = msgdgt.digest(textoPlano.getBytes());
		   StringBuilder strCryptMD5 = new StringBuilder(2 * bytes.length);
		   for (int i = 0; i < bytes.length; i++)
		   {
		       int low = (int)(bytes[i] & 0x0f);
		       int high = (int)((bytes[i] & 0xf0) >> 4);
		       strCryptMD5.append(HEXADECIMALES[high]);
		       strCryptMD5.append(HEXADECIMALES[low]);
		   }
		   return strCryptMD5.toString();
		} catch (NoSuchAlgorithmException e) {
		   return null;
		}
	}

La he testeado y ha ido funcionando, así que creo que os puede hacer un buen servicio a la hora de trabajar con contraseñas de forma segura.

Utilizando el cache de páginas con PHP

Cuando desarrollamos una página en PHP que necesita cargar información desde una base de datos nos encontramos que, en principio, se lanza una petición a la base de datos con cada recarga, que luego se procesa con el código PHP. Si tenemos una página web con poco tráfico (un blog, la página web de un grupo musical o un negocio), una web cuya información no cambie mucho, nos puede interesar crear un archivo de cache para evitar esta recarga. Esto ralentizará un poco la primera carga de la web, pero agilizará las sucesivas recargas de la misma, facilitando la navegación. En caso de páginas web optimizadas para dispositivos móviles (smartphone y tabs), que suelen depender de redes más lentas que los PC (por tirar de conexión 3G) es una opción muy válida.

Lo primero es crear una carpeta con permisos de escritura a la que llamaremos cache/ para almacenar ahí los archivos. Ok, allright, yeah man. Cuando nos metamos con el código (que pondré en un ejemplo más abajo) tenemos que pensar que hay que establecer un tiempo de expiración de la página, ya que si no no se recargaría nunca. Lo mejor es darle un tiempo que creamos prudencial para que sea eficiente sin llegar a dejar desactualizado al usuario. En fin, teniendo en cuenta todo esto, el código sería el siguiente:

$archivoCache = "cache/".$elnombrequecorresponda.".html"; //El archivo con el caché
$tiempoCache = 600; // el parámetro va en segundos, así que serían 10 minutazos

if (file_exists($archivoCache) && (time() - $tiempoCache
< filemtime($archivoCache)))
{
    include($archivoCache);
    echo "\n";
    exit;
}
ob_start(); //inicialización del buffer de salida

//Aquí iría el código PHP y HTML que corresponda

$fp = fopen($archivoCache, 'w'); //Abrimos el archivo con el cache

fwrite($fp, ob_get_contents());//Escribirmos el archivo
fclose($fp);//Cerramos el archivo IMPORTANTE!!!!! que mucha gente se olvida
ob_end_flush(); //limpiamos el buffer para evitar errores

En fin, creo que con estas instrucciones comentada ya os vais pispando todos de cómo funciona la cosa. Par el ejemplo di un tiempo de 10 minutos (ajustad vosotros según creáis conveniente) y la variable $elnombrequecorresponda pues… eso, que ahí ponéis el nombre que corresponda al archivo que queréis cachear.

En fin, chavatares, con esto me voy a dormir, que es tarde… o puede que no, porque no se si mi ordenador a cambiado o no la hora automáticamente. Si mañana llego tarde a todas partes le echaré la culpa. Un cibersaludo!!

Programa en C que imprime el código ASCII// Imprimir letra ñ en C y CPP

Así, a lo tonto, voy a hacerme aquí un típico ejemplo académico de C. No se si aportará mucho o si le interesará a alguien, pero lo hago por una cuestión más bien curricular (vamos, que he mandado curriculums a academias para dar clases de c y quiero que vean que podría dar clase… sí, lo digo así de sincero).

Lo primero es comentar que cuando uno hace un programa en C en castellano se va a topar con una «coñetta» muy jodona… Los caracteres ñ y Ñ no se imprimen si los pones a saco directamente en una cadena. Es decir, la instrucción «printf(«coñetta»);» saldría con algún símbolo raro en lugar de la Ñ. Pero don’t worry, imprimir una ñ, minúscula o mayúscula en C y C++ no requiere ser ingeniero informático. Y hasta tenéis varias opciones que podréis ver en el siguiente ejemplo:

void main(){
  printf(" %c ",164);//imprime una ñ minúscula
  printf(" %c ",165);//imprime una Ñ mayúscula
  printf(" xA4 ");//imprime una ñ minúscula
  printf(" xA5 ");//imprime una Ñ mayúscula
  printf(" co%co ",164);//imprime coño
  printf(" cumpleaxA4os ");//imprime cumpleaños
}

En los dos primeros ejemplos estaríamos diciendo «imprime una variable de caracter con el caracter cuyo valor ASCII sea 164» (165 en el segundo caso). Si estás mirando esto supongo que ya sabes algo de C, ya sabes que la función printf imprime datos en pantalla y que %c es una variable de caracter, y 164 y 165 no serían más que los parámetros con el valor ASCII.

En los casos 3 y 4 realmente es lo mismo. La instrucción viene a decir «imprime el caracter cuyo valor ASCII hexadecimal es A4» (A5 en el caso de la mayúscula). En cualquier caso ambos ejemplos hacen referencia a la tabla de valores ASCII.

Claro, el valor ASCII en principio es ese si nos ceñimos a Windows/MS-DOS. Pero en un SO Apple, BSD o Linux podría variar dependiendo de la distribución. Con este sencillo programa podéis imprimir toda la tabla ASCII para comprobarlo:

#include stdio.h;
void main(){
  int i; //variable contador para el bucle
  printf(“C%cdigo\t-\tLetrann”, 162);

  for(i=0; i<256; i++)//bucle for que recorre los 256 caracteres ASCII
    {
      printf(“%d\t-\t%c\n”, i, i);//imprimimos el número y el caracter
    }
}

Y así a lo tonto ya tenés in práctico programa que os imprimirá toda la tabla ASCII. Y si soy capaz de escribir esto a las cinco de la mañana volviendo de un pub, imaginad cómo puedo dar clase descansado y preparado.

Ordenando un array multidimensional por un campo en PHP

Aunque había pensado publicar «como hacer una encuesta en la que no pueda votar ni dios para así poder inventarte el resultado tranquilo» no lo haré porque se me han adelantado los del diario ABC. En lugar de eso he pensado que a alguien podría interesarle una función que ordene un array multidimensional por un campo en concreto.

La función en si recibirá tres parámetros: el array, el nombre del campo y un valor booleano que indique si se querrá en orden inverso o no. Podéis ver este ejemplo de código:

function orderMultiDimensionalArray ($array, $campo, $invertir) {
    $posicion = array();
    $newRow = array();
    foreach ($array as $key => $row) {
            $posicion[$key]  = $row[$campo];
            $newRow[$key] = $row;
    }
    if ($invertir) {
        arsort($posicion);
    }
    else {
        asort($posicion);
    }
    $arrayRetorno = array();
    foreach ($posicion as $key => $pos) {
        $arrayRetorno[] = $newRow[$key];
    }
    return $arrayRetorno;
}

La función asort ordena un array por los valores que contiene en orden de menor a mayor (si hay valores numéricos los pondrá antes que los alfabéticos). El caso de arsort es el mismo sólo que inverso, ordena de mayor a menor.

Ya véis que es sencillo y no tiene mucha ciencia. Existe también la función ksort (con su versión «reverse», la función krsort) que también ordena, pero en lugar de ordenenar por el valor lo hace por el índice.