<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Larapulse Technology</title>
    <description>The latest articles on DEV Community by Larapulse Technology (@larapulse).</description>
    <link>https://dev.to/larapulse</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F1643%2F43140c43-a31c-4fd3-9da2-799301176486.jpg</url>
      <title>DEV Community: Larapulse Technology</title>
      <link>https://dev.to/larapulse</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/larapulse"/>
    <language>en</language>
    <item>
      <title>Understanding GraphQL: A Guide for Backend Developers</title>
      <dc:creator>Sergey Podgorny</dc:creator>
      <pubDate>Wed, 11 Oct 2023 09:56:00 +0000</pubDate>
      <link>https://dev.to/larapulse/understanding-graphql-a-guide-for-backend-developers-10b4</link>
      <guid>https://dev.to/larapulse/understanding-graphql-a-guide-for-backend-developers-10b4</guid>
      <description>&lt;p&gt;GraphQL is a powerful query language for APIs that provides a flexible and efficient way to request and manipulate data from a server. If you're a backend developer looking to learn about GraphQL, this guide will walk you through the basics, implementation, and its relevance to your work.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Is GraphQL?
&lt;/h3&gt;

&lt;p&gt;GraphQL was developed by Facebook and has gained popularity as an alternative to RESTful APIs. It provides the following key features:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Query Language:&lt;/strong&gt;&lt;br&gt;
GraphQL uses a schema to define the types of data available and the relationships between them. Clients can send queries to request exactly the data they need, and they receive a JSON response containing only that data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Single Endpoint:&lt;/strong&gt;&lt;br&gt;
GraphQL typically has a single endpoint for all data operations, simplifying the API surface and allowing clients to request various data in a single request.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Strongly Typed:&lt;/strong&gt;&lt;br&gt;
GraphQL APIs are strongly typed, meaning they have a defined schema with clear data types. Clients can introspect the schema to understand what data is available and how to query it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Real-time Data:&lt;/strong&gt;&lt;br&gt;
GraphQL can be used to request real-time data through subscriptions, allowing clients to receive updates when data changes.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Implementing GraphQL
&lt;/h3&gt;

&lt;p&gt;Here's a step-by-step guide to implementing GraphQL in your backend:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Define a Schema:&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Create a schema that describes the types of data your API will expose. You'll specify object types, queries, mutations (for write operations), and potentially subscriptions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;!):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Mutation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;updateUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;!,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserInput&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Set Up Resolvers:&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For each field in your schema, implement resolver functions. These resolver functions determine how to fetch the data for each field. These can be as simple as fetching data from a database or involve more complex operations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resolvers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;info&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Fetch user data based on 'args.userId'&lt;/span&gt;
      &lt;span class="c1"&gt;// Return the user data&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;Mutation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;updateUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;info&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Update user data based on 'args.userId' and 'args.input'&lt;/span&gt;
      &lt;span class="c1"&gt;// Return the updated user data&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;User&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Resolver for the "name" field&lt;/span&gt;
    &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Resolver for the "email" field&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Middleware:&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Set up middleware for handling tasks like authentication, authorization, and caching.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Server Implementation:&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Choose a GraphQL server library or framework that fits your tech stack. Popular options include Apollo Server, Express GraphQL, and GraphQL Yoga for JavaScript/Node.js.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Testing and Documentation:&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Write unit tests for your resolvers and document your GraphQL schema so that clients can understand how to use it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Integration with Frontend:&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Implement the GraphQL client on your frontend to send queries and mutations to the GraphQL server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resolvers in GraphQL
&lt;/h3&gt;

&lt;p&gt;Resolvers are central to GraphQL, as they determine how to fetch the data for specific fields. Each field in your schema typically has its resolver function. These resolver functions can optimize data fetching.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If multiple fields can be efficiently fetched in a single query from the same data source, you can use a single resolver to retrieve all the necessary data.&lt;/li&gt;
&lt;li&gt;GraphQL clients request multiple fields in a single query, and the resolver functions are invoked only for the fields requested in that query.&lt;/li&gt;
&lt;li&gt;Resolvers allow you to tailor the database query to fetch only the data that corresponds to the requested fields.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Do You Need GraphQL?
&lt;/h3&gt;

&lt;p&gt;The decision to implement GraphQL depends on your project's requirements. You might benefit from GraphQL if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your project involves complex data fetching, with data from multiple sources.&lt;/li&gt;
&lt;li&gt;You want to avoid versioning your API, as GraphQL allows clients to request only the data they need.&lt;/li&gt;
&lt;li&gt;Real-time data updates are necessary through subscriptions.&lt;/li&gt;
&lt;li&gt;Frontend and backend teams work in parallel, as GraphQL enables frontend developers to specify their data requirements.&lt;/li&gt;
&lt;li&gt;Mobile apps are part of your project, as GraphQL's ability to fetch only the necessary data is advantageous for mobile apps.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, if your project has simple data retrieval needs or is small in scope, you may not necessarily need to implement GraphQL.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;GraphQL is a powerful tool for backend developers to create flexible and efficient APIs. Its ability to allow clients to request exactly the data they need and its strong typing make it a valuable addition to your API toolkit. By understanding GraphQL's principles and implementing it effectively, you can improve data retrieval and enhance your development process.&lt;/p&gt;

&lt;p&gt;Start exploring GraphQL today, and you'll find it to be a valuable addition to your backend development toolkit.&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>api</category>
      <category>backend</category>
    </item>
    <item>
      <title>CPU Cache Basics</title>
      <dc:creator>Sergey Podgorny</dc:creator>
      <pubDate>Mon, 09 Oct 2023 09:21:00 +0000</pubDate>
      <link>https://dev.to/larapulse/cpu-cache-basics-57ej</link>
      <guid>https://dev.to/larapulse/cpu-cache-basics-57ej</guid>
      <description>&lt;p&gt;CPU caches are the unsung heroes of modern computing, silently speeding up your computer's performance. These small but incredibly fast memory storage areas play a vital role in ensuring that your CPU can access frequently used data and instructions with lightning speed. In this article, we'll explore the world of CPU caches, uncovering their design, optimization strategies, and their indispensable role in enhancing the performance of software and systems.&lt;/p&gt;

&lt;p&gt;Here's what you should know as a software engineer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;L1 Cache (Level 1 Cache):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;L1 cache is the smallest but fastest cache located closest to the CPU cores.&lt;/li&gt;
&lt;li&gt;It's divided into two parts: L1i (instruction cache) and L1d (data cache). L1i stores instructions, and L1d stores data.&lt;/li&gt;
&lt;li&gt;The purpose of L1 cache is to store the most frequently used instructions and data to speed up the CPU's operations.&lt;/li&gt;
&lt;li&gt;It has low latency (the time it takes to access data) and is usually separate for each CPU core.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;L2 Cache (Level 2 Cache):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;L2 cache is larger than L1 cache but slightly slower.&lt;/li&gt;
&lt;li&gt;It is shared among CPU cores in many multi-core processors.&lt;/li&gt;
&lt;li&gt;Its role is to store additional frequently used data and instructions that couldn't fit in L1 cache.&lt;/li&gt;
&lt;li&gt;L2 cache is still faster than accessing data from RAM (main memory).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;L3 Cache (Level 3 Cache, if available):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;L3 cache is even larger but slightly slower than L2 cache.&lt;/li&gt;
&lt;li&gt;It is shared across all CPU cores in a multi-core processor.&lt;/li&gt;
&lt;li&gt;L3 cache acts as a backup storage for frequently used data and instructions that couldn't fit in L1 or L2 cache.&lt;/li&gt;
&lt;li&gt;Having an L3 cache can help reduce bottlenecks when multiple CPU cores are accessing memory simultaneously.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How it works:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;When the CPU needs data or instructions, it first checks if they are in the L1 cache.&lt;/li&gt;
&lt;li&gt;If the needed information is in the L1 cache (or L2 cache if not found in L1), it's called a cache hit, and the CPU can quickly retrieve it.&lt;/li&gt;
&lt;li&gt;If the data is not in the cache, it's called a cache miss. In this case, the CPU has to fetch the data from slower main memory (RAM), which takes more time.&lt;/li&gt;
&lt;li&gt;The goal of the cache hierarchy is to reduce the number of cache misses by storing the most frequently used data and instructions in the faster, smaller caches.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When it is used:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;L1, L2, and L3 caches are used constantly as the CPU executes programs.&lt;/li&gt;
&lt;li&gt;They are especially beneficial for speeding up frequently executed code and data access patterns.&lt;/li&gt;
&lt;li&gt;The cache hardware manages what gets stored in the cache, so as a software engineer, you generally don't interact with it directly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd14ya22r75jwo7mvn25h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd14ya22r75jwo7mvn25h.png" alt="CPU cache schema" width="463" height="544"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Optimization principles
&lt;/h3&gt;

&lt;p&gt;Caches like L1, L2, and L3 are &lt;em&gt;&lt;strong&gt;managed by the hardware&lt;/strong&gt;&lt;/em&gt;, and as a software engineer, &lt;em&gt;you don't have direct control over which programs or data are stored in them&lt;/em&gt;. However, you can follow certain programming and optimization principles to increase the likelihood that your program benefits from cache usage. Here's how:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Locality of Reference:&lt;/strong&gt; Caches work best when your program exhibits good locality of reference. There are two types of locality:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Temporal Locality:&lt;/strong&gt; This means that if you access a piece of data once, you're likely to access it again in the near future. To leverage temporal locality, try to reuse data that you've recently accessed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spatial Locality:&lt;/strong&gt; This refers to the tendency to access data located near recently accessed data. To benefit from spatial locality, try to access data in a sequential or predictable pattern.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cache-Friendly Data Structures:&lt;/strong&gt; Use data structures and algorithms that are cache-friendly. For example, when iterating over an array, processing elements that are stored close to each other in memory is more cache-efficient than jumping around in memory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cache Line Awareness:&lt;/strong&gt; Cache systems typically work with fixed-size cache lines (e.g., 64 bytes). Be aware of this when designing your data structures. If you only need a small portion of a cache line, avoid loading the entire line to reduce cache pollution.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Compiler and Compiler Flags:&lt;/strong&gt; Compilers can optimize code to improve cache locality. Use compiler flags (e.g., &lt;strong&gt;-O2&lt;/strong&gt; or &lt;strong&gt;-O3&lt;/strong&gt; in GCC) to enable optimizations. Additionally, understand how your compiler optimizes code for your target architecture.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Profiling and Benchmarking:&lt;/strong&gt; Use profiling tools to analyze cache behavior in your program. Tools like perf (on Linux) or performance analyzers in integrated development environments (IDEs) can help you identify cache-related issues.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Thread Affinity:&lt;/strong&gt; If you're working with multi-threaded programs, consider using thread affinity techniques to bind threads to specific CPU cores. This can help minimize cache contention between threads.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Cache sizes
&lt;/h3&gt;

&lt;p&gt;Regarding the sizes of cache levels, they can vary widely depending on the CPU architecture. However, here's a rough estimate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;L1 Cache: Typically ranges from 16KB to 128KB per core.&lt;/li&gt;
&lt;li&gt;L2 Cache: Can range from 256KB to 1MB per core or be shared among multiple cores.&lt;/li&gt;
&lt;li&gt;L3 Cache: Usually shared among multiple cores and can range from 2MB to 32MB or more in high-end processors.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keep in mind that these numbers can change with different CPU models and generations. You can usually find the specific cache sizes for your CPU in its documentation or by checking the manufacturer's website. Understanding cache sizes can help you make informed decisions when optimizing your code for specific hardware.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cache latencies
&lt;/h3&gt;

&lt;p&gt;Let's compare the latencies of different memory levels, including CPU caches and RAM (main memory):&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;L1 Cache Latency:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;L1 cache is the fastest and has the lowest latency among all memory levels.&lt;/li&gt;
&lt;li&gt;Typical latency ranges from 1 to 3 cycles, which is extremely fast.&lt;/li&gt;
&lt;li&gt;Accessing data from L1 cache is significantly faster than any other memory level.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;L2 Cache Latency:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;L2 cache has slightly higher latency compared to L1 cache.&lt;/li&gt;
&lt;li&gt;Typical latency ranges from 4 to 10 cycles, depending on the CPU architecture.&lt;/li&gt;
&lt;li&gt;It is still much faster than accessing RAM.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;L3 Cache Latency:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;L3 cache has higher latency compared to L2 and L1 caches.&lt;/li&gt;
&lt;li&gt;Typical latency ranges from 10 to 40 cycles, depending on the CPU and cache design.&lt;/li&gt;
&lt;li&gt;While slower than L1 and L2, it is still much faster than RAM.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;RAM (Main Memory) Latency:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accessing data from RAM is significantly slower than accessing any level of cache.&lt;/li&gt;
&lt;li&gt;RAM latency can vary widely, but it typically ranges from 60 to 100 cycles or more.&lt;/li&gt;
&lt;li&gt;RAM access times are several orders of magnitude slower than L1 cache.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Assuming a CPU clock speed of 3 GHz (3 billion cycles per second):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;L1 cache access time:

