


Les plats clés
- PINQ, un port PHP Linq, peut être utilisé pour imiter une fonction de recherche à facettes avec MySQL, offrant une approche puissante et simple.
- Une recherche à facettes fonctionne en prenant des mots clés fournis par l'utilisateur pour rechercher des produits, en retournant des produits correspondants et en offrant des liens pour affiner la recherche en fonction de différentes marques, gammes de prix et fonctionnalités.
- PINQ peut être utilisé pour étendre une application de démonstration en ajoutant des fonctionnalités de recherche à facettes essentielles, telles que le regroupement par une plage de valeur dans une étape spécifiée par $ gamme.
- La recherche à facettes implémentée avec PINQ récupère les données du serveur MySQL à chaque fois, qui peut être évitée en utilisant un moteur de mise en cache.
- Bien qu'il s'agisse d'une démo de base, l'approche de Pinq à la recherche à facettes offre beaucoup de place à l'amélioration et peut être construite sur des cas d'utilisation plus avancés.
Dans la partie 1, nous avons brièvement couvert l'installation et la syntaxe de base de PINQ, un port PHP LINQ. Dans cet article, nous verrons comment utiliser PINQ pour imiter une fonction de recherche à facettes avec mysql.
Nous n'allons pas couvrir le plein aspect de la recherche à facettes dans cette série. Les parties intéressées peuvent se référer aux articles pertinents publiés sur SitePoint et d'autres publications Internet.
Une recherche à facettes typique fonctionne comme celle-ci dans un site Web:
- Un utilisateur fournit un mot-clé ou quelques mots clés à rechercher. Par exemple, «routeur» pour rechercher des produits contenant «routeur» dans la description, mot-clé, catégorie, balises, etc.
- Le site renvoie les produits correspondant aux critères.
- Le site fournira des liens pour affiner la recherche. Par exemple, il peut inciter à différentes marques pour un routeur, et il peut y avoir différentes gammes de prix et différentes fonctionnalités.
- L'utilisateur peut être davantage filtrant les résultats en cliquant sur les différents liens fournis et finalement obtenir un ensemble de résultats plus personnalisé.
La recherche à facettes est si populaire et puissante et vous pouvez en faire l'expérience dans presque tous les site de commerce électronique.
Malheureusement, la recherche à facettes n'est pas encore une fonctionnalité intégrée fournie par MySQL. Que pouvons-nous faire si nous utilisons MySQL mais que nous voulons également fournir à nos utilisateurs une telle fonctionnalité?
Avec PINQ, nous verrons qu'il existe une approche tout aussi puissante et simple pour y parvenir comme lorsque nous utilisons d'autres moteurs DB - du moins d'une certaine manière.
Extension de la démo de la partie 1
Remarque: tout le code de cette partie et la démonstration de la partie 1 peuvent être trouvés dans le dépôt.
Dans cet article, nous prolongerons la démo que nous avons montrée dans la partie 1 et ajouterons certaines fonctionnalités de recherche à facettes essentielles.
Commençons par index.php en ajoutant les quelques lignes suivantes:
<span>$app->get('demo2', function () use ($app) </span><span>{ </span> <span>global $demo; </span> <span>$test2 = new pinqDemo<span>\Demo</span>($app); </span> <span>return $test2->test2($app, $demo->test1($app)); </span><span>} </span><span>); </span> <span>$app->get('demo2/facet/{key}/{value}', function ($key, $value) use ($app) </span><span>{ </span> <span>global $demo; </span> <span>$test3 = new pinqDemo<span>\Demo</span>($app); </span> <span>return $test3->test3($app, $demo->test1($app), $key, $value); </span><span>} </span><span>);</span>
Nous venons de créer deux autres itinéraires dans notre application de démonstration (en utilisant Silex).
La première route consiste à nous amener à la page affichant tous les enregistrements qui correspondent à notre premier comportement de recherche, c'est-à-dire la recherche en fournissant un mot-clé. Pour garder la démo simple, nous sélectionnons tous les livres dans l'exemple de table book_book. Il affichera également l'ensemble de résultats et les liens à facettes pour une navigation supplémentaire.
Le deuxième itinéraire nous amène à une autre page montrant les enregistrements correspondant aux autres critères de recherche de facettes dans l'ensemble de résultats produit à l'étape ci-dessus. Il affichera également les liens de recherche à facettes.
Dans une implémentation du monde réel, une fois un lien à facettes cliqué, tout filtrage à facettes dans la page de résultats sera ajusté pour refléter les informations statistiques de l'ensemble de données de résultat. Ce faisant, l'utilisateur peut appliquer des dépistages «complémentaires», en ajoutant «marque» d'abord puis «gamme de prix», etc.
Mais dans cette démo simple, nous sauterons cette approche, toutes les recherches à facettes et les liens ne refléteront que les informations sur l'ensemble de données d'origine. Il s'agit de la première restriction et du premier domaine d'amélioration de notre démo.
Comme nous le voyons dans le code ci-dessus, les fonctions réelles résident dans un autre fichier appelé pinqdemo.php. Voyons le code pertinent qui fournit la fonction de recherche à facettes.
une classe facette
Tout d'abord, nous créons une classe pour représenter une facette. Généralement, une facette doit avoir quelques propriétés:
- les données sur lesquelles il fonctionne ($ data)
- La clé informatique se regroupe sur ($ key)
- Le type de clé (type $). Cela peut être l'un des ci-dessous:
- Spécifiez une chaîne complète pour faire une correspondance exacte
- Spécifiez partiel (normalement en début) d'une chaîne pour faire une correspondance de modèle
- Spécifiez une plage de valeur au groupe par une plage de valeur
- Si le type de clé est une plage, il est nécessaire de spécifier une étape de valeur pour déterminer la limite supérieure / inférieure de la plage; ou si le type de clé est une chaîne partielle, nous devons fournir un numéro pour spécifier le nombre de premières lettres devraient être utilisées pour regrouper ($ gamme)
Le regroupement est la partie la plus critique d'une facette. Toutes les informations d'agrégation qu'une facette pourrait éventuellement retourner dépend des critères de «regroupement». Normalement, la «chaîne complète», la «chaîne partielle» et la «plage de valeur» sont les plus couramment utilisées.
<span>$app->get('demo2', function () use ($app) </span><span>{ </span> <span>global $demo; </span> <span>$test2 = new pinqDemo<span>\Demo</span>($app); </span> <span>return $test2->test2($app, $demo->test1($app)); </span><span>} </span><span>); </span> <span>$app->get('demo2/facet/{key}/{value}', function ($key, $value) use ($app) </span><span>{ </span> <span>global $demo; </span> <span>$test3 = new pinqDemo<span>\Demo</span>($app); </span> <span>return $test3->test3($app, $demo->test1($app), $key, $value); </span><span>} </span><span>);</span>
Dans cette classe, la fonction clé consiste à renvoyer l'ensemble de résultats à facettes en fonction des données et des propriétés de clé de facette. Nous avons remarqué que pour différents types de clés, il existe différentes façons de regrouper les données. Dans ce qui précède, nous avons montré à quoi ressemblera le code si nous regroupons les données par une plage de valeur dans une étape spécifiée par $ plage.
Faire des facettes et affichage des données d'origine
<span>namespace classFacet </span><span>{ </span> <span>use Pinq<span>\ITraversable</span>, </span> Pinq\Traversable<span>; </span> <span>class Facet </span> <span>{ </span> <span>public $data; // Original data </span> <span>public $key; // the field to be grouped on </span> <span>public $type; // F: full string; S: start of a string; R: range; </span> <span>public $range; // Only valid if $type is not F </span> <span>... </span> <span>public function getFacet() </span> <span>{ </span> <span>$filter = ''; </span> <span>if ($this->type == 'F') // Full string </span> <span>{ </span> <span>... </span> <span>} </span> <span>elseif ($this->type == "S") //Start of string </span> <span>{ </span> <span>... </span> <span>} </span> <span>elseif ($this->type == "R") // A value range </span> <span>{ </span> <span>$filter = $this->data </span> <span>->groupBy(function($row) </span> <span>{ </span> <span>return floor($row[$this->key] / $this->range) * $this->range; </span> <span>}) </span> <span>->select(function (ITraversable $data) </span> <span>{ </span> <span>return ['key' => $data->last()[$this->key], 'count' => $data->count()]; </span> <span>}); </span> <span>} </span> <span>return $filter; </span> <span>} </span> <span>} </span><span>}</span>
Dans la fonction getfacet (), nous effectuons les étapes suivantes:
- Convertir les données d'origine en un objet PINQTraversable pour un traitement ultérieur.
- Nous créons 3 facettes. La facette «auteur» se regroupera sur l’auteur de terrain et il s’agit d’un regroupement de cordes complet; Facette «Title» sur le titre de terrain et un groupe de chaînes partiels (le nombre de lettres de départ); Facette «Prix» sur le prix du terrain et un regroupement de gamme (par une étape de 10).
- Enfin, nous obtenons les facettes et les renvoyons à la fonction Test2 afin que le modèle puisse rendre les données et les facettes.
Affichage des facettes et des données filtrées
La plupart du temps, les facettes seront affichées sous forme de lien et nous amèneront à un ensemble de données filtrées.
Nous avons déjà créé une route ('Demo2 / Facet / {Key} / {Value}') pour afficher les résultats de recherche à facettes et les liens de facette.
L'itinéraire prend deux paramètres, reflétant la clé sur laquelle nous facet et la valeur de cette clé. La fonction TEST3 qui finit par être invoquée à partir de cette route est extraite ci-dessous:
<span>$app->get('demo2', function () use ($app) </span><span>{ </span> <span>global $demo; </span> <span>$test2 = new pinqDemo<span>\Demo</span>($app); </span> <span>return $test2->test2($app, $demo->test1($app)); </span><span>} </span><span>); </span> <span>$app->get('demo2/facet/{key}/{value}', function ($key, $value) use ($app) </span><span>{ </span> <span>global $demo; </span> <span>$test3 = new pinqDemo<span>\Demo</span>($app); </span> <span>return $test3->test3($app, $demo->test1($app), $key, $value); </span><span>} </span><span>);</span>
Fondamentalement, en fonction de la clé, nous appliquons le filtrage (la fonction anonyme dans la clause) correspondant à la valeur transmise et obtenez les données supplémentaires. Nous pouvons également spécifier l'ordre des données à facettes.
Enfin, nous affichons les données (avec les facettes) dans un modèle. Cette route rend le même modèle que celui qui est utilisé par la route 'Demo2').
Ensuite, jetons un coup d'œil au modèle et voyons comment les liens de facette sont affichés. J'utilise Bootstrap pour que les composants CSS utilisés ici soient assez familiers:
<span>namespace classFacet </span><span>{ </span> <span>use Pinq<span>\ITraversable</span>, </span> Pinq\Traversable<span>; </span> <span>class Facet </span> <span>{ </span> <span>public $data; // Original data </span> <span>public $key; // the field to be grouped on </span> <span>public $type; // F: full string; S: start of a string; R: range; </span> <span>public $range; // Only valid if $type is not F </span> <span>... </span> <span>public function getFacet() </span> <span>{ </span> <span>$filter = ''; </span> <span>if ($this->type == 'F') // Full string </span> <span>{ </span> <span>... </span> <span>} </span> <span>elseif ($this->type == "S") //Start of string </span> <span>{ </span> <span>... </span> <span>} </span> <span>elseif ($this->type == "R") // A value range </span> <span>{ </span> <span>$filter = $this->data </span> <span>->groupBy(function($row) </span> <span>{ </span> <span>return floor($row[$this->key] / $this->range) * $this->range; </span> <span>}) </span> <span>->select(function (ITraversable $data) </span> <span>{ </span> <span>return ['key' => $data->last()[$this->key], 'count' => $data->count()]; </span> <span>}); </span> <span>} </span> <span>return $filter; </span> <span>} </span> <span>} </span><span>}</span>
Nous devons nous rappeler que la facette générée par notre application est un réseau imbriqué. Dans la première couche, il s'agit d'un tableau de toutes les facettes, et dans notre cas, nous avons un total de 3 (pour auteur, titre, auteur, respectivement).
Pour chaque facette, il s'agit d'un tableau apparié «Valeur clé» afin que nous puissions itérer de manière traditionnelle.
Veuillez noter comment nous construisons les URI des liens. Nous avons utilisé à la fois la clé de la boucle extérieure (k) et la clé de boucles internes (vv.key) pour être les paramètres de la route ('Demo2 / Facet / {key} / {value}'). Le nombre de la clé (Vv.Count) est utilisé pour retoucher l'affichage dans le modèle (en tant que badge bootstrap).
Le modèle sera rendu comme indiqué ci-dessous:
(le premier montre la page d'entrée initiale et le second affiche un résultat à facettes avec un prix entre 0 $ et 10 $ et commandé par l'auteur)
Très bien, jusqu'à présent, nous avons réussi à imiter une fonction de recherche à facettes dans notre application Web!
Avant de conclure cette série, nous allons jeter un coup d'œil à cette démo et voir ce qui peut être fait pour l'améliorer et quelles sont les limites.
Améliorations à faire
Dans l'ensemble, il s'agit d'une démo assez rudimentaire. Nous venons de parcourir la syntaxe et les concepts de base et les avons forgés dans un exemple de canette. Comme nous l'avons vu plus tôt, quelques zones peuvent être améliorées pour la rendre plus flexible.
Nous devons envisager de fournir une capacité de recherche de critères «complémentaire». Notre implémentation actuelle limite la recherche de facettes à appliquer uniquement sur l'original, au lieu des données criblées. C'est l'amélioration la plus importante à laquelle je peux penser.
limitations
La recherche à facettes implémentée ici a une limitation profonde (et probablement vrai pour les autres implémentations de recherche à facettes):
Nous récupérons les données du serveur MySQL à chaque fois.
Cette application utilise Silex comme cadre. Pour tout cadre d'entrée unique comme Silex, Symfony, Laravel, son index.php (ou app.php) est appelé chaque fois qu'un itinéraire doit être analysé et la fonction d'un contrôleur doit être invoquée.
En regardant le code dans notre index.php, nous verrons que cela signifie également la ligne de code ci-dessous:
<span>$app->get('demo2', function () use ($app) </span><span>{ </span> <span>global $demo; </span> <span>$test2 = new pinqDemo<span>\Demo</span>($app); </span> <span>return $test2->test2($app, $demo->test1($app)); </span><span>} </span><span>); </span> <span>$app->get('demo2/facet/{key}/{value}', function ($key, $value) use ($app) </span><span>{ </span> <span>global $demo; </span> <span>$test3 = new pinqDemo<span>\Demo</span>($app); </span> <span>return $test3->test3($app, $demo->test1($app), $key, $value); </span><span>} </span><span>);</span>
s'appelle chaque fois qu'une page de l'application s'affiche, ce qui signifie alors que les lignes suivantes sont exécutées à chaque fois:
<span>namespace classFacet </span><span>{ </span> <span>use Pinq<span>\ITraversable</span>, </span> Pinq\Traversable<span>; </span> <span>class Facet </span> <span>{ </span> <span>public $data; // Original data </span> <span>public $key; // the field to be grouped on </span> <span>public $type; // F: full string; S: start of a string; R: range; </span> <span>public $range; // Only valid if $type is not F </span> <span>... </span> <span>public function getFacet() </span> <span>{ </span> <span>$filter = ''; </span> <span>if ($this->type == 'F') // Full string </span> <span>{ </span> <span>... </span> <span>} </span> <span>elseif ($this->type == "S") //Start of string </span> <span>{ </span> <span>... </span> <span>} </span> <span>elseif ($this->type == "R") // A value range </span> <span>{ </span> <span>$filter = $this->data </span> <span>->groupBy(function($row) </span> <span>{ </span> <span>return floor($row[$this->key] / $this->range) * $this->range; </span> <span>}) </span> <span>->select(function (ITraversable $data) </span> <span>{ </span> <span>return ['key' => $data->last()[$this->key], 'count' => $data->count()]; </span> <span>}); </span> <span>} </span> <span>return $filter; </span> <span>} </span> <span>} </span><span>}</span>
sera-t-il mieux si nous évitons d'utiliser un cadre? Eh bien, en plus du fait que ce n'est pas vraiment une très bonne idée de développer une application sans cadre, nous sommes toujours confrontés au même problème: les données (et le statut) ne sont pas persistants d'un appel HTTP à un autre. C'est la caractéristique fondamentale de HTTP. Cela doit être évité avec l'utilisation d'un moteur de mise en cache.
Nous enregistrons certaines instructions SQL exécutées du côté du serveur lorsque nous construisons les facettes. Au lieu de passer 1 requête de sélection et 3 requêtes de groupe différentes par la même instruction, nous émettant simplement une requête sélectionnée avec l'instruction WHERE et utilisons PINQ pour fournir les informations d'agrégation.
Conclusion
Dans cette partie, nous avons réussi à imiter une capacité de recherche de facettes pour notre site de collecte de livres. Comme je l'ai dit, il s'agit simplement d'une démo à canette et a beaucoup d'amélioration et certaines limitations par défaut. Faites-nous savoir si vous construisez sur cet exemple et pouvez nous montrer des cas d'utilisation plus avancés!
L'auteur de PINQ travaille maintenant sur la prochaine version de version principale (version 3). J'espère que cela peut devenir plus puissant.
N'hésitez pas à laisser vos commentaires et vos pensées ci-dessous!
Questions fréquemment posées (FAQ) sur PINQ et la recherche à facettes
Qu'est-ce que PINQ et comment est-il lié à la recherche à facettes?
PINQ est une bibliothèque PHP qui fournit un langage de requête unique, intuitif et puissant pour manipuler des tableaux et d'autres ensembles de données. Il est conçu pour simplifier le processus de requête et de manipulation des données. En ce qui concerne la recherche à facettes, PINQ peut être utilisé pour créer des requêtes complexes qui peuvent filtrer et trier les données en fonction de plusieurs critères, qui est le concept principal de la recherche à facettes.
Comment l'approche de Pinq à la recherche à facettes diffère-t-elle des autres méthodes?
L'approche de Pinq de la recherche à facettes est unique car elle utilise un langage de requête basé sur PHP, qui est un langage de programmation largement utilisé. Cela facilite les développeurs qui connaissent déjà PHP pour implémenter la recherche facettée. De plus, le langage de requête de Pinq est conçu pour être intuitif et facile à utiliser, ce qui peut simplifier le processus de création de requêtes complexes.
peut être utilisée avec d'autres bases de données ou est-elle limitée à MySQL?
PINQ n'est pas limité à MySQL. Il peut être utilisé avec n'importe quel ensemble de données, y compris les tableaux et autres bases de données. Cette flexibilité fait de PINQ un outil polyvalent pour les développeurs qui ont besoin de travailler avec différents types de données.
Comment PINQ gère-t-il les grands ensembles de données?
PINQ est conçu pour gérer efficacement de grands ensembles de données. Il le fait en utilisant une stratégie d'évaluation paresseuse, ce qui signifie qu'il ne traite que les données lorsqu'elle est réellement nécessaire. Cela peut améliorer considérablement les performances lorsque vous travaillez avec de grands ensembles de données.
Quels sont les avantages de l'utilisation de PINQ pour la recherche à facettes?
L'utilisation de PINQ pour la recherche à facettes présente plusieurs avantages. Premièrement, il simplifie le processus de création de requêtes complexes, ce qui peut faire gagner du temps et des efforts pour les développeurs. Deuxièmement, il fournit un langage de requête puissant et flexible qui peut gérer un large éventail de types de données et de structures. Enfin, il est basé sur PHP, qui est un langage de programmation largement utilisé, ce qui facilite l'apprentissage et l'utilisation des développeurs. 🎜> PINQ est conçu pour être intuitif et facile à utiliser, ce qui le rend adapté aux débutants et aux développeurs expérimentés. Cependant, une certaine connaissance des langages PHP et de requête est bénéfique lors de l'utilisation de PINQ.
Comment PINQ garantit-il la précision des résultats de recherche?
PINQ assure la précision des résultats de recherche en utilisant un puissant et flexible Interroger le langage qui peut filtrer et trier avec précision les données en fonction de plusieurs critères. Cela lui permet de fournir des résultats de recherche précis et pertinents.
PINQ peut être utilisé pour la recherche en temps réel?
Oui, PINQ peut être utilisé pour une recherche en temps réel. Sa gestion efficace des grands ensembles de données et sa capacité à créer des requêtes complexes le rendent adapté aux applications de recherche en temps réel.
Comment PINQ se compare-t-il aux autres bibliothèques PHP pour la recherche facettée?
PINQ Stands D'autres bibliothèques PHP pour la recherche à facettes en raison de son langage de requête unique, intuitif et puissant. Il offre également une flexibilité en termes de types de données qu'il peut gérer, et sa manipulation efficace de grands ensembles de données en fait un choix fort pour les développeurs.
Est-ce que PINQ est open source et peut-il être personnalisé?
Oui, PINQ est une bibliothèque open source, ce qui signifie que les développeurs peuvent le personnaliser en fonction de leurs besoins spécifiques. Cette flexibilité est un autre avantage de l'utilisation de PINQ pour la recherche à facettes.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Le délai d'expiration de session absolue commence au moment de la création de session, tandis qu'un délai d'expiration inactif de session démarre au moment de la non-opération de l'utilisateur. Le délai d'expiration de session absolue convient aux scénarios où un contrôle strict du cycle de vie de la session est nécessaire, tels que les applications financières; Le délai d'attente de session inactif convient aux applications qui souhaitent que les utilisateurs maintiennent leur session active pendant longtemps, comme les médias sociaux.

La défaillance de la session du serveur peut être résolue en suivant les étapes: 1. Vérifiez la configuration du serveur pour vous assurer que la session est correctement définie. 2. Vérifiez les cookies des clients, confirmez que le navigateur le prend en charge et l'envoyez-le correctement. 3. Vérifiez les services de stockage de session, tels que Redis, pour vous assurer qu'ils fonctionnent normalement. 4. Examiner le code de demande pour assurer la logique de session correcte. Grâce à ces étapes, les problèmes de conversation peuvent être diagnostiqués et réparés efficacement et l'expérience utilisateur peut être améliorée.

Session_Start () IsCrucialInPhpFormanAgingUsersessions.1) ItinitiateSanEwSessionIfNoneExists, 2) ConsomaSanExistingSession, and3) SetSasessionCooKieforContinuityAcrossrequests, permettant aux applications liées à la réaction et à la personne.

La définition de l'indicateur httponly est cruciale pour les cookies de session car il peut effectivement empêcher les attaques XSS et protéger les informations de session utilisateur. Plus précisément, 1) l'indicateur httponly empêche JavaScript d'accéder aux cookies, 2) l'indicateur peut être réglé via Setcookies et Make_Response dans PHP et FLASK, 3) Bien qu'il ne puisse pas être empêché de toutes les attaques, elle devrait faire partie de la politique de sécurité globale.

PhpSessionsSsolvetheproblemOf-MainainingStateCrossMultiplehttprequestsByStoringDataontheserverAndassociatingitwithauniquesessionId.1) ils storentaserver, généralement infilesordatabases, et de lasse de lastoredinacookietatevevedata.2)

