2012-07-12 14 views
26

Estoy tratando de escribir una función que verifique un solo valor en la base de datos utilizando mysqli sin tener que colocarlo en una matriz. ¿Qué más puedo hacer además de lo que ya estoy haciendo aquí?Valor único Mysqli

function getval($query){ 
    $mysqli = new mysqli(); 
    $mysqli->connect(HOST, USER, PASS, DB); 
    $result = $mysqli->query($query); 
    $value = $mysqli->fetch_array; 
    $mysqli->close(); 
    return $value; 
} 

Respuesta

20

La extensión mysql podría hacer esto utilizando mysql_result, pero mysqli no tiene una función equivalente a fecha de hoy, que yo sepa. Siempre devuelve una matriz.

Si no me acaba de crear el registro, lo hago de esta manera:

$getID = mysqli_fetch_assoc(mysqli_query($link, "SELECT userID FROM users WHERE something = 'unique'")); 
$userID = $getID['userID']; 

O si me acaba de crear el registro y la columna de ID de usuario es AI, que hago:

$userID = mysqli_insert_id($link); 
+2

o cambiar '' assoc' a array' y entonces usted puede hacer '$ getID [0]' – rybo111

+1

Y nadie, nadie, nadie le importa que la única parte significativa de esta largamente buscada "de una sola línea" se ha ido mucho más allá de la pantalla visible ... –

+0

downvoted únicamente porque 'fetch_object()' existió muchos años antes de esta respuesta, que devuelve un objeto simple, lo que significa que en el momento de escribir este mysqli tenía una mejor opción. También su respuesta está escrita en comandos de procedimiento mientras que la pregunta de OP fue escrita a través de mysqli basado en objetos. – skrilled

5

Siempre es mejor crear la conexión una vez al principio y cerrarla al final. Así es como implementaría tu función.

$mysqli = new mysqli(); 
$mysqli->connect(HOSTNAME, USERNAME, PASSWORD, DATABASE); 

$value_1 = get_value($mysqli,"SELECT ID FROM Table1 LIMIT 1"); 
$value_2 = get_value($mysqli,"SELECT ID FROM Table2 LIMIT 1"); 

$mysqli->close(); 

function get_value($mysqli, $sql) { 
    $result = $mysqli->query($sql); 
    $value = $result->fetch_array(MYSQLI_NUM); 
    return is_array($value) ? $value[0] : ""; 
} 
+0

es MYSQLI_NUM una constante? – Gokigooooks

+0

Sí, lo es. http://stackoverflow.com/questions/1684993/what-does-mysqli-num-mean-and-do De php.net, "Este parámetro opcional es una constante que indica qué tipo de matriz debe producirse a partir de la corriente datos de fila. Los valores posibles para este parámetro son las constantes MYSQLI_ASSOC, MYSQLI_NUM o MYSQLI_BOTH. " – jbrahy

+1

esta respuesta, y las respuestas más recientes de John y rybo111, son las únicas que abordan directamente el código de OP. La pregunta de OP muestra un método que acepta CUALQUIER consulta de devolución escalar, no requiere conocer el nombre de un campo para devolver. – ToolmakerSteve

-1

intentar algo como esto:

$last = $mysqli->query("SELECT max(id) as last FROM table")->fetch_object()->last; 

Saludos

+1

Esto supone que el escalar que se devuelve tiene un nombre de campo conocido. Esto no es coherente con el código de OP, que pasa en CUALQUIER consulta (que se espera que devuelva un único valor, una consulta "escalar"). Puede que ni siquiera sea una consulta de un campo de registro; podría estar devolviendo un recuento, o incluso una variable del sistema. – ToolmakerSteve

4

Esto es lo que terminó con:

function get_col($sql){ 
    global $db; 
    if(strpos(strtoupper($sql), 'LIMIT') === false) { 
    $sql .= " LIMIT 1"; 
    } 
    $query = mysqli_query($db, $sql); 
    $row = mysqli_fetch_array($query); 
    return $row[0]; 
} 

De esta manera, si se olvida de incluir LIMIT 1 de la consulta (todos lo hemos hecho), la función lo agregará. el uso

Ejemplo: (! repetidas conectar solos)

$first_name = get_col("SELECT `first_name` FROM `people` WHERE `id`='123'"); 
+0

Esto nunca funcionará. –

+0