&lt;ul&gt;
&lt;li&gt;Fastest case (1 cycle): 1 / 3 * 10^9 = 0.33 nanoseconds&lt;/li&gt;
&lt;li&gt;Slowest case (3 cycles): 3 / 3 * 10^9 = 1 nanosecond&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;L2 cache access time:

&lt;ul&gt;
&lt;li&gt;Fastest case (4 cycles): 4 / 3 * 10^9 = 1.33 nanoseconds&lt;/li&gt;
&lt;li&gt;Slowest case (10 cycles): 10 / 3 * 10^9 = 3.33 nanoseconds&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;L3 cache access time:

&lt;ul&gt;
&lt;li&gt;Fastest case (10 cycles): 10 / 3 * 10^9 = 3.33 nanoseconds&lt;/li&gt;
&lt;li&gt;Slowest case (40 cycles): 40 / 3 * 10^9 = 13.33 nanoseconds&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;RAM access time:

&lt;ul&gt;
&lt;li&gt;Fastest case (60 cycles): 60 / 3 * 10^9 = 20 nanoseconds&lt;/li&gt;
&lt;li&gt;Slowest case (100 cycles): 100 / 3 * 10^9 = 33.33 nanoseconds&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd25ip368jj9z5tcp566t.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd25ip368jj9z5tcp566t.jpeg" alt="Latency numbers you should know - from bytebytego" width="800" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To put these numbers into perspective, accessing data from L1 cache can be over 10 times faster than accessing the same data from L2 cache, and it can be more than 100 times faster than accessing it from RAM.&lt;/p&gt;

&lt;p&gt;Efficient use of CPU caches is crucial for optimizing software performance because minimizing cache misses and utilizing cache-friendly algorithms can help reduce the impact of slower RAM access times. This is why understanding cache behavior and optimizing for cache locality is a key consideration in high-performance computing and software development.&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;The importance of CPU caches in modern computing cannot be overstated. These small, high-speed memory storage areas play a pivotal role in enhancing software performance by reducing the latency of data access. Cache-aware programming, which involves optimizing code and data structures to maximize cache utilization, has a profound impact on software performance.&lt;/p&gt;

&lt;p&gt;In summary, caches like L1, L2, and L3 are crucial for optimizing CPU performance by reducing memory access times. As a software engineer, understanding the basics of how caches work can help you write more efficient code, such as optimizing data access patterns and minimizing cache thrashing (when cache contents change frequently). However, the specifics of cache management are typically handled by the hardware and the operating system.&lt;/p&gt;

</description>
      <category>cpu</category>
      <category>cache</category>
      <category>ram</category>
    </item>
    <item>
      <title>Dealing with RabbitMQ exchange types</title>
      <dc:creator>Sergey Podgorny</dc:creator>
      <pubDate>Tue, 20 Apr 2021 14:53:05 +0000</pubDate>
      <link>https://dev.to/larapulse/dealing-with-rabbitmq-exchange-types-44ck</link>
      <guid>https://dev.to/larapulse/dealing-with-rabbitmq-exchange-types-44ck</guid>
      <description>&lt;p&gt;Exchanges control the routing of messages to queues.  Each exchange type defines a specific routing algorithm which the server uses to determine which bound queues a published message should be routed to.&lt;/p&gt;

&lt;p&gt;RabbitMQ provides four types of exchanges: &lt;em&gt;Direct&lt;/em&gt;, &lt;em&gt;Fanout&lt;/em&gt;, &lt;em&gt;Topic&lt;/em&gt;, and &lt;em&gt;Headers&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fanout Exchanges
&lt;/h3&gt;

&lt;p&gt;The Fanout exchange type routes messages to all bound queues indiscriminately.  If a routing key is provided, it will simply be ignored.  The following illustrates how the fanout exchange type works:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8xfbjebhhvdo1q3jaygq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8xfbjebhhvdo1q3jaygq.png" alt="Fanout Exchange" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Fanout exchange type is useful for facilitating the &lt;a href="http://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern" rel="noopener noreferrer"&gt;publish-subscribe pattern&lt;/a&gt;. When using the fanout exchange type, different queues can be declared to handle messages in different ways.  For instance, a message indicating a customer order has been placed might be received by one queue whose consumers fulfil the order, another whose consumers update a read-only history of orders, and yet another whose consumers record the order for reporting purposes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Direct Exchanges
&lt;/h3&gt;

&lt;p&gt;The Direct exchange type routes messages with a routing key equal to the routing key declared by the binding queue.  The following illustrates how the direct exchange type works:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnoathf8v0slv1309zss1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnoathf8v0slv1309zss1.png" alt="Direct Exchange" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Direct exchange type is useful when you would like to distinguish messages published to the same exchange using a simple string identifier.  This is the type of exchange that was used in our Hello World example.  As discussed in part 3 of our series, every queue is automatically bound to a default exchange using a routing key equal to the queue name.  This default exchange is declared as a Direct exchange.  In our example, the queue named "hello-world-queue" was bound to the default exchange with a routing key of "hello-world-queue", so publishing a message to the default exchange (identified with an empty string) routed the message to the queue named "hello-world-queue".&lt;/p&gt;

&lt;h3&gt;
  
  
  Topic Exchanges
&lt;/h3&gt;

&lt;p&gt;The Topic exchange type routes messages to queues whose routing key matches all, or a portion of a routing key. With topic exchanges, messages are published with routing keys containing a series of words separated by a dot (e.g. "&lt;code&gt;word1.word2.word3&lt;/code&gt;").  Queues binding to a topic exchange supply a matching pattern for the server to use when routing the message.  Patterns may contain an asterisk ("&lt;code&gt;*&lt;/code&gt;") to match a word in a specific position of the routing key, or a hash ("&lt;code&gt;#&lt;/code&gt;") to match zero or more words.  For example, a message published with a routing key of "&lt;code&gt;honda.civic.navy&lt;/code&gt;" would match queues bound with "&lt;code&gt;honda.civic.navy&lt;/code&gt;", "&lt;code&gt;*.civic.*&lt;/code&gt;", "&lt;code&gt;honda.#&lt;/code&gt;", or "&lt;code&gt;#&lt;/code&gt;", but would not match "&lt;code&gt;honda.accord.navy&lt;/code&gt;", "&lt;code&gt;honda.accord.silver&lt;/code&gt;", "&lt;code&gt;*.accord.*&lt;/code&gt;", or "&lt;code&gt;ford.#&lt;/code&gt;".  The following illustrates how the fanout exchange type works:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh9u0kz7ms0p49jatp0ea.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh9u0kz7ms0p49jatp0ea.png" alt="Topic Exchange" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The topic exchange type is useful for directing messages based on multiple categories (e.g. product type and shipping preference), or for routing messages originating from multiple sources (e.g. logs containing an application name and severity level).&lt;/p&gt;

&lt;h3&gt;
  
  
  Headers Exchanges
&lt;/h3&gt;

&lt;p&gt;The Headers exchange type routes messages based upon a matching of message headers to the expected headers specified by the binding queue.  The headers exchange type is similar to the topic exchange type in that more than one criteria can be specified as a filter, but the headers exchange differs in that its criteria is expressed in the message headers as opposed to the routing key, may occur in any order, and may be specified as matching any or all of the specified headers.  The following illustrates how the headers exchange type works:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzvr327v08wkwtlc26wz2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzvr327v08wkwtlc26wz2.png" alt="Headers Exchange" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Headers exchange type is useful for directing messages which may contain a subset of known criteria where the order is not established and provides a more convenient way of matching based upon the use of complex types as the matching criteria (i.e. a serialized object).&lt;/p&gt;




&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;That wraps up our introduction to each of the exchange types.  Next time, we’ll walk through an example which demonstrates declaring a direct exchange explicitly and take a look at the push API.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Interesting in reading more about digital literacy? Follow &lt;a href="https://blog.larapulse.com/digital-literacy" rel="noopener noreferrer"&gt;this link&lt;/a&gt; to find more articles 😉&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>rabbitmq</category>
      <category>exchange</category>
      <category>messaging</category>
      <category>event</category>
    </item>
    <item>
      <title>Event-driven architecture over standard client-server aproach</title>
      <dc:creator>Sergey Podgorny</dc:creator>
      <pubDate>Fri, 16 Apr 2021 14:32:08 +0000</pubDate>
      <link>https://dev.to/larapulse/event-driven-architecture-over-standard-client-server-aproach-3naf</link>
      <guid>https://dev.to/larapulse/event-driven-architecture-over-standard-client-server-aproach-3naf</guid>
      <description>&lt;p&gt;Just 20 years ago, most of the business was offline and web development was just starting to gain traction. But gradually everything develops, the whole business is trying to go online. And along with it, web development is actively developing, there are more and more services. Web development is an integral part of any modern business.&lt;/p&gt;

&lt;p&gt;To keep our business running fast, we need to consider all the third-party services on which our business depends. First, let's take a look at the standard architecture we're used to.&lt;/p&gt;

&lt;h3&gt;
  
  
  Standard Client-Server architecture
&lt;/h3&gt;

&lt;p&gt;With a standard synchronous architecture, most changes have a large number of dependencies, sometimes on slow and unpredictable systems. This slows down interactions and increases the error rate. Maintainability is troublesome, as there is usually a high amount of possible side effects to consider.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp5yvl9ip76vmuhm2nyar.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp5yvl9ip76vmuhm2nyar.png" alt="Synchronous client-server architecture" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  👍 Advantages:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Simple to understand&lt;/li&gt;
&lt;li&gt;Easier to debug and test&lt;/li&gt;
&lt;li&gt;Better data consistency&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  👎 Disadvantages:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;High rate of client-visible errors&lt;/li&gt;
&lt;li&gt;Slow&lt;/li&gt;
&lt;li&gt;One thing fails, everything fails - does not work well for complex business processes&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Event-Driven architecture
&lt;/h3&gt;

&lt;p&gt;In an event-driven architecture, when a service performs some piece of work that other services might be interested in, that service produces an &lt;em&gt;event&lt;/em&gt; — a record of the completed action. Other services consume those events so that they can perform any of their tasks needed as a result of the event.&lt;/p&gt;

&lt;p&gt;By decoupling the core change from the side effects performance is greatly increased and error rates go down. &lt;/p&gt;

&lt;p&gt;Secondary concerns can be handled independently, this allows easier maintenance, and even involving different teams and/or technologies that are best suited for the respective tasks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6zpskswejolmj3wecw0y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6zpskswejolmj3wecw0y.png" alt="Event-driven architecture" width="800" height="575"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h4&gt;
  
  
  👍 Advantages:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Responsive&lt;/li&gt;
&lt;li&gt;Resilient &lt;/li&gt;
&lt;li&gt;Scales as a whole as well as only where needed &lt;/li&gt;
&lt;li&gt;Development can be distributed between multiple teams&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  👎 Disadvantages:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Extra work needed to keep data consistency&lt;/li&gt;
&lt;li&gt;Higher learning curve&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;Event-driven architecture has been gaining momentum in popularity lately, and there are reasons for this: services grow and develop, become larger and acquire new dependencies. Decoupling of responsibility can be a solution in this case and improve performance, but you shouldn't abuse the architecture without a detailed understanding of all its pros and cons. For small and simple projects, a standard synchronous architecture may be a much better solution.&lt;/p&gt;

&lt;p&gt;To read more, follow these links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bryanavery.co.uk/what-is-event-driven-microservice-architecture/" rel="noopener noreferrer"&gt;What is Event-Driven microservice architecture?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.infoq.com/articles/realtime-event-driven-ecosystem/" rel="noopener noreferrer"&gt;The Challenges of Building a Reliable Real-Time Event-Driven Ecosystem&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Interesting in reading more about APIs? Follow &lt;a href="https://blog.larapulse.com/api" rel="noopener noreferrer"&gt;this link&lt;/a&gt; to find more articles 😉&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>request</category>
      <category>architecture</category>
      <category>events</category>
      <category>server</category>
    </item>
    <item>
      <title>Go migrator for MySQL databases</title>
      <dc:creator>Sergey Podgorny</dc:creator>
      <pubDate>Wed, 02 Sep 2020 18:01:16 +0000</pubDate>
      <link>https://dev.to/larapulse/go-migrator-for-mysql-databases-2gom</link>
      <guid>https://dev.to/larapulse/go-migrator-for-mysql-databases-2gom</guid>
      <description>&lt;h2&gt;
  
  
  Intention
