Refactorizando PHP, ¿me paso a las clases?

RaymaN

Buenas, estoy refactorizando el código de una web para hacerlo menos infumable y separar HTML y PHP. Os pongo un ejemplo:

Función PHP:

function usuario($id, $dato) {
    $row = select("SELECT * FROM usuarios WHERE id = $id");
    $datos = Array(
        'nombre' => $row['nombre'],
        'email' => $row['email']
    );
    return $datos[$dato];
}

Y luego en el HTML imprimo los valores así:

<div class="nombre"><?=usuario(1337, 'nombre')?></div>
<div class="email"><?=usuario(1337, 'email')?></div>

Esto queda muy bonito (o no, a mi me gusta xD) y hace muy legible el código, pero obviamente hace la misma consulta dos veces para un solo usuario, y cuando son bastantes más datos los que hay que mostrar se incrementa el tiempo de carga.

No sé si utilizando clases sería la solución, nunca he trabajado con ellas en PHP. Quizá podría confiar en la caché de MySQL y seguir utilizando el modelo que he puesto, pero supongo que habrá una mejor solución y qué mejor momento que implementarla ahora.

¿Qué pensáis vosotros?

BLZKZ

y por que no devuelves el array y luego seleccionas email o nombre en el echo? asi solo haces 1 consulta

Y usando orientación a objetos todo será mucho más legible, amén que la modularización será más sencilla.

1 respuesta
RaymaN

#2 pues no había caído en eso, es buena idea.

eXtreM3

Por qué no haces un

$row = mysql_fetch_array(mysql_query("SELECT * FROM usuarios WHERE id = $id"));

Y ya tienes

echo $row['nombre'].$row['email'];

?

B

1) Llamar 2 veces a la función para un mismo usuario es perder el tiempo al ya devolverte la función todos los datos.
2) Si son muchas llamadas de distintas sesiones al mismo usuario usa memcache y cacheas la respuesta ahorrando recursos en base de datos.
3) Create una clase para manejar conexiones a la base de datos con patrón singleton y te ahorras estar haciendo nuevas conexiones cada vez que realizas una consulta.

Antes de hacer todo eso leete una guia de php 5 pues estás usando php 4.

1 respuesta
HaxeR

#1 Lo que te ha dicho #5, yo creo que ya en el 2012 nadie deberia de estar programando PHP a pelo, sin un framework detras que gestione conexiones a tu base de datos con singleton, separe la logica del diseño,etc...Y por favor no uses short tags! Acostumbrate a usar siempre la apertura y cierre correcto para PHP, en PHP6 ya no tendras soporte, y si migras de tu servidor a otro, puede que las tenga desactivadas por defecto y te vuelvas loco buscando el problema

<?php echo $dato; ?>
1 respuesta
RaymaN

#6 soy consciente del uso de short tags, los tengo así para minificar el php introducido dentro de HTML.

Tendré que mirarme a fondo eso del singleton, le he echado un vistazo y me parece un follón pero bueno... standards.

2 respuestas
neil90

#7 No es el patrón singleton lo que deberías mirar, si no un framework que te haga esas cosas automáticamente. Montar tú sólo el backend desde 0 es poco recomendable.

1
B

#7: El singleton es tan complicado como sumar 1+1, aprox. Pero vosotros dónde aprendisteis a programar? :S

#10: Qué método estás usando ahora?

1 respuesta
RaymaN

#9 me refiero a que me parece un follón comparado con el método que uso actualmente, lo veo más abstracto y menos claro, no que sea difícil de implementar.

#9 el clásico mysql_query, mysql_fetch_array y tal.

2 respuestas
Tunnecino

#10 Amén de que deberías de empezar a usar MySQLi, ya que el uso de MySQL en php está desacosejado.

RaymaN

Estoy implementando el patrón singleton junto a mysqli. He creado esta clase para la conexión:

class DB {

private static $dbLink;

const DB_SERVER = 'localhost';
const DB_USER = 'root';
const DB_PW = '';
const DB_DB = 'database';

private function __construct() {}
private function __clone() {}

public static function Get() {
	if (!self::$dbLink) {
		self::$dbLink = new mysqli(self::DB_SERVER, self::DB_USER, self::DB_PW, self::DB_DB);
		if (mysqli_connect_errno()) {
			throw new Exception("Database connection failed: ".mysqli_connect_error());
		}
	}
	return self::$dbLink;
}
}

Y estas funciones para hacer consultas de una o varias filas:

function select($sql, $rows = null) {
	$db = DB::Get();
	$result = $db->query($sql);
	if ($rows)
		return $result->num_rows;
	else
		return $result->fetch_assoc();
}

function seloop($sql) {
	$db = DB::Get();
	$result = $db->query($sql);
	while ($row = $result->fetch_assoc()) {
		$ret[] = $row;
	}
	return $ret;
}

¿Está mejor ahora?

2 respuestas
Kiroushi

#12 Usa un framework como CodeIgniter o CakePHP y en cuanto le cojas el truquillo te olvidarás de todas estos problemas.

Ya tienen las clases de de BDD y demases implementadas, con lo que sólo es aplicar las que te convengan.

2
B

#12 los métodos de la clase de base de datos van dentro de ella como estáticos o los pones como abstractos. Si te lias mucho mírate como lo hace cualquier framework.

Para que tengas una idea, cuando quieras hacer un select vas a hacer algo tipo

DB::select($query);
1 respuesta
RaymaN

#14 he metido esta función dentro de la clase DB:

public static function select($sql) {
	$db = DB::Get();
	$result = $db->query($sql);
	return $result->fetch_assoc();
}

Luego, en una hipotética clase para obtener un usuario haría:

function usuario($id) {
    $sql = 'blah';
    $result = DB::select($sql);
    return $result;
}

¿Es correcto? ¿Qué diferencia hay entre usarla dentro o fuera de la clase? Gracias por las respuestas.

1 respuesta
B

#15 Está mal implementado pues debes usar la referencia self en vez de llamar de nuevo al método estático.
La idea es que la clase DB te permita realizar cualquier operación sobre la base de datos sin instanciarla desde fuera, si pones los métodos fuera pierdes encapsulación. De todas formas probablemente no sepas ni que es un método estático por lo que te aconsejo leas principios de POO en php 5. Google es tu amigo.

Te dejo un enlace con un pdf para la certificación oficial zend php 5 que cubre todo lo que necesitas saber sobre php 5. En 24 horas lo quito.

https://www.dropbox.com/s/ogr521x4btcp7ml/zend_php_certification.pdf

Ah y el singleton te tiene que devolver una instancia de la misma clase no de mysqli.

3

Usuarios habituales