Tratamiento del AJAX en un solo fichero

Últimamente estoy desarrollando sobre todo con PHP+JavaScript (jQuery). En un proyecto interno de Arcadina, que hace un uso intensivo del AJAX, decidí probar un planteamiento diferente del utilizado hasta ahora.

Normalmente las llamadas a la parte AJAX del servidor se hacen a diferentes scripts PHP en función de lo que deseamos obtener (query) o guardar (submit). Por ejemplo, si estamos tratando una lista de clientes podemos llamar a get_cliente.php para solicitar los datos de un cliente pasando su identificador, podemos llamar a delete_cliente.php para eliminarlo o a save_cliente.php para guardar cambios en la ficha, etc. (tengo la manía de utilizar spanglish en el nombre de funciones, procedimientos, etc.). Ejemplo de llamada según esté método:

Nombre:
EMail:

Según el proyecto va avanzando nos podemos encontrar con decenas de scripts: get_loquesea, delete_loquesea…. En cada uno de ellos añadir el código de validación, los includes, etc. Se me ocurrió centralizarlo en dos ficheros ajaxsubmit.php y ajaxquery.php, y utilizar un parametro para indicar la acción a realizar. Ejemplo de un formulario utilizando este sistema:

Nombre:
EMail:

Como se ve tampoco es que varíe mucho en la parte que se envía al navegador, se añade un nuevo campo oculto “ajaxsubmit” que indica la acción que queremos realizar. Veamos el ajaxsubmit.php:

encode($respuesta);

exit;

// =======================================================================================
// Procesos de guardar, eliminar, actualizar, etc...
// =======================================================================================

function AS_save_cfg() {

	global $respuesta;
	$cfg = array();
	
	foreach($_POST as $clave => $valor) {
		// Comprobar si $clave empieza por 'cfg_'
		if (ereg('^cfg_', $clave)) {
			$k = ereg_replace("^cfg_", "", $clave);
			$cfg[$k] = $valor;
		}
	}
	$errormsg = SaveConfig($cfg);
	if ($errormsg == 'ok') {
		$respuesta['resultado'] = 'ok';
		$respuesta['mensaje'] = 'Configuración guardada';
	} else {
		$respuesta['resultado'] = 'nok';
		$respuesta['mensaje'] = $errormsg;
	}
		
}

function AS_save_cliente() {

	global $respuesta;
	
	// Código simplificado para el ejemplo: se debería
	// añadir validación y protección contra SQL injection
	$cliente = new Cliente($_POST['id']);
	$cliente->nombre = $_POST['nombre'];
	$cliente->email = $_POST['email'];
	
	$errormsg = $cliente->Save();
	if ($errormsg == 'ok') {
		$respuesta['resultado'] = 'ok';
		$respuesta['mensaje'] = 'Cliente guardado';
	} else {
		$respuesta['resultado'] = 'nok';
		$respuesta['mensaje'] = $errormsg;
	}
}

?>

La “gracia” del código está en ésta parte:

	$ajaxsubmit = $_POST['ajaxsubmit'];
			 	
	// "AS_" viene de AjaxSubmit ... 😉	
	$funcion = 'AS_' . $ajaxsubmit;
	// Comprobamos que tenemos una función con ese nombre
	if (function_exists($funcion)) {
		$funcion(); // Llamamos a la función AS_ que indique el ajaxsubmit

Lo que se envia en la variable “ajaxsubmit” es el nombre de la función a llamar, pero la precedemos de “AS_” para evitar conflictos con otros nombres de funciones. Entonces gracias a la magia de PHP, porque es un lenguaje de script, aprovechamos la variable $funcion para realizar una llamada a una funcion: $funcion()

¿Qué ventajas tiene este sistema? Tenerlo centralizado, de esa forma, añadir una capa de autenticación o variar el formato de salida de JSON a XML, por ejemplo, es mucho más sencillo. Evidentemente si alguna función es compleja se puede separar en un fichero aparte y hacer el correspondiente include, que además lo recomiendo.

Para facilitar la labor de serializar los inputs de un formulario y enviarlo por ajax estoy utilizando el plugin ajaxForm para jQuery.