&lt;/h2&gt;

&lt;p&gt;A few months ago I started working on one of my pet projects powered by Go using MySQL as persistent data storage. After some research to find the best solution to migrate my database schema, the most popular decisions suggested for me were auto-migrator by GORM and &lt;code&gt;golang-migrate&lt;/code&gt; utility. Unfortunately, they did not meet my expectations.&lt;/p&gt;

&lt;p&gt;Let me explain why...&lt;/p&gt;

&lt;p&gt;First of all, I did not want to stick to the one specific ORM and moreover, I didn't want to use ORM in my project at all. I do not want to debate whether GORM is good or not, it was just that in my case it was much more convenient and easier to use the standard library &lt;code&gt;database/sql&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I also wanted to have a long-term solution that would allow me to programmatically write code to the database without delving into sql queries. Therefore, the solution using pure sql did not suit me either.&lt;/p&gt;

&lt;h2&gt;
  
  
  Progress
&lt;/h2&gt;

&lt;p&gt;Since none of the solutions I found worked for me, I decided to write a code that would fully meet my requirements and expectations.&lt;/p&gt;

&lt;p&gt;At first, the solution I wrote was integrated into my migration files, but I immediately noticed that the code that is used to make changes to the database can be split into a separate package. This package was still an integral part of my project, but nevertheless began to grow into something more. &lt;/p&gt;

&lt;p&gt;After a few weeks of using my package, I decided that it proved to be quite stable and can be published in the public domain for general use. So it became part of the open-source community and my first public Go project on GitHub 💪&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/larapulse" rel="noopener noreferrer"&gt;
        larapulse
      &lt;/a&gt; / &lt;a href="https://github.com/larapulse/migrator" rel="noopener noreferrer"&gt;
        migrator
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      MySQL database migrator
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;MySQL database migrator&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/larapulse/migrator/blob/master/logo.png"&gt;&lt;img width="159px" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Flarapulse%2Fmigrator%2Fraw%2Fmaster%2Flogo.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://travis-ci.org/larapulse/migrator" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1142bf8fc79db921e728ef8f5f2694c025953c28058f555b8e1eb5d6e3e4fce7/68747470733a2f2f7472617669732d63692e6f72672f6c61726170756c73652f6d69677261746f722e737667" alt="Build Status"&gt;&lt;/a&gt;
&lt;a href="https://github.com/larapulse/migrator/LICENSE.md" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/2c688e7decdaf0ee046dbefbf1bfeff0500b962e151b1a606d791f8f2e9f54c6/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e737667" alt="Software License"&gt;&lt;/a&gt;
&lt;a href="https://codecov.io/gh/larapulse/migrator" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1f0572765e196a099b153905027c4072fc71b93ec069af5101301773658c88e0/68747470733a2f2f636f6465636f762e696f2f67682f6c61726170756c73652f6d69677261746f722f6272616e63682f6d61737465722f67726170682f62616467652e737667" alt="codecov"&gt;&lt;/a&gt;
&lt;a href="https://goreportcard.com/report/github.com/larapulse/migrator" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/8d102d8a1aa2c0dadb33cba1ba48d43b041723ceddd4795803312b49ee91dae8/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f6c61726170756c73652f6d69677261746f72" alt="Go Report Card"&gt;&lt;/a&gt;
&lt;a href="https://pkg.go.dev/github.com/larapulse/migrator?tab=doc" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/bf922b68ee5b784df17b4152a54362f777055192121f287e82b3a208ae91332e/68747470733a2f2f676f646f632e6f72672f6769746875622e636f6d2f6c61726170756c73652f6d69677261746f723f7374617475732e737667" alt="GoDoc"&gt;&lt;/a&gt;
&lt;a href="https://github.com/avelino/awesome-go" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d8b2bde4796b67266f07c7a619f554c926ca4750d5d8861b4b740baaddc3fd1e/68747470733a2f2f617765736f6d652e72652f6d656e74696f6e65642d62616467652e737667" alt="Mentioned in Awesome Go"&gt;&lt;/a&gt;
&lt;a href="https://github.com/larapulse/migrator/releases" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/94464745509a20fdd1fde836e14c47747b81d7a22c5cdbf0b9b732a7c9ca90d9/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f72656c656173652f6c61726170756c73652f6d69677261746f722e737667" alt="Release"&gt;&lt;/a&gt;
&lt;a href="https://www.tickgit.com/browse?repo=github.com/larapulse/migrator" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/7e3d74ac8a60c26434ca27dda6b3daaef54cc73a7635255cf15f20cbe1860878/68747470733a2f2f62616467656e2e6e65742f68747470732f6170692e7469636b6769742e636f6d2f62616467656e2f6769746875622e636f6d2f6c61726170756c73652f6d69677261746f72" alt="TODOs"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;MySQL database migrator designed to run migrations to your features and manage database schema update with intuitive go code. It is compatible with the latest MySQL v8.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Installation&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;To install &lt;code&gt;migrator&lt;/code&gt; package, you need to install Go and set your Go workspace first.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The first need &lt;a href="https://golang.org/" rel="nofollow noopener noreferrer"&gt;Go&lt;/a&gt; installed (&lt;strong&gt;version 1.13+ is required&lt;/strong&gt;), then you can use the below Go command to install &lt;code&gt;migrator&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;$ go get -u github.com/larapulse/migrator&lt;/pre&gt;

&lt;/div&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Import it in your code:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight highlight-source-go notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-s"&gt;"github.com/larapulse/migrator"&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Quick start&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Initialize migrator with migration entries:&lt;/p&gt;
&lt;div class="highlight highlight-source-go notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;var&lt;/span&gt; &lt;span class="pl-s1"&gt;migrations&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; []migrator.&lt;span class="pl-smi"&gt;Migration&lt;/span&gt;{
    {
        &lt;span class="pl-s1"&gt;Name&lt;/span&gt;: &lt;span class="pl-s"&gt;"19700101_0001_create_posts_table"&lt;/span&gt;
        &lt;span class="pl-s1"&gt;Up&lt;/span&gt;: &lt;span class="pl-k"&gt;func&lt;/span&gt;() migrator.&lt;span class="pl-smi"&gt;Schema&lt;/span&gt; {
            &lt;span class="pl-k"&gt;var&lt;/span&gt; &lt;span class="pl-s1"&gt;s&lt;/span&gt; migrator.&lt;span class="pl-smi"&gt;Schema&lt;/span&gt;
            &lt;span class="pl-s1"&gt;posts&lt;/span&gt; &lt;span class="pl-c1"&gt;:=&lt;/span&gt; migrator.&lt;span class="pl-smi"&gt;Table&lt;/span&gt;{&lt;span class="pl-s1"&gt;Name&lt;/span&gt;: &lt;span class="pl-s"&gt;"posts"&lt;/span&gt;}

            &lt;span class="pl-s1"&gt;posts&lt;/span&gt;.&lt;span class="pl-c1"&gt;UniqueID&lt;/span&gt;(&lt;span class="pl-s"&gt;"id"&lt;/span&gt;)
            &lt;span class="pl-s1"&gt;posts&lt;/span&gt;.&lt;span class="pl-c1"&gt;Varchar&lt;/span&gt;(&lt;span class="pl-s"&gt;"title"&lt;/span&gt;, &lt;span class="pl-c1"&gt;64&lt;/span&gt;)
            &lt;span class="pl-s1"&gt;posts&lt;/span&gt;.&lt;span class="pl-c1"&gt;Text&lt;/span&gt;(&lt;span class="pl-s"&gt;"content"&lt;/span&gt;, &lt;span class="pl-c1"&gt;false&lt;/span&gt;)
            &lt;span class="pl-s1"&gt;posts&lt;/span&gt;.&lt;span class="pl-c1"&gt;Timestamps&lt;/span&gt;()

            &lt;span class="pl-s1"&gt;s&lt;/span&gt;.&lt;span class="pl-c1"&gt;CreateTable&lt;/span&gt;(&lt;span class="pl-s1"&gt;posts&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/larapulse/migrator" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Since this was my first project to Go open-source packages, I didn't know a few things.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;How to publish my package to &lt;a href="https://pkg.go.dev/" rel="noopener noreferrer"&gt;pkg.go.dev&lt;/a&gt;?&lt;/em&gt;  The solution turned out to be quite simple and unusual. There is no need to upload your package anywhere, you just need to request it either with the &lt;a href="https://go.dev/about#adding-a-package" rel="noopener noreferrer"&gt;help of searching for packages, or using the command line&lt;/a&gt;. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;How to write good documentation for your package?&lt;/em&gt; The package manager independently reads the comments in front of functions and variables, and then generates documentation for your package. So be careful what and how you write in the comment before the function. Try to describe in as much detail as possible what exactly is happening and for what exactly and how this or that part of your package is used. Unfortunately, there are currently no mechanisms for editing public documentation, so you cannot change the display order or formatting to your liking. Documentation is a visual display of your comments in front of exported functions and variables. 🤷‍♂️&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;go.mod&lt;/code&gt; file really matters. While the unexported package can be called whatever you like (fe. &lt;code&gt;module migrator&lt;/code&gt;), published module should be named the same as the place where it is actually located (fe. &lt;code&gt;module github.com/larapulse/migrator&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Migrate&lt;/code&gt;, &lt;code&gt;Rollback&lt;/code&gt; and &lt;code&gt;Revert&lt;/code&gt; your migration:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Migrator&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Pool&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;migrations&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;migrated&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Migrate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Could not migrate: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;migrated&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Nothing were migrated."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;migrated&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Migration: %s was migrated ✅"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Migration did run successfully"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While &lt;code&gt;Migrate&lt;/code&gt; runs all unexecuted migrations from the pool, you can also &lt;code&gt;Rollback&lt;/code&gt; last executed migration batch, or &lt;code&gt;Rollback&lt;/code&gt; whole migration list.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It creates &lt;code&gt;migrations&lt;/code&gt; table and tracks there all executed migrations. You can set any name you like if you want.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Migrator&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;TableName&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"_my_app_migrations"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Defining migrations with schema commands. You can create, drop or alter tables:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;migration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Migration&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"19700101_0001_create_posts_table"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Up&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Schema&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Schema&lt;/span&gt;
        &lt;span class="n"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Table&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"posts"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UniqueID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timestamps&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateTable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;Down&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Schema&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Schema&lt;/span&gt;

        &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DropTableIfExists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"posts"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Using transactional migrations. In case you have multiple commands within one migration and you want to be sure it is migrated properly, you might enable transactional execution per migration:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;migration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Migration&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"19700101_0003_rename_foreign_key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Up&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Schema&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Schema&lt;/span&gt;

        &lt;span class="n"&gt;keyName&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BuildForeignNameOnTable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"comments"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"post_id"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;newKeyName&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BuildForeignNameOnTable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"comments"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"article_id"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AlterTable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"comments"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TableCommands&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DropForeignCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keyName&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DropIndexCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keyName&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenameColumnCommand&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"post_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"article_id"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddIndexCommand&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;newKeyName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"article_id"&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
            &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddForeignCommand&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Foreign&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;       &lt;span class="n"&gt;newKeyName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="s"&gt;"article_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Reference&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;On&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;        &lt;span class="s"&gt;"posts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;}},&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;Down&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Schema&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Schema&lt;/span&gt;

        &lt;span class="n"&gt;keyName&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BuildForeignNameOnTable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"comments"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"article_id"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;newKeyName&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BuildForeignNameOnTable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"comments"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"post_id"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AlterTable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"comments"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TableCommands&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DropForeignCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keyName&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DropIndexCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keyName&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenameColumnCommand&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"article_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"post_id"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddIndexCommand&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;newKeyName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"post_id"&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
            &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddForeignCommand&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Foreign&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;       &lt;span class="n"&gt;newKeyName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="s"&gt;"post_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Reference&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;On&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;        &lt;span class="s"&gt;"posts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;}},&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;Transaction&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Custom queries on schema and tables.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You may add any column definition to the database on your own, just be sure you implement &lt;code&gt;migrator.columnType&lt;/code&gt; interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;customType&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ct&lt;/span&gt; &lt;span class="n"&gt;customType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;buildRow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Table&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"posts"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UniqueID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;customType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"json not null"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timestamps&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same logic is for adding custom commands to the schema to be migrated or reverted, just be sure you implement &lt;code&gt;command&lt;/code&gt; interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;customCommand&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cc&lt;/span&gt; &lt;span class="n"&gt;customCommand&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;toSQL&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;migrator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Schema&lt;/span&gt;

&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;customCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DROP PROCEDURE abc"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CustomCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Pending features
&lt;/h2&gt;

&lt;p&gt;At the time of this writing, the latest stable version is &lt;code&gt;v1.2.0&lt;/code&gt;. As the next steps, it is planned to add more commands for interacting with the schema.&lt;/p&gt;

