¿Debería usar wpdb prepare?

11 may 2011, 10:16:11
Vistas: 58.6K
Votos: 38

Soy nuevo en SQL y me pregunto si necesito usar wpdb->prepare para la siguiente consulta a una tabla que he creado

global $wpdb;
$tablename = $wpdb->prefix . "my_custom_table";
$sql = "SELECT * FROM " . $tablename . " ORDER BY date_created DESC";
$resulst = $wpdb->get_results( $sql , ARRAY_A );

¿Necesito usar prepare aquí? ¿Cómo lo haría?

Gracias

0
Todas las respuestas a la pregunta 3
7
47

Es una buena práctica siempre usar prepare, pero su principal uso es prevenir ataques de inyección SQL, y como no hay entrada de usuarios/visitantes o no pueden afectar la consulta, entonces ese no es un problema en tu ejemplo actual.

Pero como dije antes, es una buena práctica usarlo y una vez que comienzas a usarlo, nunca paras, así que en tu ejemplo puedes usarlo así:

global $wpdb;
$tablename = $wpdb->prefix . "my_custom_table";
$sql = $wpdb->prepare( "SELECT * FROM %s ORDER BY date_created DESC",$tablename );
$results = $wpdb->get_results( $sql , ARRAY_A );

para leer más sobre cómo usarlo, dirígete a el codex

11 may 2011 10:43:00
Comentarios

Hola @Bainternet, gracias por una explicación tan clara - por alguna razón cuando intento tu código me devuelve un array vacío. He revisado y vuelto a revisar en busca de errores tipográficos. Si hago la consulta sin preparar obtengo el array. ¡No entiendo por qué no funciona..!

Richard Sweeney Richard Sweeney
11 may 2011 11:03:09

Extraño. He intentado usar el mismo código con otra consulta: `$tablename = $wpdb->prefix . "my_custom_table"; $concert_id = 1;

$sql = "SELECT * FROM " . $tablename . " WHERE concert_id = %d LIMIT 1;";

$prep_sql = $wpdb->prepare( $sql, $concert_id );

$get_concerts = $wpdb->get_results( $prep_sql , ARRAY_A );`

¡Y funciona perfectamente! No estoy seguro de por qué sería. ¡Pero al menos ahora lo entiendo!

Richard Sweeney Richard Sweeney
11 may 2011 11:36:02

Encerrar el nombre de la tabla entre comillas simples no funcionará. El escape normal es con acentos graves, por lo que tu consulta debería terminar luciendo así: SELECT * FROM \wp_my_custom_table`. Puedes habilitar el soporte para comillas dobles, pero entonces tendría que verse así:SELECT * FROM "wp_my_custom_table"`.

Jan Fabry Jan Fabry
11 may 2011 11:52:17

No estoy de acuerdo con esta respuesta. ¿Por qué deberías escapar si la función ya escapa todo? ¿Crees que WordPress decidirá eliminar el escape del núcleo? Además, no tiene sentido escapar el nombre de la tabla :) porque está hardcodeado y sabes que está bien. Sé que esto es solo un ejemplo, pero de todos modos no escapen nombres de tablas, tengo problemas al usar prepare con nombres de tablas ya que añade backticks y SQL lanza un error.

Tommixoft Tommixoft
4 nov 2014 14:41:44

@Tommixoft Si lees la respuesta de nuevo, verás que en realidad dices lo mismo que yo dije, y que el nombre de la tabla es un ejemplo.

Bainternet Bainternet
5 nov 2014 09:07:36

¿Puedes respaldar la afirmación de que es la mejor práctica? Parece extraño (como en que no es la mejor práctica) usar una función que es innecesaria y espera 2+ parámetros en este caso....

random_user_name random_user_name
14 oct 2016 17:23:32

¡Ahhh la respuesta es del 2011!!! Si aceptas entradas del usuario en la consulta, entonces sí, siempre es una buena práctica.

Bainternet Bainternet
20 oct 2016 17:27:15
Mostrar los 2 comentarios restantes
2

Cuando utilizas prepare estás protegiendo el código de vulnerabilidades de inyección SQL.

Aquí está el código que necesitas modificar para usar prepare():

global $wpdb;
$tablename = $wpdb->prefix . "my_custom_table";
$sql = $wpdb->prepare( "SELECT * FROM {$tablename} ORDER BY date_created DESC");
$resulst = $wpdb->get_results( $sql , ARRAY_A );
12 oct 2015 18:34:35
Comentarios

El simple hecho de usar prepare() no protege automáticamente el código contra inyecciones SQL. Tu código podría sugerir que $tablename está protegido contra inyecciones SQL porque se usa en prepare, lo cual no es el caso, ya que no se proporciona a través de los argumentos. En este caso no es un problema porque el contenido de $tablename es seguro, pero creo que sería bueno aclararlo.

Constantin Constantin
28 dic 2020 17:04:58

Sí. Esta respuesta es incorrecta y peligrosamente engañosa, diría yo. Has llamado a prepare de una manera que en realidad no protege contra la inyección SQL.

Harry Wood Harry Wood
11 nov 2021 13:30:10
0

En tu caso no es posible un ataque de inyección SQL. Tu código no necesita protección adicional porque no utiliza entrada de usuario como: post, get, request, cookie.

No utilices funciones complicadas cuando no sean necesarias para ahorrar recursos del servidor.

17 jul 2015 11:51:54