2009-09-05 14 views
5

He buscado en la web un buen ejemplo, pero no puedo encontrar nada.¿Cómo hacer una clase de extensión mysqli adecuada con declaraciones preparadas?

Estoy tratando de extender la clase mysqli para hacer una clase auxiliar que abstraiga algunas de las complejidades. Una de las principales cosas que quiero lograr es hacer uso de declaraciones preparadas.

Realmente no sé por dónde empezar, o cómo manejar la entrada y salida correctamente en una clase. Otro problema es que no puedo generar datos como una matriz mientras uso las declaraciones preparadas.

Realmente podría usar un ejemplo simple para apuntarme en la dirección correcta.

Gracias!

Respuesta

5

Verifique la implementación de Zend_Db, y en particular, Zend_Db_Select. De hecho, puede optar por usar eso en lugar de desarrollar el suyo. Ejemplos:

//connect to a database using the mysqli adapter 
//for list of other supported adapters see 
//http://framework.zend.com/manual/en/zend.db.html#zend.db.adapter.adapter-notes 
$parameters = array(
        'host'  => 'xx.xxx.xxx.xxx', 
        'username' => 'test', 
        'password' => 'test', 
        'dbname' => 'test' 
        ); 
try { 
    $db = Zend_Db::factory('mysqli', $parameters); 
    $db->getConnection(); 
} catch (Zend_Db_Adapter_Exception $e) { 
    echo $e->getMessage(); 
    die('Could not connect to database.'); 
} catch (Zend_Exception $e) { 
    echo $e->getMessage(); 
    die('Could not connect to database.'); 
} 

//a prepared statement 
$sql = 'SELECT * FROM blah WHERE id = ?'; 
$result = $db->fetchAll($sql, 2); 

//example using Zend_Db_Select 
$select = $db->select() 
      ->from('blah') 
      ->where('id = ?',5); 
print_r($select->__toString()); 
$result = $db->fetchAll($select); 

//inserting a record 
$row = array('name' => 'foo', 
      'created' => time() 
      ); 
$db->insert('blah',$row); 
$lastInsertId = $db->lastInsertId(); 

//updating a row 
$data = array(
    'name'  => 'bar', 
    'updated' => time() 
); 

$rowsAffected = $db->update('blah', $data, 'id = 2');  
+0

Tenía la esperanza de hacer mi propio, pero no estoy seguro. ¿'$ Db-> fetchAll ($ sql, 2);' se comporta como mysql_fetch_array? Además, ¿por qué parece que hay tanto código redundante que debe existir en cada script? ¿Puedo hacer otra clase para manejar todo hasta el final de esa declaración de catch o try, o se considera una mala práctica? –

+0

@Jon - fetchAll devolverá una matriz asociativa por defecto (se puede cambiar, también hay fetchRow, fetchCol, fetchOne, etc.). Lo ideal es que el try'catch largo solo aparezca una vez en la aplicación dentro del bootstrap (o una inclusión o similar), por lo que no es realmente un problema. – karim79

+0

Ok, esto parece que voy a seguir. ¡Gracias por toda tu ayuda! –

0

Echa un vistazo a Zend Framework y es absolutamente modular Zend_Db clase, especialmente el adaptador mysqli.

0

Suponiendo que en realidad estás queriendo escribir su propia versión (en lugar de utilizar una de las bibliotecas existentes otras respuestas han sugerido, y esas son buenas opciones, también) ...

Aquí hay un par de funciones que puede que le resulte útil examinar. La primera le permite vincular los resultados de una consulta a una matriz asociativa, y la segunda le permite pasar dos matrices, una ordenada de claves ordenadas y la otra una matriz asociativa de datos para esas claves y tener esos datos vinculados a una declaración preparada:

function stmt_bind_assoc (&$stmt, &$out) { 
    $data = mysqli_stmt_result_metadata($stmt); 
    $fields = array(); 
    $out = array(); 

    $fields[0] = $stmt; 
    $count = 1; 

    while($field = mysqli_fetch_field($data)) { 
     $fields[$count] = &$out[$field->name]; 
     $count++; 
    } 
    call_user_func_array(mysqli_stmt_bind_result, $fields); 
} 

function stmt_bind_params($stmt, $fields, $data) { 
    // Dynamically build up the arguments for bind_param 
    $paramstr = ''; 
    $params = array(); 
    foreach($fields as $key) 
    { 
     if(is_float($data[$key])) 
      $paramstr .= 'd'; 
     elseif(is_int($data[$key])) 
      $paramstr .= 'i'; 
     else 
      $paramstr .= 's'; 
     $params[] = $data[$key]; 
    } 
    array_unshift($params, $stmt, $paramstr); 
    // and then call bind_param with the proper arguments 
    call_user_func_array('mysqli_stmt_bind_param', $params); 
} 
0

he escrito una clase contenedora para hacer esto - que proporciona una interfaz idéntica para las consultas parametrizadas, ya sea con o MySQLi DOP. La interfaz le permite ejecutar SQL parametrizado en una sola línea de código, lo que simplifica drásticamente su propio código.

http://www.robpoyntz.com/blog/?p=191

Cuestiones relacionadas