&lt;p&gt;If necessary, in the next major versions drivers can be added for Postgres, SQLite, Microsoft SQL Server etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Result
&lt;/h2&gt;

&lt;p&gt;At the moment, this package is a part of the go open source community and is versatile enough to be used in various projects. I really hope that it will also be useful to you when working with the database schema.&lt;/p&gt;

&lt;p&gt;It is not popular yet, but I am really proud of it and believe it may grow fast with your support and contributions! &lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1277288650959736832-585" src="https://platform.twitter.com/embed/Tweet.html?id=1277288650959736832"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1277288650959736832-585');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1277288650959736832&amp;amp;theme=dark"
  }



&lt;/p&gt;

</description>
      <category>go</category>
      <category>mysql</category>
      <category>migrator</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How DNS servers work</title>
      <dc:creator>Sergey Podgorny</dc:creator>
      <pubDate>Tue, 04 Feb 2020 11:15:52 +0000</pubDate>
      <link>https://dev.to/larapulse/how-dns-servers-work-2b84</link>
      <guid>https://dev.to/larapulse/how-dns-servers-work-2b84</guid>
      <description>&lt;h2&gt;
  
  
  What is DNS
&lt;/h2&gt;

&lt;p&gt;DNS is a global system for translating human-readable domain names to IP addresses. When a user tries to access a web address like "example.com", their web browser or application performs a &lt;strong&gt;DNS Query&lt;/strong&gt; against a DNS server, supplying the hostname. The DNS server takes the hostname and resolves it into a numeric IP address, which the web browser can connect to.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2w113ewxandfewhmeoj9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2w113ewxandfewhmeoj9.png" alt="DNS request flow" width="650" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A component called a &lt;strong&gt;DNS Resolver&lt;/strong&gt; is responsible for checking if the hostname is available in the local cache, and if not, contacts a series of DNS Name Servers, until eventually it receives the IP of the service the user is trying to reach and returns it to the browser or application. This usually takes less than a second.&lt;/p&gt;




&lt;h2&gt;
  
  
  Domain Registrars
&lt;/h2&gt;

&lt;p&gt;Before anything else, it is important to know that your domain registrar is where the entire process begins. Your domain registrar is normally the place where you purchased/obtained your domain. Your registrar could be a business that only does domain registration or even your web host itself.&lt;/p&gt;

&lt;p&gt;The registrar is the first piece of our puzzle because whenever a request for a domain is made, the registrar is the first place that gets referenced for information. As it pertains to loading a website, the most important part of the response is what set of "nameservers" the domain is pointed at.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhq3gnoo232kcxkqtfw5t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhq3gnoo232kcxkqtfw5t.png" alt="Sample registrar information from who.is" width="646" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Websites like &lt;a href="http://who.is" rel="noopener noreferrer"&gt;http://who.is&lt;/a&gt; can help you identify your domain's registrar.&lt;/p&gt;

&lt;p&gt;You can change your domain's registrar through a transfer process. In general, changing registrars is not necessary to modify your domain's DNS records.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nameservers
&lt;/h2&gt;

&lt;p&gt;A domain's nameservers are significant because they identify what set of servers any requests should reference in order to obtain a domain's DNS records. Your domain should have its nameservers pointed to wherever you are intending to manage your site's DNS records.&lt;/p&gt;

&lt;p&gt;You can point your domain's nameservers anywhere that you can manage DNS, though. This means that if your domain's registrar allows you to manage DNS with them, then you can point nameservers at your registrar's nameservers and use their DNS management panel to set records. If you are interested in having your DNS hosted somewhere other than your web host or registrar, then hosted DNS is a good solution for you if you can find a service offering that fits your need and capacity requirements (e.g. AWS Route 53 that is a scalable cloud DNS web service).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fc8yrin2kw737gutqazcy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fc8yrin2kw737gutqazcy.png" alt="Sample nameserver information from who.is" width="647" height="325"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your domain's nameservers will likely need to change in the following cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You have &lt;strong&gt;just purchased a domain&lt;/strong&gt; and need to point nameservers at your web host. The default nameservers when purchasing a domain are normally the ones operated by the domain registrar.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You are currently managing your DNS records at your registrar and &lt;strong&gt;want your host to manage them&lt;/strong&gt; instead.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You have nameservers pointed at a web host that &lt;strong&gt;you are transitioning away from&lt;/strong&gt;. It is necessary to change nameservers because closing your hosting account will also remove your DNS records at that host so you will want to point them elsewhere.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of the most important things to note when changing nameservers is that they are a setting that &lt;strong&gt;can take a while to take effect across the world&lt;/strong&gt;. In most cases, nameservers will take between 1 and 10 hours to spread across a majority of servers across the world, but you should allow as long as 36 hours for them to take fully.&lt;/p&gt;

&lt;p&gt;This is quite a vital piece of knowledge because it is entirely possible to have two different sets of DNS records on two different sets of nameservers. If nameservers have taken effect in some parts of the world, but not others, then you may have some visitors seeing the site on old DNS records and some on new ones.&lt;/p&gt;




&lt;h2&gt;
  
  
  Query Types
&lt;/h2&gt;

&lt;p&gt;There are three types of queries in the DNS system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Recursive Query&lt;/strong&gt;: In a recursive query, a DNS client provides a hostname, and the DNS Resolver "must" provide an answer - it responds with either a relevant resource record or an error message if it can't be found. The resolver starts a recursive query process, starting from the DNS Root Server until it finds the Authoritative Name Server that holds the IP address and other information for the requested hostname.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Iterative Query&lt;/strong&gt;: In an iterative query, a DNS client provides a hostname, and the DNS Resolver returns the best answer it can. If the DNS resolver has the relevant DNS records in its cache, it returns them. If not, it refers the DNS client to the Root Server or another Authoritative Name Server which is nearest to the required DNS zone. The DNS client must then repeat the query directly against the DNS server it was referred to.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Non-Recursive Query&lt;/strong&gt;: A non-recursive query is a query in which the DNS Resolver already knows the answer. It either immediately returns a DNS record because it already stores it in the local cache, or queries a DNS Name Server which is authoritative for the record, meaning it definitely holds the correct IP for that hostname. In both cases, there is no need for additional rounds of queries (like in recursive or iterative queries). Rather, a response is immediately returned to the client.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  DNS Servers Types
&lt;/h3&gt;

&lt;p&gt;The following are the most common DNS server types that are used to resolve hostnames into IP addresses.&lt;/p&gt;

&lt;h5&gt;
  
  
  DNS Resolver
&lt;/h5&gt;

&lt;p&gt;A DNS resolver (recursive resolver), is designed to receive DNS queries, which include a human-readable hostname such as &lt;em&gt;&lt;a href="http://www.example.com" rel="noopener noreferrer"&gt;www.example.com&lt;/a&gt;&lt;/em&gt;, and is responsible for tracking the IP address for that hostname.&lt;/p&gt;

&lt;h5&gt;
  
  
  DNS Root Server
&lt;/h5&gt;

&lt;p&gt;The root server is the first step in the journey from hostname to IP address. The DNS Root Server extracts the Top Level Domain (TLD) from the user's query, for example, &lt;em&gt;&lt;a href="http://www.example.com" rel="noopener noreferrer"&gt;www.example.com&lt;/a&gt;&lt;/em&gt; and provides details for the &lt;strong&gt;.com&lt;/strong&gt; TLD Name Server. In turn, that server will provide details for domains with the .com DNS zone, including "example.com".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffd4x07qqqwu1f6bcsx7n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffd4x07qqqwu1f6bcsx7n.png" alt="A map of the thirteen logical name servers, including any casted instances, at the end of 2006" width="800" height="342"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are &lt;a href="https://en.wikipedia.org/wiki/Root_name_server" rel="noopener noreferrer"&gt;13 root servers&lt;/a&gt; worldwide, indicated by the letters &lt;strong&gt;A&lt;/strong&gt; through &lt;strong&gt;M&lt;/strong&gt;, operated by organizations like the Internet Systems Consortium, Verisign, ICANN, the University of Maryland, and the U.S. Army Research Lab.&lt;/p&gt;

&lt;h5&gt;
  
  
  Authoritative DNS Server
&lt;/h5&gt;

&lt;p&gt;Higher-level servers in the DNS hierarchy define which DNS server is the "authoritative" name server for a specific hostname, meaning that it holds the up-to-date information for that hostname.&lt;/p&gt;

&lt;p&gt;The Authoritative Name Server is the last stop in the name server query - it takes the hostname and returns the correct IP address to the DNS Resolver (or if it cannot find the domain, returns the message &lt;code&gt;NXDOMAIN&lt;/code&gt;).&lt;/p&gt;




&lt;h3&gt;
  
  
  Record Composition
&lt;/h3&gt;

&lt;p&gt;In general, most every DNS record requires at least three pieces of information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Record Name&lt;/li&gt;
&lt;li&gt;Record Type&lt;/li&gt;
&lt;li&gt;Record Value/Data&lt;/li&gt;
&lt;li&gt;Time to Live (TTL)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fewvzy9oqsi04p2mm4ysy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fewvzy9oqsi04p2mm4ysy.png" alt="AWS Route 53 Sample DNS Entry/Edit Box" width="417" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Record Name
&lt;/h4&gt;

&lt;p&gt;A DNS Record's name is the descriptor and effective subdomain of that entry. If you were adding a blog to your domain, you would create a DNS record and assign it the name "blog". This would mean that whenever a request attempts to use &lt;em&gt;blog.larapulse.com&lt;/em&gt;, the DNS zone is queried for information about a DNS record with the name of "blog". Although you can assign whatever name you'd like to a record, there exist a few special cases you should be aware of.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Blank Name&lt;/strong&gt; – A record that has nothing in the name slot gets used for all requests made to the base/naked form of the domain. To refer to a previous example, larapulse.com and &lt;a href="http://www.larapulse.com" rel="noopener noreferrer"&gt;www.larapulse.com&lt;/a&gt; are two different DNS records with separate values for their name. The &lt;a href="http://www.larapulse.com" rel="noopener noreferrer"&gt;www.larapulse.com&lt;/a&gt; DNS record uses "www" as its record name and larapulse.com uses nothing/blank for its record name.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;@ Symbol&lt;/strong&gt; – Some DNS management systems use the @ symbol in the "name" slot instead of the blank name entry. This is important because it allows the use of @ as another record's value/data, meaning the other record will refer to the value of the base/naked form of the domain to know where to point.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fog8ar5crz6p6nawy24il.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fog8ar5crz6p6nawy24il.png" alt="DNS allowed values" width="800" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's say for instance you always wanted &lt;a href="http://www.larapulse.com" rel="noopener noreferrer"&gt;www.larapulse.com&lt;/a&gt; to point at the same place as larapulse.com. You could just set them individually to point at the same place and manage them separately, but since the @ symbol represents the base/naked DNS record, you could set the www DNS record entry to have a value/data of @ and it will always refer to and use the value of the @ name record when being requested. &lt;em&gt;This is useful when multiple subdomains/records need to all point at the same place as the base/naked domain.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;* Symbol (Wildcard)&lt;/strong&gt; – It isn't strange to see the * symbol be used as the name for a DNS record. This symbol is used as an indicator that the record named * should be used in place of any record that isn't specified. These can be used when you would like to direct subdomains that do not exist somewhere where they can be accounted for or handled. This means that you can specify where you would like to send all traffic for the subdomain that does not exist as a DNS record or that you might not expect people to visit. You could consider the * symbol to be the DNS record "for everything else".&lt;/p&gt;

&lt;h4&gt;
  
  
  Record Types
&lt;/h4&gt;

&lt;p&gt;DNS servers create a DNS record to provide important information about a domain or hostname, particularly its current IP address. The most common DNS record types are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;A Record: Address Mapping record&lt;/em&gt;: also known as a DNS host record, stores a hostname and its corresponding IPv4 address.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;AAAA Record: IP Version 6 Address record&lt;/em&gt;: stores a hostname and its corresponding IPv6 address.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;CNAME Record: Canonical Name record&lt;/em&gt;: specifies a domain name that has to be queried in order to resolve the original DNS query. Therefore it can be used to alias a hostname to another hostname.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;MX Record: Mail exchanger record&lt;/em&gt;: specifies an SMTP email server for the domain a DNS domain name.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;NS Record: Name Server records&lt;/em&gt;: specifies that a DNS Zone, such as "example.com" is delegated to a specific Authoritative Name Server, and provides the address of the name server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;SOA Record: Start of Authority&lt;/em&gt;: this record appears at the beginning of a DNS zone file and specifies core information about a DNS zone, such as Authoritative Name Server for the current DNS zone, contact details for the domain administrator, domain serial number, and information on how frequently DNS information for this zone should be refreshed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;TXT Record: Text Record&lt;/em&gt;: is used to store any text-based information that can be grabbed when necessary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;PTR Record: Reverse-lookup Pointer records&lt;/em&gt;: is used to look up domain names based on an IP address, and allows a DNS resolver to provide an IP address and receive a hostname (reverse DNS lookup).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;CERT Record: Certificate record&lt;/em&gt;: store certificates and related revocation lists (CRL) for cryptographic keys.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;SRV Record: Service Location&lt;/em&gt;: is used to specify the location of a service, like MX but for other communication protocols.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh5wqv9ac01hbfmcswq66.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh5wqv9ac01hbfmcswq66.png" alt="DNS records" width="800" height="749"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Record Value/Data
&lt;/h4&gt;

