The Magic of One Click: How Does Postman Turn into Curl?
\n\nEveryone who has worked with APIs knows this situation: you set up the perfect request in Postman, everything works like clockwork, and then you need to pass this request to a colleague or embed it in a PHP script. You click "Code" → select cURL → and get a ready-made command. Magic? No, pure math and parsing.
\n\nBut what if you need to automate this process? Or write your own converter that turns a JSON request description into an executable curl on the fly? Today we'll look under the hood of this mechanism and write a PHP function that does the same thing as Postman — but with our own hands.
This material will be useful not only for backend developers but also for anyone who wants to understand more deeply how HTTP requests work and how to convert them from one format to another. Let's go!
\n\nWhat is "Postman to Curl" Really?
\n\nWhen you click the export button in Postman, the program does a simple but important thing: it takes a structured description of the request (method, URL, headers, body) and translates it into command-line syntax.
\n\nEssentially, this is a request conversion from one representation to another. Postman stores requests in its internal JSON model. When you select cURL, it iterates through this model and assembles a string like:
\n\ncurl --request POST \\\n --url https://api.example.com/data \\\n --header 'Content-Type: application/json' \\\n --data '{"key":"value"}'\n\nEverything ingenious is simple. But let's break down how this works at the code level.
\n\nCreating Our Own Converter in PHP
\n\nWe'll write a class PostmanToCurl that takes an associative array with request parameters and returns a string with a ready-made curl command. This will be our mini conversion engine.
Step 1. Define the Input Data Structure
\n\nFor simplicity, let's agree that the input is an array with keys: method, url, headers (associative array), body (string or array). This is the minimal model that Postman uses.
<?php\n\n$request = [\n 'method' => 'POST',\n 'url' => 'https://api.example.com/users',\n 'headers' => [\n 'Content-Type' => 'application/json',\n 'Authorization' => 'Bearer token123'\n ],\n 'body' => json_encode(['name' => 'John', 'email' => 'john@example.com'])\n];\n\nStep 2. Write the Assembly Function
\n\nThe main logic: take the method, URL, headers, body — and glue them into a command. Pay attention to escaping quotes and special characters.
\n\nfunction generateCurlCommand(array $request): string {\n $parts = ['curl'];\n\n // 1. Method (if not GET)\n if (strtoupper($request['method']) !== 'GET') {\n $parts[] = '--request ' . strtoupper($request['method']);\n }\n\n // 2. URL\n $parts[] = '--url ' . escapeshellarg($request['url']);\n\n // 3. Headers\n foreach ($request['headers'] as $key => $value) {\n $parts[] = '--header ' . escapeshellarg($key . ': ' . $value);\n }\n\n // 4. Request body\n if (!empty($request['body'])) {\n $parts[] = '--data ' . escapeshellarg($request['body']);\n }\n\n return implode(" \\\\\\n ", $parts);\n}\n\nThe escapeshellarg function is your best friend. It properly escapes quotes, preventing command breakage and potential injections.
Under the Hood: What Postman Actually Does
\n\nNow that we have working code, let's break down exactly how Postman (and our converter) processes each element of the request.
\n\n1. HTTP Method
\nPostman checks if the method differs from GET. If so, it adds the --request flag. Why not for GET? Because cURL makes a GET request by default if not specified otherwise. Sma