KNP Labs
“We offer Quality Development services for your Symfony project.” We only hire and train passionate developers: be sure that they will care about your code!
The KNP Labs agency was started in 2009 by developers for entrepreneurs, CTOs and communication agencies all over the world. Our goal is to help you make your Symfony2 project a success thanks to our experience with it − both in commercial and open-source projects.
Let’s dive into the State Pattern—a smart way to make your objects change behavior as their internal state shifts. By breaking states into separate classes, you can switch between them smoothly.
The State Pattern It's time to talk about the *State pattern*. Here's how I like to define it: *State* is a way to organize your code so that an object can change its *behavior* when its *internal state* changes
Time for a family reunion! Let's take a short detour and meet the Chain of Responsibility's cousin: the Middleware pattern. We’ll check out what makes it different, why you'd use it over CoR, and where it's used in !
The Chain of Responsibility's *Cousin* - the *Middleware* Pattern Did you know that the Chain of Responsibility pattern has a *cousin*? It's called the *Middleware* pattern. The two patterns are *very* similar, but the Middleware pattern has a subtle difference; This pattern *always* makes it to the end of the chain
🎉 Nouvelle série : KNPHACKATHON TOY PROJECT ! 🎉
Premier épisode de notre nouvelle série sur les Toy Projects de notre KNPHackathon.
🎲 JARNAC 🎲
Nos KNPeers, Alu et Nathan, ont décidé de passer leurs 3 jours du Hackathon n° 17 à créer un jeu de société sur la plateforme BGA (Board Game Arena). Cette plateforme propose un moteur permettant la création de jeux de société à jouer directement dans le navigateur, en solo ou en multijoueur. 🖥️👾
BGA inclut une structure permettant d'utiliser l'écosystème du site (matchmaking, scoring, gestion des états, chat) 💬, ce qui permet aux développeuses et développeurs de se concentrer sur l'implémentation technique des mécaniques et des règles du jeu. 🛠️
Dans notre cas, nous avons choisi d'implémenter Jarnac, un jeu de lettres semblable à Scrabble, où l'on joue avec ses propres lettres ainsi qu'avec celles de l'adversaire. Cette expérience nous a permis de revisiter certains concepts que nous n'utilisons pas tous les jours, comme la mise en place du pattern State Machine et l'utilisation du drag-and-drop natif en HTML. 🖱️💻
Stack : HTML/CSS, PHP, JS
Building a chain of responsibility? It’s the real world, so we’ll wire it up with Symfony’s DI! Also, to reduce code duplication (and show off) we’ll throw in the NullObject pattern.
Configuring CoR with Symfony This is a Symfony app, so let's take advantage of that and use the *autoconfigure* feature to set up our chain. There's even a super useful "Autoconfigure" attribute we can use in our handler classes
Pour les plus chanceux, c’est les vacances en ce moment ☀️
Chez KNP, on profite d’un repos bien mérité, mais on prépare déjà la rentrée !
On vous a concocté un éventail de formations sur nos technos préférées. 🤓
Découvrez dès maintenant nos formations sur des sujets variés comme React, Behat, BDD, infrastructure, Agile, Symfony (débutant et avancé), PHP, Docker, et bien plus encore.
Rendez-vous sur notre site pour en savoir plus : Formations par KNP - pratiques, agréables, basées sur l'expérience https://knplabs.com/fr/services/formations
On a hâte de vous retrouver ! ❤️💙
Now that we've built our XP bonus handlers using the chain of responsibility pattern, let's configure the chain and try it out!
Triggering Chain of Responsibility Open up "GameApplication". We're going to set up the chain inside its constructor, and we'll *start* by instantiating all of the handlers
When you have a sequence of steps where each step can determine whether to end or continue, you can use the chain of responsibility pattern. Let's use this to give players XP when certain conditions are met 🎮
Chain of Responsibility Time for design pattern number two - the *Chain of Responsibility* pattern. Sometimes, an *official* definition for a pattern doesn't exist
During our KNPHackathon, it’s a time for everyone to think together. Always with a touch of humor, we tackle serious topics like the management of our sanctuaries. Yes, with our offices in Nantes and Caen, Célia, our administrative magician and Office Manager, has to juggle both 🤹♀️.
In addition to this hackathon time, to keep our beautiful offices lively, we meet every two months for a retro where we discuss crucial questions: the mystery of multiplying mugs ☕, the fine art of tidying up (or artistic disorder) 🎨, and of course, the adventures of our cables that seem to have a life of their own 🔌.
We always have plenty of ideas to energize our spaces, like organizing a Hacktoberfest 🎉 or hosting events with AFUP, and of course, celebrating birthdays in style 🎂.
During this hackathon, it was also decided that Célia will now make a monthly trip to Caen to greet our local KNPeers 👋, ensure everything is in order (or disorder, depending on preferences) 🗂️, and add her personal touch to the decoration to make it feel like home 🏡.
These exchange moments are not just meant to be functional, they are mainly to foster dialogue between our Nantes and Caen offices. Because that is essential 🤝.
Symfony itself uses the Command Pattern, but not only in the place you’d expect! Let's find out where this hides and look at the pros and cons of this pattern.
Command Pattern in the Real World Now that we're pros at *applying* the Command pattern, can you guess where *Symfony* uses it? If you said "Symfony Console", you're right! And, we've been using it all along. Open up "GameCommand"
is a custom HTML element and it’s smart. Let’s use it and fragment_uri() to lazily load just part of our page!
Turbo Frames Look for & Load the Matching Frame On page load, Turbo *did* notice our new "" element and it *did* make an Ajax request to fetch the contents. But then, for some reason, it gave us this error
Let’s explore : a native way to make the experience of browsing your site even faster, with or without Turbo! ⚡️
Looking at the code of this "prefetch" script, there is *another* way this can be used. If you add a "data-prefetch-with-link="true"" attribute to a link, instead of making an Ajax call, it will add a "" element to the "head" tag of the page
3rd party-hosted JavaScript - like widgets and analytics - are getting smarter for the “no page reloads” reality. Still, sometimes this JS is written to *expect* full page reloads. Let’s learn about the problem and how we can make it behave properly with Turbo Drive
3rd Party JavaScript Widgets In a perfect world, all your JavaScript would be written in Stimulus and you would have *zero* "script" elements in your "body" tag. With that ideal setup, your JavaScript would always work - regardless of how or when new HTML was loaded - and it would only be parsed and executed...
In order to make the most of our time on-site during the KNPHackathon 🚀, we also dedicate discussions to fundamental topics concerning the organization of KNP, which is primarily based on autonomy and self-management by KNPeers.
We don't have a CTO, no salespeople, no HR manager, no communication officers. Our KNPeers organize themselves autonomously.
We have teams dedicated to various topics:
Skill development for our apprentices by the Mentoring Team 📈
Code quality by the Continuous Quality Team 🛠️
Internal and external communication by the Com Team 📣
Internal and external training by the Training Team 🎓
To support our KNPeers in their projects and their growth at KNP, we have implemented one-to-one conversations and follow-ups since 2015, initially managed by our People Manager. Over time, we have grown both in number and in maturity, and we have distributed the follow-ups among facilitators and our office manager.
Today, we realize that the needs have evolved again, and the maturity of the team allows us to change even more.
We have therefore revisited our follow-up practices to find new solutions adapted to our current needs. 💡
When a player loses a battle, it would be cool to try the last action again. The command pattern makes it easy to implement undo functionality, let's add this!
Undoing Action Commands There we were... in the middle of a *fierce* battle and... uh, what's that? We *lost*? *No way*! Our opponent got *super* lucky. Surely there's a way to undo that operation and try again, right? There *is* - with the *command pattern*
What’s the importance of the defer script attribute? We'll take a look! Plus a way to disable Turbo drive everywhere or just for some parts of your site… which can be a great trick while migrating!
The "defer" Attribute & Conditionally Activating Turbo Inspect element and go check out the "head" tag. Notice that all of our "script" elements live up here in the "head" with a "defer" attribute
Turbo Drive instantly removes full page refreshes with zero backend changes. Let’s look at how Turbo is activated & how it smartly merges the new for each page to make the magic happen
https://buff.ly/3fLKKVJ
Now that we’ve refactored our game to use the command pattern for actions, we are going to need…. more actions! Let’s get this mage archer battle going!
Implementing More Actions All right! We're ready to add more actions to our game and allow players to *choose* their actions. *First*, we need to create an *interface* for our commands
We need to make our game more interactive. Attack is currently the only action… lame! What about healing yourself? To add more actions, let's first refactor to utilize the command pattern
Adding Actions to the Game Our investors have asked for a new feature: "make the game more interactive". Those stakeholders are so funny... Ok so, instead of running battles automatically, they want the player to be able to choose which action to perform at the start of each turn
During our KNPHackathon 🚀, Joris presented an introduction to HDFS and MapReduce 📊. This paradigm, widely popularized and democratized by Google, enables scaling (petabyte files, thousands of nodes, billions of relationships, etc.).
The presentation covered the two main aspects of this stack:
Distributed storage via HDFS 📂:
HDFS (Hadoop Distributed File System) is a distributed file system designed to store very large amounts of data reliably and to allow fast access to these data. It divides the data into blocks, replicates them across multiple nodes to ensure fault tolerance and high availability.
Parallel processing with MapReduce 🔄:
MapReduce is a programming model that enables processing and generating large amounts of data in parallel on a cluster. It consists of two main stages: the Map phase, which breaks tasks into independent sub-tasks, and the Reduce phase, which aggregates the results of the sub-tasks to produce the final result. This model is particularly effective for massively parallel computations.
Time for a design pattern that I think is… just fun! The command pattern: a way to encapsulate some action into a standalone class… which you can then execute from anywhere! Bonus: this pattern can even give you “undo” abilities.
Command Pattern Ready for a new design patterns episode? Grab a cup of coffee and settle in, because we're taking a deep dive into the *command pattern*! We'll start with the basics - the definition and theory. *Later*, we'll have some fun by applying what we've learned to our game application
Design Patterns are back... with a vengeance! Let's continue building the "greatest command-line role-playing game ever" by applying 5 new patterns.
Introduction Hey friends! Welcome back to episode *two* of our Design Patterns series! In this episode, we'll continue our journey of building the *greatest* command-line RPG game *ever*! To do that, we'll apply not *one*, not *two*, but *five* new design patterns. We'll learn three new *behavioral* patterns: *....
During our KNPHackathon 🚀, our Design Team 🎨, with Soizic and Cédric, organized a Figma workshop 🖌️.
This workshop was based on a replica of a vacation apartment search app design 🏖️. It allowed our devs 👩💻, our office manager 👨💼, and our facilitator 🧑🎨 to:
🔧 Understand the utility of a UI kit,
🔧 Create components,
🔧 Play with their properties .
The Design Team also created a post generator 📸. This tool allows for quick creation of visuals for our social media by simply modifying attributes. And voila, we have our visual 🎉 (as seen in this post). It’s perfect for communication managers 📢 or teams who need to unify visuals without reinventing the wheel each time.
We offer design training for all levels and all professions 🏫. Whether you are a developer looking to integrate and use a UI Kit and Design System 🛠️, or a communication manager seeking to create templates and components to unify your campaigns 🗂️, we have training tailored to your needs!
The weather is beautiful ☀️, it's hot 🔥, and the days are long 🌞, so come and train with KNP!
In a joyful and friendly atmosphere 😃, take advantage of our practical-oriented training sessions 🎓, delivered by experienced developers 👩💻👨💻 working on our client projects.
PHP, Symfony, React, Behat… All these topics can be the subject of a training session! These sessions usually last a few days 📅 to thoroughly immerse yourself in the subject. We can also cater to more specific needs, so don't hesitate to contact us to discuss a custom session ✉️.
To see the dates: Training by KNP - practical, enjoyable, based on experience
https://knplabs.com/en/services/trainings
During our recent KNPHackathon 🚀, we worked on various Toy Projects 🎮, but that's not all. KNPeers also proposed discussion topics 🗣️, workshops ⚙️, and enriching conferences 🎓.
Our KNPeer Clément proposed a workshop on hexagonal architecture 🛑🔷. Many projects have already migrated to this architecture or are in the process of migrating 🔄. Clément took the time to explain the utility and benefits of this approach to new KNPeers:
🔹 Introduction to hexagonal architecture
🔹 Advantages and disadvantages
🔹 A practical workshop on redesigning a project 🧩
🔹 Discovery and application of different patterns used in this architecture 📐
Would you like to adopt hexagonal architecture for your project? We can support you and your team, either by directly collaborating on the migration or by training your team in this architecture! 🤝
Autoconfiguration is one of my favorite Symfony features: create a service, implement an interface (or use an #[Attribute]) and boom! Your service just got integrated into part of Symfony itself. Let's try this by creating a Twig extension.
Autoconfiguration This real-time ISS location feature is *cool*, but it would be *even cooler* if we could see this on *every* page, not just the homepage. How can we do that? We *could* pass the data in every action, *but* that's not ideal
Imagine sending this JSON to an API Platform app: { "name": "Ryan", "company": "/api/companies/5" } The string “Ryan” is set onto a name property. But the string “/api/companies/5"... becomes a Company object. Let’s chat about how that happens.
Writable Relation Fields Open up "DragonTreasureResourceTest" and check out "testPostToCreateTreasureWithLogin()". We've talked a lot about making our resources able to return relation fields
Environment variables let us set config (like db connection info) by machine (e.g. local vs prod). Setting "real" env vars can be tricky, so we use a .env file instead. Let's look at this and inject these important values into a service 🧐
Environment Variables Environment variables are for values that differ depending on the environment we're developing in, like locally vs production. The most common example of this is the database connection details
If you need a special action in your API - like “publishing” - you may not need a custom endpoint. In our DTO system, let’s run custom code when the isPublished state changes... via the tried-and-true PATCH operation!
Triggering a "Publish" We're down to just one test failure: it's in "testPublishTreasure". Let's check it out
Most services (the most commonly needed) are autowireable. But there are hundreds more that aren’t! Can we use those? Heck yea! And my favorite way is via a trick we already learned: the #[Autowire] attribute!
Non-Autowireable Services In the last chapter, we autowired a *non-autowireable* argument. *This time*, let's try to autowire an non-autowireable *service*
Time to perfect our DTO #[ApiResource]! In less than 10 minutes, we’ll smooth out validation AND security, including a custom Symfony voter and validator.
DTO & Security Our "DragonTreasureApi" is looking great! Back when this resource was an *entity*, we added *quite* a few cool customizations *and* included tests for those. Past "us" rocks
Cliquez ici pour réclamer votre Listage Commercial.
Vidéos (voir toutes)
Type
Site Web
Adresse
8q Rue Emile Péhant
Nantes
44000
60, Du Pontereau
Nantes
Community manager & créateur digital. Développer votre entreprise sur les réseaux sociaux.
Nantes, 44200
Bienvenu sur la page Facebook d'histofocus. Chaine de vulgarisation historique, quelque soit le sujet
Nantes, 44000
⚜️ KTM 500 EXC-F ⚜️ ⚜️² GASGAS 300 EC ⚜️ 🏴☠️ Powered by @grenzgaenger 🤘🏻 Crew @boarsgang
12 Route De Vannes
Nantes, 44100
🇨🇲 FRANCK BIYA OU RIEN PRÉSIDENT 2025
7bis Rue De La Tour D'Auvergne
Nantes, 44200
Jeannette est un collectif d'indépendants nantais, professionnels de la création audiovisuelle.