[Hack] Crear una consulta SEGURA con parámetros y marcadones posición.

  • 0 Respuestas
  • 146 Vistas

Valarjar
Hijo de Odyn

AsyncMysqlConnection::queryf


Ejecutar una consulta con marcadores de posición y parámetros, utilizamos queryf en lugar de query, ya que esta es segura y escapa a caracteres no autorizados.

Descripción

Código: PHP
  1. public function queryf(
  2.   HH\FormatString<HH\SQLFormatter> $query,
  3.   ...$args,
  4. ): Awaitable<AsyncMysqlQueryResult>
  5.  

Este es probablemente el más común de los dos métodos de consulta, dada su flexibilidad y escape automático en la mayoría de los casos de cadena.

Ejemplo:
Código: PHP
  1. queryf("SELECT %C FROM %T WHERE %C %=s", $col1, $table, $col2, $value);

Los soportados marcadores de posición son:

  • %T El nombre de la tabla.
  • %C El nombre de la columna.
  • %s Cadena anulable (se escapará).
  • %d Entero.
  • %f Flotante.
  • %=s Comparación cadena anulable - se expande a: = 'escaped_string' IS NULL.
  • %=d Comparación entero anulable.
  • %=f Comparación flotante anulable.
  • %Q Consulta SQL sin formato. El typechecker intencionalmente no reconoce esto, sin embargo, puede usarlo en combinación con // UNSAFE si es absolutamente necesario. Utiliza esto a tu propio riesgo, ya que podría abrirse para la inyección de SQL.
  • %Lx Donde x es uno de T, C, s, d, o f representa una lista de nombres de tablas, nombres de columnas, cadenas anulables, números enteros o flotantes, respectivamente. Pasa un Vector de valores para que se expanda en una lista separada por comas. Los paréntesis no se agregan automáticamente alrededor del marcador de posición en la cadena de consulta, así que asegúrate de agregarlos si es necesario.

Con la excepción de %Q, cualquier cadena proporcionada se escapará correctamente.

Parámetros
  • HH\FormatString<HH\SQLFormatter> $query
  • ...$args

Variables devueltas

Awaitable<AsyncMysqlQueryResult> - Un Awaitable representando el resultado de su consulta. Use await o join para obtener el objeto AsyncMysqlQueryResult.



Ejemplos

En el ejemplo siguiente se muestra cómo utilizar AsyncMysqlConnection :: queryf. Primero obtiene una conexión desde un AsyncMysqlConnectionPool; Entonces decidirás qué parámetros deseas pasar como marcadores de posición de consulta.

Código: PHP
  1. <?hh
  2.  
  3. namespace Hack\UserDocumentation\API\Examples\AsyncMysql\Conn\Queryf\Basic;
  4.  
  5. use \Hack\UserDocumentation\API\Examples\AsyncMysql\ConnectionInfo as CI;
  6.  
  7. async function connect(\AsyncMysqlConnectionPool $pool):
  8.   Awaitable<\AsyncMysqlConnection> {
  9.   return await $pool->connect(
  10.     CI::$host,
  11.     CI::$port,
  12.     CI::$db,
  13.     CI::$user,
  14.     CI::$passwd
  15.   );
  16. }
  17.  
  18. async function get_data(\AsyncMysqlConnection $conn, string $col, int $id):
  19.   Awaitable<\AsyncMysqlQueryResult> {
  20.   return await $conn->queryf(
  21.     'SELECT %C FROM test_table where userID = %d',
  22.     $col,
  23.     $id
  24.   );
  25. }
  26.  
  27. async function simple_queryf(): Awaitable<int> {
  28.   $pool = new \AsyncMysqlConnectionPool(array());
  29.   $conn = await connect($pool);
  30.   $result = await get_data($conn, 'name', 1);
  31.   $x = $result->numRows();
  32.   $result = await get_data($conn, 'name', 2);
  33.   $conn->close();
  34.   return $x + $result->numRows();
  35. }
  36.  
  37. function run(): void {
  38.   $r = \HH\Asio\join(simple_queryf());
  39.   var_dump($r);
  40. }
  41.  
  42. run();
  43.  

