usar todas sintaxis para mundo listos las instrucciones hola etiquetas ejemplos comandos codigos php sql coding-style

todas - ¿Cómo incrusta sus consultas sql en scripts php(estilo de codificación)?



sintaxis php (10)

¿Cómo incrusta sus scripts sql en php? ¿Simplemente los escribe en una cadena o un heredoc o los externaliza a un archivo sql? ¿Existen mejores prácticas para subcontratarlos? ¿Hay una forma elegante de organizar esto?


Depende del tamaño y la dificultad de una consulta.

Personalmente me gusta heredocs. Pero no lo uso para consultas simples. Eso no es importante. Lo principal es "Nunca olvides escapar de los valores"


Normalmente los escribo como argumento de función:

db_exec ("SELECT ...");

Excepto en los casos en que sql va a ser muy grande, lo paso como variable:

$SQL = "SELECT ..."; $result = db_exec ($SQL);

(Utilizo wrapper-funciones u objetos para operaciones de base de datos)


Puede utilizar un generador de cadenas ORM o sql, pero algunas consultas complejas requieren escribir sql. Al escribir sql, como lo ilustra Michał Słaby, utilice enlaces de consulta. Los enlaces de consulta previenen la inyección de sql y mantienen la legibilidad. En cuanto a dónde colocar sus consultas: use las clases modelo.


Siempre debe realmente SIEMPRE usar declaraciones de preparación con marcadores de posición para sus variables.

Es un poco más código, pero se ejecuta de manera más eficiente en la mayoría de los DB y te protege contra los ataques de inyección SQL.


Una vez que llegue a un cierto nivel, se dará cuenta de que el 99% del SQL que escribe podría ser automático. Si escribe tantas consultas que piensa en un archivo de propiedades, probablemente esté haciendo algo que podría ser más simple:

La mayoría de las cosas que hacemos los programadores es CRUD: Crear Leer Actualizar Eliminar

Como herramienta para mí, construí Pork.dbObject. Object Relation Mapper + Active Record en 2 clases simples (Database Abstraction + clase dbObject)

Un par de ejemplos de mi sitio:

Crea un weblog:

$weblog = new Weblog(); // create an empty object to work with. $weblog->Author = ''SchizoDuckie''; // mapped internally to strAuthor. $weblog->Title = ''A test weblog''; $weblog->Story = ''This is a test weblog!''; $weblog->Posted = date("Y-m-d H:i:s"); $weblog->Save(); // Checks for any changed values and inserts or updates into DB. echo ($weblog->ID) // outputs: 1

Y una respuesta a esto:

$reply = new Reply(); $reply->Author = ''Some random guy''; $reply->Reply = ''w000t''; $reply->Posted = date("Y-m-d H:i:s"); $reply->IP = ''127.0.0.1''; $reply->Connect($weblog); // auto-saves $reply and connects it to $weblog->ID

Y, busque y muestre el weblog + todas las respuestas:

$weblog = new Weblog(1); //Fetches the row with primary key 1 from table weblogs and hooks it''s values into $weblog; echo("<h1>{$weblog->Title}</h1> <h3>Posted by {$weblog->Author} @ {$weblog->Posted}</h3> <div class=''weblogpost''>{$weblog->Story}</div>"); // now fetch the connected posts. this is the real magic: $replies = $weblog->Find("Reply"); // fetches a pre-filled array of Reply objects. if ($replies != false) { foreach($replies as $reply) { echo("<div class=''weblogreply''><h4>By {$reply->Author} @ {$reply->Posted}</h4> {$reply->Reply}</div>"); } }

El objeto weblog se vería así:

class Weblog extends dbObject { function __construct($ID=false) { $this->__setupDatabase(''blogs'', // database table array(''ID_Blog'' => ''ID'', // database field => mapped object property ''strPost'' => ''Story'', // as you can see, database field strPost is mapped to $this->Story ''datPosted'' => ''Posted'', ''strPoster'' => ''Author'', ''strTitle'' => ''Title'', ''ipAddress'' => ''IpAddress'', ''ID_Blog'', // primary table key $ID); // value of primary key to init with (can be false for new empty object / row) $this->addRelation(''Reaction''); // define a 1:many relation to Reaction } }

Ver, no hay escritura SQL manual :) Enlace + más ejemplos: Pork.dbObject

Oh, sí, también creé una GUI rudimentaria para mi herramienta de andamios: Pork.Generator


Use un marco con una capa ORM (Object-Relational Mapping). De esta forma no tienes que poner SQL directamente en ningún lado. SQL incrustado apesta para la legibilidad, el mantenimiento y todo.


$sql = sprintf("SELECT * FROM users WHERE id = %d", mysql_real_escape_string($_GET["id"]));

Seguro de la inyección de MySQL


Prefiero como tal:

$sql = "SELECT tbl1.col1, tbl1.col2, tbl2.col1, tbl2.col2" . " FROM Table1 tbl1" . " INNER JOIN Table2 tbl2 ON tbl1.id = tbl2.other_id" . " WHERE tbl2.id = ?" . " ORDER BY tbl2.col1, tbl2.col2" . " LIMIT 10, 0";

Podría tomar PHP un poco más de tiempo para concatenar todas las cadenas, pero creo que se ve mucho mejor y es más fácil de editar.

Ciertamente, para consultas extremadamente largas y especializadas, tendría sentido leer un archivo .sql o usar un procedimiento almacenado. Dependiendo de su marco, esto podría ser tan simple como:

$sql = (string) View::factory(''sql/myfile'');

(que le da la opción de asignar variables en la vista / plantilla si es necesario). Sin la ayuda de un motor o framework de plantillas, usarías:

$sql = file_get_contents("myfile.sql");

Espero que esto ayude.


Recuerde siempre escaparse de la entrada. No lo hagas manualmente, usa declaraciones preparadas. Aquí hay un método de ejemplo de mi clase de informes.

public function getTasksReport($rmId, $stage, $mmcName) { $rmCondition = $rmId ? ''mud.manager_id = :rmId'' : ''TRUE''; $stageCondition = $stage ? ''t.stage_id = :stageId'' : ''TRUE''; $mmcCondition = $mmcName ? ''mmcs.username = :mmcName'' : ''TRUE''; $sql = " SELECT mmcs.id AS mmc_id, mmcs.username AS mmcname, mud.band_name AS mmc_name, t.id AS task_id, t.name AS task, t.stage_id AS stage, t.role_id, tl.id AS task_log_id, mr.role, u.id AS user_id, u.username AS username, COALESCE(cud.full_name, bud.band_name) AS user_name, DATE_FORMAT(tl.completed_on, ''%d-%m-%Y %T'') AS completed_on, tl.url AS url, mud.manager_id AS rm_id FROM users AS mmcs INNER JOIN banduserdetails AS mud ON mud.user_id = mmcs.id LEFT JOIN tasks AS t ON 1 LEFT JOIN task_log AS tl ON tl.task_id = t.id AND tl.mmc_id = mmcs.id LEFT JOIN mmc_roles AS mr ON mr.id = t.role_id LEFT JOIN users AS u ON u.id = tl.user_id LEFT JOIN communityuserdetails AS cud ON cud.user_id = u.id LEFT JOIN banduserdetails AS bud ON bud.user_id = u.id WHERE mmcs.user_type = ''mmc'' AND $rmCondition AND $stageCondition AND $mmcCondition ORDER BY mmcs.id, t.stage_id, t.role_id, t.task_order "; $pdo = new PDO(.....); $stmt = $pdo->prepare($sql); $rmId and $stmt->bindValue(''rmId'', $rmId); // (1) $stage and $stmt->bindValue(''stageId'', $stage); // (2) $mmcName and $stmt->bindValue(''mmcName'', $mmcName); // (3) $stmt->execute(); return $stmt->fetchAll(); }

En las líneas marcadas (1), (2) y (3) verá una forma de enlace condicional.

Para consultas simples utilizo el marco ORM para reducir la necesidad de construir SQL manualmente.


Me gusta este formato Fue mencionado en un comentario anterior, pero la alineación me pareció desagradable.

$query = "SELECT " . " foo, " . " bar " . "FROM " . " mytable " . "WHERE " . " id = $userid";

Lo suficientemente fácil de leer y entender. Los puntos se alinean con el signo igual manteniendo todo en una línea limpia.

Me gusta la idea de mantener tu SQL en un archivo separado también, aunque no estoy seguro de cómo funcionaría con variables como $ userid en mi ejemplo anterior.