When developing web applications, it is sometimes necessary to capture and replicate a particular request in order to debug and fix a problem. This is especially true when integrating with third-party applications, where it can be challenging and time-consuming to reproduce a specific scenario. If the errors are sporadic, capturing all relevant data to a file will allow the developer to review the log afterward to match the incident time with the suspect form parameters.
Using the tools outlined in this article, it is possible to fully capture the GET and POST variables sent to a form, and reproduce them later for repetitive debugging. The form sniffer consists of two components – the data logger and the data simulator.
The data logger is relatively straightforward:
$debug_log_path = '/data/debug.txt';
$postdata = file_get_contents("php://input");
$getdata = $_SERVER['QUERY_STRING'];
if($getdata) debug_log('GET: '.$getdata);
if($postdata) debug_log('POST: '.$postdata);
Using the “php://input” custom stream, it is possible to save the full POST header to a string variable. The full set of GET variables can be accessed through the $_SERVER collection. The “debug_log” helper function is used to append the time to any logged data, and simplify future logging operations.
A few possible changes may be necessary for the specific implementation. If the script will be used on multiple web pages, it would be useful to log the page URL dynamically. In addition, if user authentication or cookies are used, it is possible to log that information into the log file as well. If the debug logging will be used for an extended period of time, it is recommended to log to a rotating file based on the current date or time. Finally, for complex debugging situations, it may be necessary to download the full set of HTTP headers to the log file.
Once the target form parameters have been captured, the next step is simulation. At this point, logging should be disabled, and the following code should be added to the top of the destination page:
$debug_post = '[full POST string from log]';
$debug_get = '[full GET string from log]';
parse_str ( $debug_post, $_POST );
parse_str ( $debug_get, $_GET );
If only one of the GET or POST collections is used, the other section can be commented. This code will parse the input string, and populate the appropriate variables in the $_GET and $_POST, effectively simulating the same situation that initially caused the error. The rest of the form should execute as usual, and the page can be called in the browser without any parameters. This simplifies debugging, as errors can be displayed directly to the browser window without requiring complex logging.
These two tools – the data logger and data simulator, can be a useful addition to any PHP tool chest, aiding in debugging complex third-party interactions and resolving challenging integration issues.
Written by Andrew Palczewski
About the Author
Andrew Palczewski is CEO of apHarmony, a Chicago software development company. He holds a Master's degree in Computer Engineering from the University of Illinois at Urbana-Champaign and has over ten years' experience in managing development of software projects.