Salida
Código: PHP
  1. int(2)




El siguiente ejemplo utiliza el marcador de posición %=s para permitirle comprobar si existe una dirección de correo electrónico con la cadena proporcionada en la tabla o, si se pasa null, si hay un usuario con una dirección de correo electrónico nula.

Código: PHP
  1. <?hh
  2.  
  3. namespace Hack\UserDocumentation\API\Examples\AsyncMysql\Conn\Queryf\PerEqual;
  4.  
  5. use \Hack\UserDocumentation\API\Examples\AsyncMysql\ConnectionInfo as CI;
  6.  
  7. async function connect(\AsyncMysqlConnectionPool $pool):
  8.   Awaitable<\AsyncMysqlConnection> {
  9.   return await $pool->connect(
  10.     CI::$host,
  11.     CI::$port,
  12.     CI::$db,
  13.     CI::$user,
  14.     CI::$passwd
  15.   );
  16. }
  17.  
  18. async function get_data(
  19.   \AsyncMysqlConnection $conn,
  20.   string $col,
  21.   ?string $email):
  22.   Awaitable<\AsyncMysqlQueryResult> {
  23.   // %=s allows you to check an actual string value or IS NULL
  24.   return await $conn->queryf(
  25.     'SELECT %C FROM test_table where email %=s',
  26.     $col,
  27.     $email
  28.   );
  29. }
  30.  
  31. async function simple_queryf(): Awaitable<int> {
  32.   $pool = new \AsyncMysqlConnectionPool(array());
  33.   $conn = await connect($pool);
  34.   $result = await get_data($conn, 'name', 'joelm@fb.com');
  35.   $x = $result->numRows();
  36.   $result = await get_data($conn, 'name', null);
  37.   $conn->close();
  38.   return $x + $result->numRows();
  39. }
  40.  
  41. function run(): void {
  42.   $r = \HH\Asio\join(simple_queryf());
  43.   var_dump($r);
  44. }
  45.  
  46. run();
  47.  

Salida
Código: PHP
  1. int(46)




En el ejemplo siguiente se muestra cómo utilizar el marcador de posición %L para AsyncMysqlConnection :: queryf. Primero obtienes una conexión desde un AsyncMysqlConnectionPool; Entonces estamos pasando un vector de ids para utilizar en el marcador de posición. El marcador de posición termina siendo %Ld ya que los ids son enteros.

Código: PHP
  1. <?hh
  2.  
  3. namespace Hack\UserDocumentation\API\Examples\AsyncMysql\Conn\Queryf\PerL;
  4.  
  5. use \Hack\UserDocumentation\API\Examples\AsyncMysql\ConnectionInfo as CI;
  6.  
  7. async function connect(\AsyncMysqlConnectionPool $pool):
  8.   Awaitable<\AsyncMysqlConnection> {
  9.   return await $pool->connect(
  10.     CI::$host,
  11.     CI::$port,
  12.     CI::$db,
  13.     CI::$user,
  14.     CI::$passwd
  15.   );
  16. }
  17.  
  18. async function get_data(\AsyncMysqlConnection $conn, Vector<int> $ids):
  19.   Awaitable<\AsyncMysqlQueryResult> {
  20.   return await $conn->queryf(
  21.     'SELECT name FROM test_table where userID IN (%Ld)',
  22.     $ids
  23.   );
  24. }
  25.  
  26. async function percent_L_queryf(): Awaitable<int> {
  27.   $pool = new \AsyncMysqlConnectionPool(array());
  28.   $conn = await connect($pool);
  29.   $ids = Vector {1, 2};
  30.   $result = await get_data($conn, $ids);
  31.   $conn->close();
  32.   return $result->numRows();
  33. }
  34.  
  35. function run(): void {
  36.   $r = \HH\Asio\join(percent_L_queryf());
  37.   var_dump($r);
  38. }
  39.  
  40. run();
  41.  

Salida
Código: PHP
  1. int(2)
« Última modificación: Junio 02, 2017, 04:08:24 am por Valarjar »