2009-11-23 25 views
40

Estoy tratando de hacer una búsqueda a través de la clase PDO de php (controlador mysql). Tengo la siguiente consulta trabajar con el cliente MySQL (nombres de tabla cambiados para proteger a los inocentes):Declaración preparada de PHP PDO - MySQL LIKE query

SELECT hs.hs_pk, 
      hs.hs_text, 
      hs.hs_did, 
      hd.hd_did, 
      hd.hd_text, 
      hv.hv_text, 
      hc.hc_text 
FROM  hs 
LEFT JOIN hd 
ON  hs.hs_did = hd.hd_did 
LEFT JOIN hd 
ON  hd.hd_vid = hv.hv_id 
LEFT JOIN hc 
ON  hd.hd_pclass = hc.hc_id 
WHERE  hs.hs_text LIKE "%searchTerm%" 
LIMIT 25; 

Esto funciona como un encanto sin importar el término de búsqueda que utilizo. Sin embargo, cuando me muevo a php, no puedo hacer que devuelva nada. He intentado varias sintaxis diferentes que parecen lógicas para trabajar, pero nada de lo que he intentado funciona. aquí está mi código existente:

$handle = fopen('/foo/bar/test.log', 'w+'); 
fwrite($handle, "doSearch, with search term: $searchTerm\n"); 
$sql = 
'SELECT hs.hs_pk, 
      hs.hs_text, 
      hs.hs_did, 
      hd.hd_did, 
      hd.hd_text, 
      hv.hv_text, 
      hc.hc_text 
FROM  hs 
LEFT JOIN hd 
ON  hs.hs_did = hd.hd_did 
LEFT JOIN hd 
ON  hd.hd_vid = hv.hv_id 
LEFT JOIN hc 
ON  hd.hd_pclass = hc.hc_id 
WHERE  hs.hs_text LIKE :searchTerm 
LIMIT 25'; 

try { 
$dbh = new PDO('mysql:host=localhost;dbname=awdb', "user", "password"); 
fwrite($handle, "connected to DB\n"); 
$prep = $dbh->prepare($sql); 
$ret = $prep->execute(array(':searchTerm' => '"%'.$searchTerm.'%"')); 

while ($row = $prep->fetch(PDO::FETCH_ASSOC)) { 
    $i++; 
    $result[$i]['subText'] = $row['hs_pk']; 
    $result[$i]['subText'] = $row['hs_text']; 
    $result[$i]['subDid'] = $row['hs_did']; 
    $result[$i]['devDid'] = $row['hd_did']; 
    $result[$i]['devText'] = $row['hd_text']; 
    $result[$i]['vendorText'] = $row['hv_text']; 
    $result[$i]['classText'] = $row['hc_text']; 
} 
    $dbh = null; 
} 
catch (PDOException $e) { 
    print "Error!: " . $e->getMessage() . "<br/>"; 
    die(); 
} 

He intentado lo siguiente, así (cláusula WHERE de SQL & paración> ejecutar líneas son todo lo que el cambio):

WHERE hs.hs_text LIKE CONCAT(\'%\', ?, \'%\') 
$ret = $prep->execute(array($searchTerm)); 

WHERE hs.hs_text LIKE "%:searchTerm%" 
$ret = $prep->execute(array(':searchTerm' => $searchTerm)); 

WHERE hs.hs_text LIKE ":searchTerm" 
$ret = $prep->execute(array(':searchTerm' => '%'.$searchTerm.'%')); 

etc ...

+1

puede que solo sea una cuestión de transposición, pero no se han cerrado la instrucción SQL - usted necesita poner un apóstrofe (') al final de eso. –

+0

Fue un problema de transposición. Si hubiera olvidado el 'Estoy seguro de que PHP se habría asustado por completo, jajaja. Gracias por la respuesta extremadamente rápida, sin embargo. – TIm

+1

¿Qué obtienes cuando var_dump() $ dbh, $ prep y $ ret? ¿Son los valores que esperas? ¿Has intentado ejecutar la misma consulta usando la familia de funciones mysql_ * para comparar? – jkndrkn

Respuesta

93
$ret = $prep->execute(array(':searchTerm' => '"%'.$searchTerm.'%"')); 

Esto está mal. No necesitas las comillas dobles.

WHERE hs.hs_text LIKE ":searchTerm" 
$ret = $prep->execute(array(':searchTerm' => '%'.$searchTerm.'%')); 

Esto también es incorrecto. Inténtalo con :

$prep = $dbh->prepare($sql); 
$ret = $prep->execute(array(':searchTerm' => '%'.$searchTerm.'%')); 

Explicación: declaraciones preparadas no se limitan a hacer una cadena de reemplazar. Transportan los datos completamente separados de la consulta. Las cotizaciones solo son necesarias cuando se incrustan valores en una consulta.

+0

Gracias por esa explicación.Puede que no resuelva esta, pero la archivaré en mi memoria para usarla en el futuro. – TIm

+26

@Tlm usted todavía debe aceptar su respuesta. responde su pregunta tal como se proporciona directamente. No le cuesta nada aceptar. –

-5

Bueno, he resuelto este. Y francamente, soy un idiota ... Gracias a todos por ver esto y dar buenos comentarios. El problema era un error tipográfico en el nombre de una tabla (que cambié, por lo que nadie aquí podría ver mi problema, para empezar ...). Las sugerencias me llevaron a encontrar el problema, así que gracias adam, jkndrkn y troelskn.

Para el registro, la siguiente combinación funciona bien:

WHERE aw_hcl_subdevices.hs_text LIKE CONCAT(\'%\', ?, \'%\') 
$ret = $prep->execute(array($searchTerm)); 
+14

-1 Esta no es la forma correcta de hacerlo. Debería * no * usar CONCAT() para tres literales de cadena * estáticos *, ya que lo abre a un tipo específico de inyección SQL (me olvido del nombre). –

+4

No sé quiénes son todas estas personas que votaron por el comentario anterior, pero extrañamente, ninguno de ellos logró nombrar la inyección. Probablemente porque tal "inyección" nunca existió. –

+0

Me encantaría escucharlo de @ TheodoreR.Smith si él todavía está por allí. [Más específicamente en esta pregunta distinta] (http://stackoverflow.com/questions/22740375/why-should-you-not-use-concat-for-static-string-literals) – Prix

-2
$prep = $dbh->prepare($sql); 
$ret = $prep->execute(array('searchTerm' => $searchTerm)); 
+4

Este anser no está completo (¿a qué $ sql se refiere?), Está omitiendo algo de información (cómo hacer ".. LIKE '% FOO%'" ¿búsquedas?) Y le falta alguna explicación. Algún código puesto así no es una respuesta, IMO, es simplemente una cosa fuera de contexto. – Redips77

Cuestiones relacionadas