&lt;p&gt;A DNS Record's value or data is the information that tells the DNS record where you want it to point, or in some cases, what you want it to do. In the case of &lt;code&gt;A&lt;/code&gt; Records and &lt;code&gt;CNAME&lt;/code&gt;s, the data/value represents the IP or domain, respectively, that the record name is pointed at and should refer to figure out where to go next.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;MX&lt;/code&gt; records, the value/data information indicates what mail servers email should be routed to. &lt;code&gt;SPF&lt;/code&gt; records use the value/data field so specify what servers are allowed to legitimately use your domain name for the sending of emails.&lt;/p&gt;

&lt;h4&gt;
  
  
  Time to Live (TTL)
&lt;/h4&gt;

&lt;p&gt;TTL is the numerical value, in seconds, of how long a DNS record will be cached before it needs to be refreshed. Whenever a nameserver is queried for a DNS record, it will check to see if it has delivered that same DNS record within the time period specified by the TTL and if so, will deliver the cached version of that DNS record. Once that period of time specified by the TTL passes, the nameserver will query the zone for record data and cache it once more for the specified period of time.&lt;/p&gt;

&lt;p&gt;The most important thing to know about TTL is that any changes you make to the value/data of a DNS record are subject to that TTL in regard to how long it will take for that record to start taking effect.&lt;/p&gt;

&lt;p&gt;TTL also applies to change the TTL itself in a record. For instance, if you are switching hosts and know you are going to need to change the IP address your domain points to, you might want to lower the TTL on your DNS records so that the switch over from your old host to new host happens as quickly as possible.&lt;/p&gt;

&lt;p&gt;Simply changing the TTL from 3600 to 60 will not ensure that your IP change will take effect within 60 seconds, it simply indicates to your zone/nameservers that once they request a fresh set of information after the current 3600 second caching period, it should also adjust your TTL from that point on. This means that if you want to switch from a 3600 TTL to a 60 second TTL, you should make the TTL change at least 3600 seconds in advance of your IP change to ensure yourself the 60 second TTL period.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Interesting in reading more about Networks? Follow &lt;a href="https://blog.larapulse.com/network" rel="noopener noreferrer"&gt;this link&lt;/a&gt; to find more articles 😉&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>dns</category>
      <category>nameservers</category>
      <category>server</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Commonly used DNS record types</title>
      <dc:creator>Sergey Podgorny</dc:creator>
      <pubDate>Mon, 13 Jan 2020 16:47:34 +0000</pubDate>
      <link>https://dev.to/larapulse/commonly-used-dns-record-types-3e4b</link>
      <guid>https://dev.to/larapulse/commonly-used-dns-record-types-3e4b</guid>
      <description>&lt;h2&gt;
  
  
  What is DNS
&lt;/h2&gt;

&lt;p&gt;DNS is a global system for translating IP addresses to human-readable domain names. When a user tries to access a web address like &lt;code&gt;example.com&lt;/code&gt;, their web browser or application performs a &lt;strong&gt;DNS Query&lt;/strong&gt; against a DNS server, supplying the hostname. The DNS server takes the hostname and resolves it into a numeric IP address, which the web browser can connect to.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F56532c7u6m5k0ypv5pny.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F56532c7u6m5k0ypv5pny.png" alt="DNS - Domain Name System" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is record types
&lt;/h2&gt;

&lt;p&gt;Before we dive into various types of DNS records, it is important to understand the distinction and concept of DNS Zones and DNS Records.&lt;/p&gt;

&lt;p&gt;Zone DNS database is a collection of resource records and each of the records provides information about a specific object. A DNS Zone is like a container of all the DNS records for a specific domain and only that domain.&lt;/p&gt;

&lt;p&gt;A DNS Record is a single entry that gives the zone instructions on how to handle any given request based on type.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp9mtcwyo9yzgswg6jqo8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp9mtcwyo9yzgswg6jqo8.png" alt="DNS record types" width="800" height="174"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;DNS servers create a DNS record to provide important information about a domain or hostname, particularly its current IP address. Each individual DNS record is assigned a type and information needed for that type of record.&lt;/p&gt;

&lt;p&gt;The most common DNS record types are:&lt;/p&gt;

&lt;h4&gt;
  
  
  Record A: Address Mapping record
&lt;/h4&gt;

&lt;p&gt;The A-record is the most basic and the most commonly used DNS record type. It is also known as a DNS host record, stores a hostname and its corresponding IPv4 address.&lt;/p&gt;

&lt;p&gt;It is used to translate human-friendly domain names such as &lt;code&gt;www.example.com&lt;/code&gt; into IP-addresses such as &lt;code&gt;93.184.216.34&lt;/code&gt; (machine friendly numbers).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3hi54t7ubor6bi73na4n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3hi54t7ubor6bi73na4n.png" alt="DNS record type A - to GitHub" width="800" height="238"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A-records are the DNS server equivalent of the hosts' file - a simple domain name to IP-address mapping. A-records are not required for all computers, but are needed for any computer that provides shared resources on a network. Assigning a value to an A record is as simple as providing your DNS management panel with an IP address to where the domain or subdomain should point and a TTL.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fglkdrzfdqpk7qc3xdu6j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fglkdrzfdqpk7qc3xdu6j.png" alt="DNS record type A" width="800" height="213"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You'll want to use an A Record for your DNS entry if you have an IP address that the domain/subdomain should point to or if you want to establish a domain/subdomain to be used as the place to point a CNAME.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This record type is defined in RFC1035.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Record AAAA: IP Version 6 Address record
&lt;/h4&gt;

&lt;p&gt;The record AAAA (also quad-A record) specifies IPv6 address for a given host. So it works the same way as the A record and the difference is the type of IP address.&lt;/p&gt;

&lt;p&gt;IPv6 is the future replacement for the current IP address system (also known as IPv4). The current IPv4 addresses are 32 bits long (&lt;code&gt;xxx.xxx.xxx.xxx&lt;/code&gt; = 4 bytes), and therefore "only" support a total of 4,294,967,296 addresses - less than the global population. With this limitation, there is an increasing shortage of IPv4 addresses, and to solve the problem, the whole Internet will eventually be migrated to IPv6.&lt;/p&gt;

&lt;p&gt;IPv6 addresses are 128 bits long and are written in hexadecimal numbers separated by colons (&lt;code&gt;:&lt;/code&gt;) at every four digits (segment). A series of zero value segments can be shortened as "&lt;code&gt;::&lt;/code&gt;", and leading zeros in a segment can be skipped. For example: &lt;code&gt;4C2F::1:2:3:4:567:89AB&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This record type is defined in RFC3596.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Record CNAME: Canonical Name record
&lt;/h4&gt;

&lt;p&gt;The CNAME record specifies a domain name that has to be queried in order to resolve the original DNS query. Therefore CNAME records are used for creating aliases of domain names. CNAME records are truly useful when you want to alias a domain to an external domain.&lt;/p&gt;

&lt;p&gt;When a DNS client requests a record that contains a CNAME, which points to another hostname, the DNS resolution process is repeated with the new hostname. In other cases, we can remove CNAME records and replace them with A records and even decrease performance overhead.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiv8iwau27f9riod9yawp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiv8iwau27f9riod9yawp.png" alt="DNS record type CNAME" width="800" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Computers on the Internet often perform multiple roles such as web-server, ftp-server, chat-server etc. To mask this, CNAME-records can be used to give a single computer multiple names (aliases).&lt;/p&gt;

&lt;p&gt;For example, the computer "computer1.xyz.com" may be both a web-server and an ftp-server, so two CNAME-records are defined:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;www.xyz.com&lt;/code&gt; = &lt;code&gt;computer1.xyz.com&lt;/code&gt; and &lt;code&gt;ftp.xyz.com&lt;/code&gt; = &lt;code&gt;computer1.xyz.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Sometimes a single server computer hosts many different domain names (take ISPs), and so CNAME-records may be defined such as &lt;code&gt;www.abc.com&lt;/code&gt; = &lt;code&gt;www.xyz.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The most common use of the CNAME-record type is to provide access to a web-server using both the standard &lt;code&gt;www.domain.com&lt;/code&gt; and &lt;code&gt;domain.com&lt;/code&gt; (with and without the www prefix). This is usually done by creating an A-record for the short name (without www), and a CNAME-record for the www name pointing to the short name.&lt;/p&gt;

&lt;p&gt;CNAME-records can also be used when a computer or service needs to be renamed, to temporarily allow access through both the old and new name.&lt;/p&gt;

&lt;p&gt;A CNAME-record should always point to an A-record and never to itself or another CNAME-record to avoid circular references.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This record type is defined in RFC1035.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Record MX: Mail exchanger record
&lt;/h4&gt;

&lt;p&gt;It specifies an SMTP email server for the domain a DNS domain name. The information is used by Simple Mail Transfer Protocol (SMTP) to route emails to proper hosts. Typically, there is more than one mail exchange server for a DNS domain and each of them has set priority.&lt;/p&gt;

&lt;p&gt;Mail Exchanger (MX) records are used to help route email according to the domain owners preference. The MX record itself specifies which server(s) to attempt to use to deliver mail to when this type of request is made to the domain. They differ from A Records and CNAMEs in the way that they also require a "priority" value as a part of their entry. The priority number is used to indicate which of the servers listed as MX records it should attempt to use first.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If a domain name is handled by multiple e-mail servers (for backup/redundancy), a separate MX-record is used for each e-mail server, and the preference numbers then determine in which order (lower numbers first) these servers should be used by other e-mail servers.&lt;/li&gt;
&lt;li&gt;If a domain name is handled by a single e-mail server, only one MX-record is needed and the preference number does not matter.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some email providers have only one MX record and some have well over two. The number of MX entries you will need to create depends largely on the mail provider and how they expect the load on these email servers to be handled.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Farsj7i0q5un6x2l1gjyc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Farsj7i0q5un6x2l1gjyc.png" alt="DNS record type MX" width="800" height="134"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When sending an e-mail to "&lt;a href="mailto:user@example.com"&gt;user@example.com&lt;/a&gt;", your e-mail server must first lookup any MX-records for "example.com" to see which e-mail servers handle incoming e-mail for "example.com". This could be "mail.example.com" or someone else's mail server like "mail.larapulse.com". After this, it looks up the A-record for that e-mail server name to connect to its IP-address.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt;&lt;br&gt;
An MX-record must point to the name of a mail server - not directly to the IP-address.&lt;br&gt;
Because of this, it is very important that an A-record for the referenced mail server name exists (not necessarily on your DNS server, but wherever it belongs), otherwise there may not be any way to connect to that e-mail server.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Do not point an MX-record to a CNAME-record. Many e-mail servers don't understand this. Add another A-record instead.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This record type is defined in RFC1035.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Record NS: Name Server records
&lt;/h4&gt;

&lt;p&gt;It specifies that a DNS Zone, such as “example.com” is delegated to a specific Authoritative Name Server, and provides the address of the name server.&lt;/p&gt;

&lt;p&gt;A zone should contain one NS-record for each of its own DNS servers (primary and secondaries). This is mostly used for zone transfer purposes (notify messages). These NS-records have the same name as the zone in which they are located.&lt;/p&gt;

&lt;p&gt;The more important function of the NS-record is &lt;strong&gt;delegation&lt;/strong&gt;. Delegation means that part of a domain is delegated to other DNS servers.&lt;/p&gt;

&lt;p&gt;For example, all ".com" sub-names (such as "example.com") are delegated from the "com" zone. The "com" zone contains NS-records for all ".com" sub-names (a lot!).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F227sl1jhnp86uufgia52.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F227sl1jhnp86uufgia52.png" alt="DNS record type NS" width="590" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can delegate sub-names of your own domain name (such as "subname.example.com") to other DNS servers the same way. To delegate "subname.example.com", create NS-records for "subname.example.com" in the "example.com" zone. These NS-records must point to the DNS server responsible for "subname.example.com", for example, "ns1.subname.example.com" - or a DNS server somewhere else like "ns1.othername.net".&lt;/p&gt;

