Requêtes SQL fantômes

Jetez un œil au code PHP:

$user->v_useragent = 'coresky.agent'; 

Un tel code peut provoquer une requête SQL UPDATE ou INSERT, ou ne pas provoquer si des données identiques sont déjà installées dans la base de données, c'est pourquoi cette fonctionnalité est appelée Requêtes SQL fantômes. Une fonctionnalité similaire est généralement présente dans la plupart des CRM, mais regardons comment elle peut être implémentée sans CRM. Les requêtes fantômes ont le potentiel d'être assez largement utilisées dans les applications web, notamment en termes de configurations. Un algorithme typique (mais pas nécessaire) se déroule en trois étapes: lecture des données de la base de données, modification des données, éventuellement plusieurs fois, et génération de requêtes SQL réelles pour mettre à jour les données dans la base de données. Voyons les détails ...

Au total, vous devez avoir trois méthodes, une pour chaque étape. Je vais donner le code de la première méthode qui décompresse complètement les données lues dans la base de données, car c'est assez simple:

 class SKY //    coresky { ... static function &ghost($char, $original, $sql = '', $flag = 0) { SKY::$mem[$char] = [$flag, $flag & 4 ? null : $original, $sql, []]; if ($sql) trace('GHOST SQL: ' . (is_array($sql) ? end($sql) : $sql), false, 1); if ($original) foreach (explode("\n", unl($original)) as $v) { list($k, $v) = explode(' ', $v, 2); SKY::$mem[$char][3][$k] = unescape($v, true); } return SKY::$mem[$char][3]; } 

Paramètres d'entrée de méthode:

  • $ char - une petite lettre de l'alphabet anglais, indique le type de fonctionnalité des requêtes fantômes, peut être utilisée dans des préfixes variables, comme dans l'exemple ci-dessus;
  • $ original - le contenu textuel de la cellule de la base de données («mediumtext» pour MySQL), où toutes les variables des requêtes fantômes $ char sont stockées en vrac. Une chaîne vide peut également être entrée;
  • $ sql - un modèle de requête qui sera utilisé pour générer une vraie requête SQL, par exemple, dans une fonction de rappel pour register_shutdown_function ();
  • $ flag - le drapeau. Le plus souvent, une valeur prédéfinie de 0 est utilisée;

Les modèles de requête peuvent être de deux types, basés sur les fonctions sql (..) ou sqlf (..). Je donnerai le deuxième code complètement, car il, lorsqu'il est utilisé correctement, garantit l'impossibilité de l'injection SQL, il est rapide et assez simple:

 function sqlf() { # quick parsing, using printf syntax. No SQL injection! $in = func_get_args(); $tpl = array_shift($in); if ($pos = strpos($tpl, '$')) $tpl = preg_replace('/\$_(\w+)/', T_PREFIX . '$1', $tpl); $sql = vsprintf($tpl, array_map(function ($a) { if (!is_array($a)) return is_num($a) ? $a : escape($a); # escape ALL if not numeric return implode(', ', array_map(function ($v) { return is_num($v) ? $v : escape($v); # escape ALL if not numeric }, $a)); }, $in)); return sql(1, $sql); } 

Malheureusement, la fonction sqlf () n'est pas universelle en termes de compilation de requêtes SQL arbitraires en termes de protection contre l'injection. Cependant, il existe en parallèle avec la fonction universelle sql (), en raison de la vitesse de fonctionnement relativement élevée. Les modèles pour sqlf () sont utilisés dans le cas de travailler avec une seule cellule de texte moyen. Le deuxième modèle est utilisé lorsque vous devez organiser de telles requêtes en attente pour de nombreuses colonnes de la table.

Comment se déroule le traitement du code PHP spécifié au tout début de l'article


La variable $ user contient un pointeur sur un objet USER, qui à son tour a les méthodes magiques __get () et __set (). Par le préfixe v_, la classe comprend qu'elle écrit dans la table de session `visiteurs` et appelle la méthode SKY :: save (..), qui enregistre le code dans le tableau SKY :: $ mem. À la fin du script, la fonction de rappel de register_shutdown_function () est appelée, dans laquelle la requête SQL réelle dans la base de données est réellement exécutée (ou non).

Ainsi, les deux autres méthodes nécessaires à l'organisation de la fonctionnalité sont SKY :: save (..) et SKY :: here (..). Le premier stocke les données dans un tableau, et le second génère et effectue une véritable requête dans la base de données.

Le code coresky (framework réutilisable ou code CMF) utilise 8 types de SQL fantôme:

  • la configuration du système, qui est stockée dans la base de données;
  • Configuration des visiteurs
  • configuration des utilisateurs autorisés;
  • configuration système du panneau d'administration;
  • configuration système des lancements de console;
  • trois types de SQL fantôme sont utilisés pour organiser l'utilitaire i18n;

Comme vous pouvez le voir, «SQL fantôme» est pertinent pour presque toutes les applications Web.

Avantages de la fonctionnalité décrite


  • pas besoin de faire ALTER TABLE ... (ou INSERER de nouvelles lignes) pour ajouter de nouvelles variables de configuration au fur et à mesure que l'application se développe. Vous pouvez ajouter de nouvelles variables simplement en code PHP sans changer la structure de la base de données;
  • la fonctionnalité peut réduire le nombre de requêtes de base de données à un, dans le cas où il y a un enregistrement dans la même ligne de la même table;

Inconvénient


Pour les variables SQL fantômes, vous ne pouvez pas «visser» les index, très probablement, vous ne pouvez pas créer LOCK TABLE ou utiliser d'autres fonctionnalités avancées de MySQL.

Plus d'informations peuvent être trouvées sur le site web du projet SKY.

Source: https://habr.com/ru/post/fr451034/


All Articles