alpha_full/admin/adminInclude/_fonctions/fonctionRequete_select.php
2026-04-06 22:58:51 +02:00

191 lines
7.5 KiB
PHP
Executable File

<?php
//afficherMsg==1 affiche le succes; afficherMsg==1 ou 2 affiche si erreur
function dynRequete_select($queryType, $tableName, $fields = [], $conditions = [], $orderBy='', $ficAppelant = '', $afficherMsg = 0, $localDebug = 0, $resultName='') {
global $admMsg, $admMsgClass, $idPdo, $debugMsg, $debug ; // Déclaration unique des variables globales
$startTime = microtime(true); // Pour mesurer le temps d'exécution
$reqSelect = '';
//gestion des requetes imbriquées : nom du tableau de résultat dynamique
$resultTab = empty($resultName) ? 'tabResult' : $resultName;
if (!isset($$resultTab)) {
$$resultTab = []; // Initialise le tableau dynamique
}
//blindage tere sur de ne jamais afficher le debug en prod en rajoutant le $debug en plus du local
// peutre plus besoin du local plus tard ?
if ($localDebug == 2 && ( isset($debug[1]) && $debug[1] == '1' || isset($debug[2]) && $debug[2] == '1') ) $debugMsg .= monDebug(2, ['queryType' => $queryType, 'tableName' => $tableName ] ,'fonctionRequete_select.php (generique)', $ficAppelant);
// ----------------------------------------------------
// Gestion des champs retournés
// ----------------------------------------------------
// Gestion des backticks sauf si le champ est *
// ----------------------------------------------------
$escapedFields = array_map(function($field) {
// Si le champ est '*' on ne fait rien, sinon on échappe les champs avec backticks
if ($field === '*') {
return '*';
}
// Si le champ contient un point (pour une jointure), on échappe chaque partie (table/alias + champ)
$fieldParts = explode('.', $field);
if (count($fieldParts) === 2) {
// Exemple: 'cl.idCat' ou 'c.lienImageWeb'
return "$fieldParts[0].$fieldParts[1]";
// return "`$fieldParts[0]`.`$fieldParts[1]`";
} else {
// Cas où il n'y a pas de jointure, on échappe simplement le champ
// return "`$field`";
return "$field";
}
}, $fields);
$fieldsStr = implode(", ", $escapedFields);
// ----------------------------------------------------
// Construction du debut de la requete
// ----------------------------------------------------
if (!(substr($tableName, 0, 1) === '`' && substr($tableName, -1) === '`')) {
$tableName = "`" . str_replace("`", "", $tableName) . "`";
}
if ($queryType == 'SELECT') $reqSelect = "SELECT " .$fieldsStr. " FROM " .$tableName."";
if ($queryType == 'MAX') $reqSelect = "SELECT MAX(".$fieldsStr.") as max FROM " . $tableName."";
if ($queryType == 'COUNT') $reqSelect = "SELECT COUNT(".$fieldsStr.") as count FROM " .$tableName."";
// ----------------------------------------------------
// Ajout des conditions WHERE si elles existent
// ----------------------------------------------------
$bindParams = [];
if (!empty($conditions) && is_array($conditions)) {
$whereClauses = [];
foreach ($conditions as $key => $value) {
if ($localDebug == 2 && ( isset($debug[1]) && $debug[1] == '1' || isset($debug[2]) && $debug[2] == '1') ) $debugMsg .= monDebug(2, [''. $key => ''.$value], '');
$operator = '=';
if (preg_match('/\s+(=|!=|LIKE|IN)$/i', $key, $m)) {
$operator = strtoupper($m[1]);
$key = trim(str_ireplace($m[0], '', $key)); // enlève l'opérateur de la clé
}
// Échapper correctement la clé de la condition si alias de table de type client.id, devient 'client.id'
$escapedKey = escapeConditionKey($key);
// Nom du paramètre PDO qui vaudra :value ( paramName sera la partie droite si client.id ou le champ seul si id)
$keyParts = explode('.', $key); // Sépare la table de la colonne
$paramName = (count($keyParts) === 2) ? $keyParts[1] : $keyParts[0];
if ($operator === 'IN') {
if (is_array($value) && !empty($value)) {
$inParams = [];
foreach ($value as $i => $val) {
$p = $paramName . '_' . $i;
$inParams[] = ':' . $p;
$bindParams[$p] = $val;
}
$whereClauses[] = "$escapedKey IN (" . implode(',', $inParams) . ")";
}
} else {
// LIKE ou = ou !=
$whereClauses[] = "$escapedKey $operator :$paramName";
$bindParams[$paramName] = $value;
}
}
$reqSelect .= " WHERE " . implode(' AND ', $whereClauses);
}
$reqSelect .= " " .$orderBy. " "; // Order
$reqSelect .= ";"; // Fin de la requête
// Debug affichage de la requete brute
if ($localDebug == 2 && ( isset($debug[1]) && $debug[1] == '1' || isset($debug[2]) && $debug[2] == '1') ) { $debugMsg .= monDebug(2, ['requete Brute' => $reqSelect ], $ficAppelant); }
// Requete construite
$requeteFinale = reconstruireRequete($reqSelect, $bindParams);
// Debug affichage de la requete construite
if ( ($localDebug == 1 || $localDebug == 2) && ( isset($debug[1]) && $debug[1] == '1' || isset($debug[2]) && $debug[2] == '1') ) {
$debugMsg .= monDebug (2, ['Requête' => $requeteFinale ], $ficAppelant );
}
// ----------------------------------------------------
// Exécution de la requête
// ----------------------------------------------------
try {
$stmt = $idPdo->prepare($reqSelect);
// Execution
$stmt->execute($bindParams ?? []);
// On récupère les résultats
if ($stmt) {
$$resultTab= $stmt->fetchAll(PDO::FETCH_ASSOC);
}
if ($localDebug == 2 && ( isset($debug[1]) && $debug[1] == '1' || isset($debug[2]) && $debug[2] == '1') ) {
$debugMsg .= '<br>';
foreach ($$resultTab as $index => $row) {
$line = [];
foreach ($row as $key => $value) {
// sécurité : éviter tableaux / objets
if (is_array($value) || is_object($value)) {
$value = json_encode($value);
}
$line[] = "[$key] => $value";
}
$debugMsg .= '<b>Champ trouvé : </b>'.implode(' | ', $line) . " | ";
}
}
if ($afficherMsg == 1) { $admMsg .= "Requête exécutée avec succès "; $admMsgClass='ok';}
} catch (PDOException $e) {
if ($afficherMsg != 0) { $admMsg .= "Erreur lors de l'exécution de la requête"; }
if ( ($localDebug == 1 || $localDebug == 2) && ( isset($debug[1]) && $debug[1] == '1' || isset($debug[2]) && $debug[2] == '1') ) {
$erreur = $idPdo->errorInfo();
$debugMsg .= monDebug(2,[
'PDO message' => $e->getMessage(),
'SQLSTATE' => $erreur[0],
'Driver code' => $erreur[1],
'Erreur mysql' => $erreur[2],
'SQL' => $reqSelect
// 'Params' => $bindParams
],'fonctionRequete_select.php', $ficAppelant );
}
$admMsgClass='ko';
return []; // Retourner échec
}
// Temps d'exécution (si nécessaire)
if ($localDebug == 1 && ( isset($debug[1]) && $debug[1] == '1' || isset($debug[2]) && $debug[2] == '1') ) {
$endTime = microtime(true);
$executionTime = $endTime - $startTime;
$debugMsg .= " | Temps d'exécution : " . number_format($executionTime, 5) . " secondes.";
}
return $$resultTab; // Retourner le résultat
}
function reconstruireRequete($sql, $params) {
foreach ($params as $key => $val) {
$escaped = is_numeric($val) ? $val : "'" . addslashes($val) . "'";
$sql = str_replace(":$key", $escaped, $sql); // Remplace les `:param`
}
return $sql;
}
function escapeConditionKey($key) {
// Si la clé contient un point (par exemple `cl.idCat`), c'est un alias de table
if (strpos($key, '.') !== false) {
$keyParts = explode('.', $key); // Sépare la table de la colonne
return "$keyParts[0].$keyParts[1]"; // Échappe la table et la colonne
} else {
// Si la clé ne contient pas de point, c'est simplement une colonne sans alias
return "`$key`"; // Échappe uniquement le nom de la colonne
}
}
?>