&lt;p&gt;An NS-record identifies the name of a DNS server - not the IP-address. Because of this, it is important that an A-record for the referenced DNS server exists (not necessarily on your DNS server, but wherever it belongs), otherwise there may not be any way to connect with that DNS server.&lt;/p&gt;

&lt;p&gt;If an NS-record delegates a sub-name ("subname.example.com") to a DNS server with a name in that sub-name ("ns1.subname.example.com"), an A-record for that server (""ns1.subname.example.com") must exist in the parent zone ("example.com"). This A-record is called a &lt;em&gt;"glue record"&lt;/em&gt;, because it doesn't really belong in the parent zone, but is necessary to locate the DNS server for the delegated sub-name.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This record type is defined in RFC1035.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Record SOA: Start of Authority
&lt;/h4&gt;

&lt;p&gt;This record appears at the beginning of a DNS zone file and specifies core information about a DNS zone. A zone contains exactly one SOA-record, which holds the following properties for the zone:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name of primary DNS server&lt;/strong&gt;. The hostname of the primary DNS server for the zone. The zone should contain a matching NS-record.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;NOTE: For dynamic updates from Windows clients and Active Directory to work correctly, it is important that this contains the correct hostname for the primary DNS server for the zone, and also that an A-record exists for this name pointing to the correct IP address.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;E-mail address of responsible person&lt;/strong&gt;. The e-mail address of the person responsible for the zone. The standard for this is the "hostmaster" alias - such as "&lt;a href="mailto:hostmaster@example.com"&gt;hostmaster@example.com&lt;/a&gt;".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Serial number&lt;/strong&gt;. Used by secondary DNS servers to check if the zone has changed. If the serial number is higher than what the secondary server has, a zone transfer will be initiated. You should never decrease the serial number.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Refresh Interval&lt;/strong&gt;. How often secondary DNS servers should check if changes are made to the zone.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Retry Interval&lt;/strong&gt;. How often secondary DNS server should retry checking if changes are made - if the first refresh fails.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Expire Interval&lt;/strong&gt;. How long the zone will be valid after a refresh. Secondary servers will discard the zone if no refresh could be made within this interval.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Minimum (default) TTL&lt;/strong&gt;. Used by other DNS servers to cache negative responses (such as record does not exist etc.).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;This record type is defined in RFC1035.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Record TXT: Text Record
&lt;/h4&gt;

&lt;p&gt;A TXT record is used to store any text-based information that can be grabbed when necessary. We most commonly see TXT records used to hold SPF data and verify domain ownership. They are also often used to hold general information about a domain name such as who is hosting it, contact person, phone numbers, etc.&lt;/p&gt;

&lt;p&gt;One common use of TXT-records is for SPF.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This record type is defined in RFC1035.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Record ALIAS: Auto resolved alias
&lt;/h4&gt;

&lt;p&gt;ALIAS-records are virtual alias records resolved by DNS Provider at the time of each request - providing "flattened" (no CNAME-record chain) synthesized records with data from a hidden source name.&lt;/p&gt;

&lt;p&gt;This can be used for different purposes - including solving the classic problem with CNAME-records at the domain apex (for the zone name / for "the naked domain").&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Similar implementations of virtual alias records ("ANAME", "ALIAS", "CNAME flattening") are offered by various DNS service providers. There is no standard (RFC or similar) for this.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Record PTR: Reverse-lookup Pointer records
&lt;/h4&gt;

&lt;p&gt;As opposed to forward DNS resolution (A and AAAA DNS records), the PTR record is used to look up domain names based on an IP address.&lt;/p&gt;

&lt;p&gt;For a reverse IPv4 mapping, the name of the PTR-record is the IP address with the segments reversed and with "in-addr.arpa" appended to the end. As an example, looking up the domain name for IP address "&lt;code&gt;12.23.34.45&lt;/code&gt;" is done with a query for the PTR-record for "&lt;code&gt;45.34.23.12.in-addr.arpa&lt;/code&gt;".&lt;/p&gt;

&lt;p&gt;For a reverse IPv6 mapping, the name of the PTR-record is each hex digit of the IP address in reverse order, with dots between each digit, and with "ip6.arpa" appended to the end. As an example, looking up the domain name for IPv6 address "&lt;code&gt;1234:5678:90ab:cdef:1234:5678:90ab:cdef&lt;/code&gt;" is done with a query for the PTR-record for "&lt;code&gt;f.e.d.c.b.a.0.9.8.7.6.5.4.3.2.1.f.e.d.c.b.a.0.9.8.7.6.5.4.3.2.1.ip6.arpa&lt;/code&gt;".&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This record type is defined in RFC1035.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Record CERT: Certificate record
&lt;/h4&gt;

&lt;p&gt;CERT-records store certificates and related revocation lists (CRL) for cryptographic keys.&lt;/p&gt;

&lt;p&gt;CERT-records have the following data elements (see RFC below for details):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Type&lt;/em&gt;: the type of certificate/CRL stored. Select one of the predefined values, or enter a numeric value (0-65535).&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Key tag&lt;/em&gt;: A numeric value (0-65535) used the efficiently pick a CERT record.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Algorithm&lt;/em&gt;: the algorithm used. Select one of the predefined values, or enter a numeric value (0-65535).&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Certificate or CRL&lt;/em&gt;: Base 64 encoded.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;This record type is defined in RFC4398.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Record SRV: Service Location
&lt;/h4&gt;

&lt;p&gt;SRV-records are used to specify the location of a service. They are used in connection with different directory servers such as LDAP (Lightweight Directory Access Protocol), and Windows Active Directory, and more recently with SIP servers.&lt;/p&gt;

&lt;p&gt;They can also be used for advanced load balancing and to specify specific ports for services, for example, that a web-server is running on port &lt;code&gt;8080&lt;/code&gt; instead of the usual port &lt;code&gt;80&lt;/code&gt; (theoretical example - this is not yet supported by any major browsers). This record type is, however, &lt;strong&gt;NOT supported&lt;/strong&gt; by most programs in use today, including web-browsers.&lt;/p&gt;

&lt;p&gt;The SRV record identification (record name) is made of 3 parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Service&lt;/em&gt;: Most internet services are defined in RFC1700 (page 15).&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Protocol&lt;/em&gt;: Generally TCP or UDP, but also values are also valid.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Domain name&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The "service location" is specified through a priority, weight, port and target:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Priority is a preference number used when more servers are providing the same service (lower numbers are tried first).&lt;/li&gt;
&lt;li&gt;Weight is used for advanced load balancing.&lt;/li&gt;
&lt;li&gt;Port is the TCP/UDP port number on the server that provides this service.&lt;/li&gt;
&lt;li&gt;Target is the domain name of the server (referencing an A-record or AAAA-record).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;This record type is defined in RFC2782.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Record HINFO: Host Information records
&lt;/h4&gt;

&lt;p&gt;HINFO records are used to acquire general information about a host. The record specifies a type of CPU and OS. The HINFO record data provides the possibility to use operating system specific protocols when two hosts want to communicate. For security reasons, the HINFO records are not typically used on public servers.&lt;/p&gt;

&lt;p&gt;This information can be used by application protocols such as FTP, which use special procedures when communicating with computers of a known CPU and operating system type. Standard CPU and operating system types are defined in RFC1700 (Page 206 / 214). The standard for a Windows PC is "INTEL-386" / "WIN32".&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This record type is defined in RFC1035.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Record ISDN: Integrated Services Digital Network records
&lt;/h4&gt;

&lt;p&gt;The ISDN resource record specifies ISDN address for a host. An ISDN address is a telephone number that consists of a country code, a national destination code, an ISDN Subscriber number and, optionally, an ISDN subaddress.&lt;/p&gt;

&lt;p&gt;The ISDN phone numbers / DDI (Direct Dial In) used should follow &lt;code&gt;ITU-T E.163/E.164&lt;/code&gt; international telephone numbering standards. The ISDN sub-address is an optional hexadecimal number.&lt;/p&gt;

&lt;p&gt;The function of the record is the only variation of the A resource record function.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This record type is defined in RFC1183.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Managing your own DNS can be a tricky endeavour, especially if you haven't ever considered what this means or ever even seen a DNS record. The most important DNS record types you should know is A, CNAME, MX, NS and SOA.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Interesting in reading more about Networks? Follow &lt;a href="https://blog.larapulse.com/network" rel="noopener noreferrer"&gt;this link&lt;/a&gt; to find more articles 😉&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>network</category>
      <category>dns</category>
      <category>server</category>
      <category>administration</category>
    </item>
    <item>
      <title>Process monitoring tools you probably didn't know about</title>
      <dc:creator>Sergey Podgorny</dc:creator>
      <pubDate>Fri, 20 Dec 2019 12:45:34 +0000</pubDate>
      <link>https://dev.to/larapulse/process-monitoring-tools-you-probably-didn-t-know-about-3fmm</link>
      <guid>https://dev.to/larapulse/process-monitoring-tools-you-probably-didn-t-know-about-3fmm</guid>
      <description>&lt;h2&gt;
  
  
  Htop – Linux Process Monitoring
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;htop&lt;/code&gt; is a much advanced interactive and real time Linux process monitoring tool. This is much similar to Linux &lt;code&gt;top&lt;/code&gt; command, but it has some rich features like user friendly interface to manage process, shortcut keys, vertical and horizontal view of the processes and much more. &lt;code&gt;htop&lt;/code&gt; is a third-party tool and isn't included in Linux systems, you need to install it manually.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuxe109b2ve2728sax909.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuxe109b2ve2728sax909.png" alt="htop - Process monitoring tool" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Features
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;it shows a frequently updated list of the processes running on a computer, normally ordered by the amount of CPU usage;&lt;/li&gt;
&lt;li&gt;it provides a full list of processes running, instead of the top resource-consuming processes;&lt;/li&gt;
&lt;li&gt;it uses color and gives visual information about processor, swap and memory status;&lt;/li&gt;
&lt;li&gt;it can also display the processes as a tree;&lt;/li&gt;
&lt;li&gt;it provides a convenient, visual, cursor-controlled interface for sending signals to processes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Instalation
&lt;/h4&gt;

&lt;p&gt;Debian / Ubuntu:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo apt-get install htop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CentOs / Fedora:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# yum install htop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MacOS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ brew install htop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Usage
&lt;/h4&gt;

&lt;p&gt;All you have to do is just run it from the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ htop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Navigating throughout this tools is very easy, especially due to the fact that it supports the work of the cursor.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can also check out other alternatives, like &lt;a href="https://nicolargo.github.io/glances/" rel="noopener noreferrer"&gt;Glances&lt;/a&gt; or &lt;a href="http://nmon.sourceforge.net/pmwiki.php" rel="noopener noreferrer"&gt;nmon&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;Glances&lt;/code&gt; is a good htop alternative as it can adapt dynamically when displaying system information, depending on the terminal size.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F14c4xmvieeldn5alu0ih.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F14c4xmvieeldn5alu0ih.png" alt="Glances at the terminal" width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;nmon&lt;/code&gt; is another htop alternative systems administrators tool, for server tuning, benchmarking or viewing detailed system performance information.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0rpwsuzy1ok4f06liv09.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0rpwsuzy1ok4f06liv09.png" alt="nmon at the terminal" width="800" height="411"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  IPTraf – Real Time IP LAN Monitoring
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;iptraf&lt;/code&gt; is an open source console-based real time network (IP LAN) monitoring utility for Linux. It collects a variety of information such as IP traffic monitor that passes over the network, including TCP flag information, ICMP details, TCP/UDP traffic breakdowns, TCP connection packet and byne counts. It also gathers information of general and detailed interface statistics of TCP, UDP, IP, ICMP, non-IP, IP checksum errors, interface activity etc.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzmh2xc1q90vc5umzgrzk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzmh2xc1q90vc5umzgrzk.png" alt="IPTraf – Real Time IP LAN Monitoring" width="800" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Features
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;An &lt;em&gt;IP traffic monitor&lt;/em&gt; shows information on the IP traffic passing over your network. Includes TCP flag information, packet and byte counts, ICMP details, OSPF packet types.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;General and detailed interface statistics&lt;/em&gt; showing IP, TCP, UDP, ICMP, non-IP and other IP packet counts, IP checksum errors, interface activity, packet size counts.&lt;/li&gt;
&lt;li&gt;A &lt;em&gt;TCP and UDP service monitor&lt;/em&gt; showing counts of incoming and outgoing packets for common TCP and UDP application ports.&lt;/li&gt;
&lt;li&gt;A &lt;em&gt;LAN statistics module&lt;/em&gt; discovers active hosts and shows statistics showing the data activity on them.&lt;/li&gt;
&lt;li&gt;TCP, UDP, and other protocol display filters allowing you to view only traffic you're interested in.&lt;/li&gt;
&lt;li&gt;Support Logging.&lt;/li&gt;
&lt;li&gt;Supports Ethernet, FDDI, ISDN, SLIP, PPP, and loopback interface types.&lt;/li&gt;
&lt;li&gt;Utilizes the built-in raw socket interface of the Linux kernel, allowing it to be used over a wide range of supported network cards.&lt;/li&gt;
&lt;li&gt;Full-screen, menu-driven operation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Instalation
&lt;/h4&gt;

&lt;p&gt;Debian / Ubuntu:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo apt-get install iptraf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CentOS / Fedora:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# yum install iptraf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Usage
&lt;/h4&gt;

&lt;p&gt;If the &lt;code&gt;iptraf&lt;/code&gt; command is issued without any command-line options, the program comes up in interactive mode, with the various facilities accessed through the main menu. &lt;strong&gt;Note&lt;/strong&gt;, that it has to be run with &lt;code&gt;root&lt;/code&gt; privileges:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo iptraf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Ctop - interface for container metrics
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://ctop.sh/" rel="noopener noreferrer"&gt;&lt;code&gt;ctop&lt;/code&gt;&lt;/a&gt; provides a concise and condensed overview of real-time metrics for multiple containers, as well as a single container view for inspecting a specific container.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It mostly works same as &lt;code&gt;docker stats&lt;/code&gt;, but provides a better interface and single container view and logging.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmrxkf5oyzflnko9qcvck.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmrxkf5oyzflnko9qcvck.png" alt="Ctop - Top-like interface for container metrics" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Features
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;it shows a frequently updated list of the containers with metrics running on a computer;&lt;/li&gt;
&lt;li&gt;it comes with built-in support for Docker and runC;&lt;/li&gt;
&lt;li&gt;it uses color and gives visual information about CPU, memory and network usage;&lt;/li&gt;
&lt;li&gt;it shows logs per instance;&lt;/li&gt;
&lt;li&gt;it has a full-screen, menu-driven operation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxlmvh5vewm2euymbjhau.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxlmvh5vewm2euymbjhau.png" alt="Ctop - Instance logging" width="800" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Instalation
&lt;/h4&gt;

&lt;p&gt;Linux:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo wget https://github.com/bcicen/ctop/releases/download/v0.7.2/ctop-0.7.2-linux-amd64 -O /usr/local/bin/ctop
$ sudo chmod +x /usr/local/bin/ctop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MacOS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ brew install ctop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Usage
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;ctop&lt;/code&gt; requires no arguments and uses Docker host variables by default. To run it, just type it in the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ctop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Mytop - real-time threads and performance monitoring tools
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;mytop&lt;/code&gt; is an open source, command line tool used for monitoring MySQL performance. Mytop connects to a MySQL server and periodically runs the &lt;code&gt;show processlist&lt;/code&gt; and &lt;code&gt;show global status&lt;/code&gt; commands. It then summarizes the information in a useful format. Using &lt;code&gt;mytop&lt;/code&gt;, we can in real-time monitor MySQL threads, queries, and uptime as well as see which user is running queries on which database, which are the slow queries, and more. All this information can be used to optimize the MySQL server performance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8p0yrexho4tdz602kt95.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8p0yrexho4tdz602kt95.png" alt="Mytop - monitoring queries and processes" width="800" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Features
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;htop&lt;/code&gt; provides a command-line shell interface to monitor real time MySQL/MariaDB threads, queries per second, process list and performance of databases and gives an idea for the database administrator to better optimize the server to handle a heavy load.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;mytop&lt;/code&gt; display screen is really broken into two parts. The top 4 lines (header) contain summary information about your MySQL server:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first line identified the hostname of the server and the version of MySQL it is running. The right side shows the &lt;code&gt;uptime&lt;/code&gt; of the MySQL server process in &lt;code&gt;days+hours:minutes:seconds&lt;/code&gt; format (much like FreeBSD's top) as well as the current time.&lt;/li&gt;
&lt;li&gt;The second line displays the total number of queries the server has processed, the average number of queries per second, the real-time number of queries per second, and the number of slow queries.&lt;/li&gt;
&lt;li&gt;The third line deals with threads. Versions of MySQL before 3.23.x didn't give out this information, so you'll see all zeros.&lt;/li&gt;
&lt;li&gt;And the fourth line displays key buffer efficiency (how often keys are read from the buffer rather than disk) and the number of bytes that MySQL has sent and received.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The second part of the display lists as many threads as can fit on screen. By default, they are sorted according to their idle time (least idle first).&lt;/p&gt;

&lt;h4&gt;
  
  
  Instalation
&lt;/h4&gt;

&lt;p&gt;By default Mytop tool is included in the Fedora and Debian/Ubuntu repositories, so you just have to install it using your default package manager. To install Mytop, run the appropriate command below for your Linux distribution to install it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo apt install mytop    # Debian/Ubuntu
# yum install mytop         # RHEL/CentOS
# dnf install mytop         # Fedora 22+
# pacman -S mytop           # Arch Linux
# zypper in mytop           # openSUSE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To prevent inserting connection details, create a customized configuration file for mytop named &lt;code&gt;.mytop&lt;/code&gt; in the home directory and add the following content in the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;user&lt;/span&gt;=&lt;span class="n"&gt;root&lt;/span&gt;
&lt;span class="n"&gt;pass&lt;/span&gt;=
&lt;span class="n"&gt;host&lt;/span&gt;=&lt;span class="m"&gt;127&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;db&lt;/span&gt;=
&lt;span class="n"&gt;port&lt;/span&gt;=&lt;span class="m"&gt;3306&lt;/span&gt;
&lt;span class="n"&gt;delay&lt;/span&gt;=&lt;span class="m"&gt;3&lt;/span&gt;
&lt;span class="n"&gt;slow&lt;/span&gt;=&lt;span class="m"&gt;10&lt;/span&gt;
&lt;span class="n"&gt;socket&lt;/span&gt;=
&lt;span class="n"&gt;batchmode&lt;/span&gt;=&lt;span class="m"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;header&lt;/span&gt;=&lt;span class="m"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;color&lt;/span&gt;=&lt;span class="m"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;idle&lt;/span&gt;=&lt;span class="m"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;long&lt;/span&gt;=&lt;span class="m"&gt;120&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;delay&lt;/code&gt; option specifies the amount of time in seconds between display refreshes. The &lt;code&gt;idle&lt;/code&gt; parameter specifies whether to allow idle (sleeping) threads to appear in the list in mytop display screen.&lt;/p&gt;

&lt;h4&gt;
  
  
  Usage
&lt;/h4&gt;

&lt;p&gt;If you configured &lt;code&gt;.mytop&lt;/code&gt; file, you can run &lt;code&gt;mytop&lt;/code&gt; without any command-line arguments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mytop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you didn't provide a password in the configuration file, you have to use the &lt;code&gt;--prompt&lt;/code&gt; option to &lt;code&gt;mytop&lt;/code&gt;, which asks for the password each time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mytop --prompt
Password:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you need to connect to another database, then in the configuration file, you could run mytop with necessary arguments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mytop -u larapulse -d larapulse_db --prompt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;That's definitely not all useful monitoring tools that exist, so you could find more in resources (links) below. Nevertheless, we think that &lt;code&gt;htop&lt;/code&gt;, &lt;code&gt;iptraf&lt;/code&gt;, &lt;code&gt;ctop&lt;/code&gt; and &lt;code&gt;mytop&lt;/code&gt; are the most used in the daily development cycle.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Interesting in reading more? Follow &lt;a href="https://blog.larapulse.com/dev-tools" rel="noopener noreferrer"&gt;this link&lt;/a&gt; to find more articles 😉&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>terminal</category>
      <category>tracking</category>
      <category>monitoring</category>
      <category>devtools</category>
    </item>
    <item>
      <title>PHP variables under the hood</title>
      <dc:creator>Sergey Podgorny</dc:creator>
      <pubDate>Wed, 18 Dec 2019 12:50:13 +0000</pubDate>
      <link>https://dev.to/larapulse/php-variables-under-the-hood-2onh</link>
      <guid>https://dev.to/larapulse/php-variables-under-the-hood-2onh</guid>
      <description>&lt;p&gt;Variables in PHP are some containers that store the type of the variable, its value, the amount of referring variables to this container, and the flag - whether this variable is referenced.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6elgtqcr8fzobblkj41.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6elgtqcr8fzobblkj41.png" alt="PHP variables under the hood" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Structures and Pointers
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Structures&lt;/strong&gt; are very similar to classes, but they can not have methods, just data, pointers to data and pointers to functions. Declaring a structure in C, you define the data type. And when defining a variable, you can write the name of this structure in place of the type of that variable, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;my_super_struct&lt;/span&gt; &lt;span class="n"&gt;super_struct_instance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pointers&lt;/strong&gt; are like variables, but their values store an address in memory. Reference variables behave like dereferenced pointers, that means they access values of the pointer. Let's look at an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="c1"&gt;// defining pointer `foo`, that will points to the variable with `int` type&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// defining variable with `int` type&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// taking reference to variable `bar` and assigning it to pointer.&lt;/span&gt;
&lt;span class="c1"&gt;// `foo` stores memory address, where `bar` stores&lt;/span&gt;
&lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// with an asterisk we dereference the pointer (take the value at its address) and increment the value&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// we increment the pointer itself, that means the pointer will refer at another value&lt;/span&gt;
&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbjvlcg4utso88hmr2bvg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbjvlcg4utso88hmr2bvg.png" alt="Dealing with pointers" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Containers
&lt;/h3&gt;

&lt;p&gt;The container is a structure called &lt;code&gt;zval&lt;/code&gt; (short for &lt;strong&gt;“Zend value”&lt;/strong&gt;), it represents an arbitrary PHP value and looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;zval&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;zvalue_value&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;zend_uchar&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;zend_uchar&lt;/span&gt; &lt;span class="n"&gt;is_ref&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;zend_ushort&lt;/span&gt; &lt;span class="n"&gt;refcount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we can see, there is a value, a type, a flag and an amount of referring variables. PHP &lt;code&gt;zval&lt;/code&gt; supports the following 8 types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;BOOL&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;LONG&lt;/code&gt; &lt;em&gt;(signed integer type)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DOUBLE&lt;/code&gt; &lt;em&gt;(used to store floating point numbers)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;STRING&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ARRAY&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OBJECT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RESOURCE&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NULL&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;zvalue_value&lt;/code&gt; is an &lt;code&gt;union&lt;/code&gt;. A union is a special type that may have several members declarations of different types, but only one will be used. That how it defines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;union&lt;/span&gt; &lt;span class="n"&gt;_zvalue_value&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;lval&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// integer&lt;/span&gt;
    &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;dval&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// float&lt;/span&gt;
    &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// string&lt;/span&gt;
    &lt;span class="n"&gt;HashTable&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ht&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// array&lt;/span&gt;
    &lt;span class="n"&gt;zend_object&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// object&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;zvalue_value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As a result, when you create a variable of this type, it will take in memory exactly as much as occupies the heaviest element of unions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0c9btu90jj40wjhm2q9m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0c9btu90jj40wjhm2q9m.png" alt="PHP variable creation" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why do we need all this
&lt;/h3&gt;

&lt;p&gt;First, let's figure out why we need &lt;strong&gt;refcount&lt;/strong&gt;. That's very simple: when you assign to a variable value of another variable, they both refer to one &lt;code&gt;zval&lt;/code&gt;, and &lt;code&gt;refcount&lt;/code&gt; increments.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl35qbsevqqaaflbidkxv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl35qbsevqqaaflbidkxv.png" alt="2 variables refers to the same memory place" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, if you change the value of one of these variables, PHP seeing the &lt;code&gt;refcount&lt;/code&gt; greater than 1, will copy this &lt;code&gt;zval&lt;/code&gt;, make the changes there, and your variable will point already to the new &lt;code&gt;zval&lt;/code&gt;. It will look something like this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
    &lt;tr&gt;
        &lt;th&gt;PHP&lt;/th&gt;
        &lt;th&gt;Under the hood&lt;/th&gt;
    &lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
    &lt;tr&gt;
        &lt;td class="highlight"&gt;
&lt;pre class="highlight php"&gt;
&lt;code&gt;$foo = "baz";
$bar = $foo;
&lt;/code&gt;&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td class="highlight"&gt;
&lt;pre class="highlight c"&gt;
&lt;code&gt;bar,foo: {
    type: string,
    value:
        str:
            val: "baz"
            len: 3
    is_ref: 0
    refcount: 2
}
&lt;/code&gt;&lt;/pre&gt;
        &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td class="highlight"&gt;
&lt;pre class="highlight php"&gt;
&lt;code&gt;$bar .= "q";
&lt;/code&gt;&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td class="highlight"&gt;
&lt;pre class="highlight c"&gt;
&lt;code&gt;foo: {
    type: string,
    value:
        str:
            val: "baz"
            len: 3
    is_ref: 0
    refcount: 1
}
bar: {
    type: string,
    value:
        str:
            val: "bazq"
            len: 4
    is_ref: 0
    refcount: 1
}
&lt;/code&gt;&lt;/pre&gt;
        &lt;/td&gt;
    &lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This technique is called &lt;strong&gt;"copy on write"&lt;/strong&gt; and it allows to reduce memory consumption quite well. Also, &lt;code&gt;refcount&lt;/code&gt; is needed for the &lt;strong&gt;garbage collector&lt;/strong&gt;, which removes from memory all &lt;code&gt;zval&lt;/code&gt;s, which have &lt;code&gt;refcount = 0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And what happens with references? And &lt;strong&gt;&lt;code&gt;is_ref&lt;/code&gt;&lt;/strong&gt; is working? That's very simple: if you create a reference from a variable, the is_ref flag becomes 1, and the above optimization for this zval will not be applied.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
    &lt;tr&gt;
        &lt;th&gt;PHP&lt;/th&gt;
        &lt;th&gt;Under the hood&lt;/th&gt;
    &lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
    &lt;tr&gt;
        &lt;td class="highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;$foo = "baz";
$bar = $foo;&lt;/code&gt;&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class="highlight c"&gt;
&lt;code&gt;bar,foo: {
    type: string,
    value:
        str:
            val: "baz"
            len: 3
    is_ref: 0
    refcount: 2
}
&lt;/code&gt;&lt;/pre&gt;
        &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td class="highlight"&gt;
&lt;pre class="highlight php"&gt;
&lt;code&gt;$baz = &amp;amp;$foo;&lt;/code&gt;&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;
&lt;pre class="highlight c"&gt;
&lt;code&gt;baz,foo: {
    type: string,
    value:
        str:
            val: "baz"
            len: 3
    is_ref: 1
    refcount: 2
}
bar: { // variable `bar` was allocated to a separate `zval`
    type: string,
    value:
        str:
            val: "baz"
            len: 3
    is_ref: 0
    refcount: 1
}
&lt;/code&gt;&lt;/pre&gt;
        &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td class="highlight"&gt;
&lt;pre class="highlight php"&gt;
&lt;code&gt;$qwe = $foo;&lt;/code&gt;&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td class="highlight"&gt;
&lt;pre class="highlight c"&gt;
&lt;code&gt;baz,foo: {
    type: string,
    value:
        str:
            val: "baz"
            len: 3
    is_ref: 1
    refcount: 2
}
bar: {
    type: string,
    value:
        str:
            val: "baz"
            len: 3
    is_ref: 0
    refcount: 1
}
// this variable was also allocated to a separate `zval`
qwe: {
    type: string,
    value:
        str:
            val: "baz"
            len: 3
    is_ref: 0
    refcount: 1
}
&lt;/code&gt;&lt;/pre&gt;
        &lt;/td&gt;
    &lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Interesting in reading more about PHP? Follow &lt;a href="https://blog.larapulse.com/php" rel="noopener noreferrer"&gt;this link&lt;/a&gt; to find more articles 😉&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>php</category>
      <category>variables</category>
      <category>structures</category>
      <category>pointers</category>
    </item>
    <item>
      <title>Datastructures in PHP</title>
      <dc:creator>Sergey Podgorny</dc:creator>
      <pubDate>Tue, 17 Dec 2019 12:44:59 +0000</pubDate>
      <link>https://dev.to/larapulse/datastructures-in-php-4hkl</link>
      <guid>https://dev.to/larapulse/datastructures-in-php-4hkl</guid>
      <description>&lt;p&gt;The development process in PHP is mostly related to the receipt and processing of data from different sources, such as databases, local files, remote APIs, etc. Developers spend a lot of time organizing data, getting, moving and processing it. The most used structure for representing data in PHP is an &lt;code&gt;array&lt;/code&gt;. However, in some cases, arrays are not suitable for solving problems due to insufficient performance and excessive memory consumption, and therefore more appropriate data structures are required.&lt;/p&gt;

&lt;p&gt;Usage of the &lt;strong&gt;Standard PHP Library, SPL&lt;/strong&gt; and knowledge of its composition is an area whose possession can confirm the competence of the PHP developer. &lt;/p&gt;

&lt;p&gt;SPL is like patterns, but purely for data. Mostly it doesn't simplify writing of code, but simplify its understanding by others (or by yourself after a while). Of course, if you used it well and right.&lt;/p&gt;

&lt;h3&gt;
  
  
  Doubly-linked lists
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;SplDoublyLinkedList&lt;/code&gt; - Doubly-linked lists are a variation on "standard" linked lists where each node has a pointer to the previous node as well as a pointer to the next node. &lt;/p&gt;

&lt;p&gt;Imagine that you are in the queue at the bank and at the same time you can see only the person in front of you and behind you. This is an analogy of the relationship between the elements in the &lt;code&gt;SplDoublyLinkedList&lt;/code&gt;. Inserting an item into the list corresponds to the situation when someone climbed into the queue, and you suddenly forgot who was standing in front of you (and this someone forgot about you). A doubly-linked list allows you to efficiently bypass and add large data sets without re-hashing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fil0ui20kbdgi4gb12c9p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fil0ui20kbdgi4gb12c9p.png" alt="Linked list types, single-listed and doubly-linked lists" width="800" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;SplDoublyLinkedList&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SplStack&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SplQueue&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;SplQueue&lt;/code&gt; and &lt;code&gt;SplStack&lt;/code&gt; are very similar to &lt;code&gt;SplDoublyLinkedList&lt;/code&gt;. Both these structures, in fact, are doubly linked lists with different iterator flags (&lt;code&gt;IT_MODE_LIFO&lt;/code&gt; - Last In First Out, and &lt;code&gt;IT_MODE_FIFO&lt;/code&gt; - First In First Out), which regulate the order of node processing and what to do with these elements after they have been processed. Another difference between these structures is that the &lt;code&gt;SplQueue&lt;/code&gt; interface contains more intuitive &lt;code&gt;enqueue()&lt;/code&gt; and &lt;code&gt;dequeue()&lt;/code&gt; methods, unlike the &lt;code&gt;push()&lt;/code&gt; and &lt;code&gt;pop()&lt;/code&gt; methods of &lt;code&gt;SplStack&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="nv"&gt;$stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\SplStack&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// add items to the stack&lt;/span&gt;
    &lt;span class="nv"&gt;$stack&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'1'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
    &lt;span class="nv"&gt;$stack&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$stack&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'3'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$stack&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;count&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;       &lt;span class="c1"&gt;// 3&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$stack&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;top&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;         &lt;span class="c1"&gt;// 3&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$stack&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;      &lt;span class="c1"&gt;// 1&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$stack&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;serialize&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;   &lt;span class="c1"&gt;// i:6;:s:1:"1";:s:1:"2";:s:1:"3";&lt;/span&gt;

    &lt;span class="c1"&gt;// retrieve items from the stack&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$stack&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 3&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$stack&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 2&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$stack&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="nv"&gt;$queue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\SplQueue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nv"&gt;$queue&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setIteratorMode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SplQueue&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;IT_MODE_DELETE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nv"&gt;$queue&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;enqueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'one'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$queue&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;enqueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'two'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$queue&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;enqueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'three'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nv"&gt;$queue&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;dequeue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nv"&gt;$queue&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;dequeue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$queue&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;top&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// three&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Stacks are widely used in the analysis or processing of nested data structures, in particular in the calculation of mathematical expressions.&lt;br&gt;
Queues could be used when processing the lists of "jobs" or some tasks, as parsing the text input in the form of a list of individual elements, normalizing it in one cycle, and then process the normalized list in the other.&lt;/p&gt;
&lt;h3&gt;
  
  
  Heaps
&lt;/h3&gt;

&lt;p&gt;Heaps are complete binary tree structures, that should satisfy heap-order property: each node is greater than or equal to the data stored in its children. Each level of a tree is completely filled, except possibly the bottom level (at this level it is filled from left to right).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnj0m43ittdx9zb5ze1tr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnj0m43ittdx9zb5ze1tr.png" alt="A properly constructed heap binary tree" width="787" height="211"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;SplHeap&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SplMaxHeap&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SplMinHeap&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SplPriorityQueue&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;SplHeap&lt;/code&gt; is a heap represented as a binary tree, each node of which has no more than two child nodes. This is an abstract class that requires an implementation of the &lt;code&gt;compare()&lt;/code&gt; method, which allows real-time sorting while inserting new nodes into a tree.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjyu88wempho9ydfzqiq9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjyu88wempho9ydfzqiq9.gif" alt="Read heap tree" width="780" height="493"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="nv"&gt;$heap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\SplMaxHeap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nv"&gt;$heap&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'111'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$heap&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'222'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$heap&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'333'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$heap&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;extract&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 333&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$heap&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;extract&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 222&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$heap&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;extract&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 111&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$heap&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;extract&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Exception: Can't extract from an empty heap&lt;/span&gt;

    &lt;span class="nv"&gt;$heap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\SplMinHeap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nv"&gt;$heap&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'111'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$heap&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'222'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$heap&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'333'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$heap&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;extract&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 111&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$heap&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;extract&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 222&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$heap&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;extract&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 333&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$heap&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;extract&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Exception: Can't extract from an empty heap&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;SplMaxHeap&lt;/code&gt; and &lt;code&gt;SplMinHeap&lt;/code&gt; are concrete implementations of the abstract class &lt;code&gt;SplHeap&lt;/code&gt;. &lt;code&gt;SplMaxHeap&lt;/code&gt; implements the &lt;code&gt;compare()&lt;/code&gt; method so that the tree is sorted in descending order of node values, and &lt;code&gt;SplMinHeap&lt;/code&gt; is in ascending order of values.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo9mrgg597g95orbna735.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo9mrgg597g95orbna735.png" alt="Min heap and Max heap" width="800" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SplPriorityQueue&lt;/code&gt; is a queue similar to &lt;code&gt;SplHeap&lt;/code&gt;, but unlike &lt;code&gt;SplHeap&lt;/code&gt;, sorting based on the value of the &lt;code&gt;priority&lt;/code&gt; property assigned to each node.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="nv"&gt;$queue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\SplPriorityQueue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nv"&gt;$queue&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setExtractFlags&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SplPriorityQueue&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;EXTR_DATA&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// extract only values of elements&lt;/span&gt;

    &lt;span class="nv"&gt;$queue&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Q'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$queue&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'W'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$queue&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'E'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$queue&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'R'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$queue&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'T'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$queue&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Y'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nv"&gt;$queue&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;top&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$queue&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$queue&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;current&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 
        &lt;span class="nv"&gt;$queue&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;//YTREWQ&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Arrays
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;SplFixedArray&lt;/code&gt; is an array of fixed length, the indixes of which can be only &lt;strong&gt;integers&lt;/strong&gt; (which are greater than or equals 0). These restrictions provide a higher processing speed of the array, which is achieved, due to the fact that in &lt;code&gt;SplFixedArray&lt;/code&gt; there &lt;strong&gt;is no hashing of the keys&lt;/strong&gt; of the elements when they are added (in contrast to the usual arrays). The length could be changed, but this is a costly operation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Map
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;SplObjectStorage&lt;/code&gt; is an object storage, that provides an interface for mapping objects to data, or can be used as a container for multiple objects. Allows you to use an object as a key of associative array and associate it with some data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$storage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\SplObjectStorage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nv"&gt;$o1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\stdClass&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nv"&gt;$o2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\stdClass&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nv"&gt;$storage&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;attach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$o1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$storage&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$o1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// bool(true)&lt;/span&gt;
&lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$storage&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$o2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// bool(false)&lt;/span&gt;

&lt;span class="nv"&gt;$storage&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;detach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$o1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$storage&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$o1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// bool(false)&lt;/span&gt;
&lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$storage&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$o2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// bool(false)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$storage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\SplObjectStorage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nv"&gt;$object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;\stdClass&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nv"&gt;$storage&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$object&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"data from object"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$storage&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$object&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c1"&gt;// data from object&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;PHP isn't C. That’s all you should remember while working with data. You can't expect that a super dynamic language like PHP has the same highly efficient memory usage that C has. But if you do want to save memory you could consider using an SPL for large, static arrays.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Interesting in reading more about PHP? Follow &lt;a href="https://blog.larapulse.com/php" rel="noopener noreferrer"&gt;this link&lt;/a&gt; to find more articles 😉&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>php</category>
      <category>spl</category>
      <category>datastructures</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