@YourCommonSense tu negatividad es mi motivación. Fijo. – rybo111

+0

Problema menor: la consulta podría contener 'limit' (minúscula) en lugar de' LIMIT'.Entonces, si usa la parte de la respuesta que implica 'LIMIT', podría querer hacer la prueba' if (strpos ($ sql, 'LIMIT') === false && strpos ($ sql, 'limit') === false) {' – ToolmakerSteve

1

Aunque hay muchos defectos en su aplicación, así como en otras respuestas (? una sola línea en el costo de trasladar los parámetros fuera de la pantalla), hay uno esencial:

Tal función debe tener soporte para comandos preparados

lo contrario, será horribly insecure.

Por lo tanto, la única manera aceptable para llamar a una función de este tipo será

$name = getVal($query, $param1, $param2); 

o

$name = getVal($query, [$param1, $param2]); 

permitiendo $query a contener sólo marcadores de posición, mientras que los datos real tiene que ser añadido por separado. Cualquier otra variante, incluidas todas las demás respuestas publicadas aquí, , nunca debe usarse.

Suponiendo que necesitamos otras funciones del tipo (como getRow(), getAll()), sería lógico combinarlas todas en una clase. Para mysqli puedes usar mi safeMysql wrapper:

$name = $db->getOne("SELECT name FROM users WHERE id = ?i", $id); 

como se puede ver, que tiene una sintaxis muy concisa y perfectamente seguro.

Si no desea utilizar las envolturas de terceros, entonces me aconsejo encarecidamente que utilice DOP como una API de respaldo, simplemente porque implementación basada en mysqli resultaría en una cantidad insana de código . Basta con comparar estas 2 funciones, una utilizando mysqli:

function getVal($sql, $values = array()) 
{ 
    global $mysqli; 

    $stm = $mysqli->prepare($sql); 

    if ($values) 
    { 
     $types = str_repeat("s", count($values)); 

     if (strnatcmp(phpversion(),'5.3') >= 0) 
     { 
      $bind = array(); 
      foreach($values as $key => $val) 
      { 
       $bind[$key] = &$values[$key]; 
      } 
     } else { 

      $bind = $values; 
     } 
     array_unshift($bind, $types); 
     call_user_func_array(array($stm, 'bind_param'), $bind); 
    } 
    $stm->execute(); 
    $stm->bind_result($ret); 
    $stm->fetch(); 
    return $ret; 
} 

y el otro con DOP:

function getVal($query, $params = array()) 
{ 
    global $pdo; 
    $stmt = $pdo->prepare($query); 
    $stmt->execute($params); 
    return $stmt->fetchColumn(); 
} 

y se puede ver claramente la diferencia.

De cualquier manera, usted va a terminar el uso de esta función como esta

$name = getVal("SELECT name FROM users WHERE id = ?", [$id]); 

ya que es la única manera adecuada y segura para llamar a una función de este tipo, mientras que todas las demás variantes carecen de seguridad, facilidad de lectura, manejo de errores y cordura.

+0

No solo no puede escribir una función uniforme, sino que tampoco puede leer otra respuesta :) –

20

¿Qué tal

$name = $mysqli->query("SELECT name FROM contacts WHERE id = 5")->fetch_object()->name; 
+2

Explique * por qué * su código resuelve el problema. Ver respuesta]. – brasofilo

+4

Esta es la línea de código más corta para obtener un valor de resultado de mysqli. –

+0

Esto supone que el escalar que se devuelve tiene un nombre de campo conocido. Esto no es coherente con el código de OP, que pasa en CUALQUIER consulta (que se espera que devuelva un único valor, una consulta "escalar"). Puede que ni siquiera sea una consulta de un campo de registro; podría estar devolviendo un recuento, o incluso una variable del sistema. – ToolmakerSteve

2

incluso esto es un viejo tema, no veo aquí manera bastante simple Solía ​​usar para tal asignación:

list($value) = $mysqli->fetch_array; 

puede asignar directamente más variables , no solo uno, por lo que puede evitar el uso de matrices por completo. Vea la función php list() para más detalles.

0

Esto no evita completamente la matriz, pero prescinde de ella en una línea.

function getval($query) { 
    $mysqli = new mysqli(); 
    $mysqli->connect(HOST, USER, PASS, DB); 
    return $mysqli->query($query)->fetch_row()[0]; 
}