PhpSessionsCanstorestrings, Numbers, Arrays, Andobject.1.Strings: TextDatalikeUserames.2.Numbers: IntegersorFloatsForCounters.3.arrays: listslikeshoppingcarts.4.Objects: complexestructuresthataReSerialized.

TostartaphpSession, usessession_start () aTTheScript'sbeginning.1) PlaceItBeForeanyOutputToSetTheSessionCooKie.2) USESSIONSFORUSERDATALIKELOGINSTATUSORSHOPPINGSCARS.3) RegegeraSesessionIdStopreventfixationAtTACKS.4)

La régénération de session fait référence à la génération d'un nouvel ID de session et à l'invalidation de l'ancien ID lorsque l'utilisateur effectue des opérations sensibles en cas d'attaques fixes de session. Les étapes de mise en œuvre incluent: 1. Détectez les opérations sensibles, 2. Générer un nouvel ID de session, 3. Détruiser l'ancien ID de session, 4. Mettre à jour les informations de session côté utilisateur.


Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

Video Face Swap
Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Article chaud

Outils chauds

ZendStudio 13.5.1 Mac
Puissant environnement de développement intégré PHP

MinGW - GNU minimaliste pour Windows
Ce projet est en cours de migration vers osdn.net/projects/mingw, vous pouvez continuer à nous suivre là-bas. MinGW : un port Windows natif de GNU Compiler Collection (GCC), des bibliothèques d'importation et des fichiers d'en-tête librement distribuables pour la création d'applications Windows natives ; inclut des extensions du runtime MSVC pour prendre en charge la fonctionnalité C99. Tous les logiciels MinGW peuvent fonctionner sur les plates-formes Windows 64 bits.

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

Version crackée d'EditPlus en chinois
Petite taille, coloration syntaxique, ne prend pas en charge la fonction d'invite de code
