- Quick Start Guide
- Change Log
- Authorship and Credits
- PHP Application Development Excercise: Detailed Overview
- Task Description
A REST API1 written in PHP. It computes the Mean, Mode, Median, and Range (MMMR) of any set of numbers.
Test the public-facing web interface here. Alternatively, access the API endpoint from the command line or your app with the following parameters:
- Display Results as Raw Curl Output:
curl -d '{"numbers":[ 5, 6, 8, 7, 5 ]}' https://phonegrid.net/numbers/mmmr
- Display Results as Beautified JSON Output:
curl -d '{"numbers":[ 5, 6, 8, 7, 5 ]}' https://phonegrid.net/numbers/mmmr | python -m json.tool
The numbers to be analyzed may be separated by comma, whitespace, or both as shown above.
This repo is regulary maintained and is available on Github as well as Bitbucket.
1. Exposed user interface and API endpoint to the public. Also installed an SSL certificate on public server using LetsEncrypt
2. Updated DocBlock in class-statistics.php
with instructions on how to use the class
3. Corrected calculation of the median in class-statistics.php
4. Best Practice: Moved PHP class files to src/
and deleted the inc/
folder
5. Best Practice: Made computed properties private for encapsulation purposes. Accessing of computed properties are now only allowed via setter and getter methods. To illustrate:
public $array_of_numbers; // this can be private. user modifying this adds no value
public $submission_type; // auto-sent by mmmr.php. Expected values: 'web-client' or 'API'
/*
* The below properties may alternatively be declared as 'protected'
* if inheritance (and manipulation) by child classes is needed
*/
private $mean;
private $mode;
private $median;
private $range;
private $statistics_array;
6. Implemented unit testing and continuous integration into project workflow:
-
Installed composer and created a
tests/
folder for automated unit testing with PHPUnit. See the DocBlock inStatisticsTest.php
to learn how to deploy PHPUnit on your development box -
Added
.travis.yml
(i.e., the travis-ci configuration file) to automate unit testing
Some of the most interesting updates are the use of Continous Integration (CI) tools. CI is a software development workflow process which automates build creation and code testing. These are the CI tools used in this project:
-
PHPUnit: testing of object oriented PHP code. All method tests and expected results are manual specified in a test file ending in
Test.php
-
Travis CI: at the most basic level, it tests your under various deployment environments. It then alerts developers of bugs, quality issues, and failures.
-
Better Code Hub: a code review tool that checks your GitHub codebase against 10 engineering guidelines devised by the authority in software quality, Software Improvement Group.
This PHP Rest API along with this README
file was developed by Marcus B. as a part of a code challenge he was asked to complete in January 2016. He has donated it to Code Sport for use in our small group, classroom instruction.
The rewrite-rules were found back in 2013 from an unknown website, and have been reposted below in Part 3, Rewrite Rules.
This repo is available on Github and Bitbucket
Demonstrates understanding of Object Oriented PHP and structured application development. Naming conventions and formatting syntax strongly adheres to the WordPress Coding Standards. Tested and uploaded to a live LAMP server. Below are the two main files used along with the rewrite rules for "pretty" urls.
src/class-statistics.php This is the Phase 1 request and contains a single class called Statistics. It serves as an Obect Oriented Programming (OOP) demonstration using built-in PHP array functions. Extra verbose commenting is used as this excercise will be used in future teaching session.
mmmr.php This is the Phase 2 request and is an API accepting POST requests that are either JSON or comma-space separated strings.
- Converts JSON object to PHP array
- Sends array to Statistics Class
- Converts array output from Statistics Class to JSON object
- Echoes JSON object to stdout (terminal)
- Converts string of numbers (e.g. 2, 4, 5 7 9 2) to PHP array. Accepts comma AND space delimited or just space delimited numbers
- Sends array to Statistics Class
- Echoes Class output to stdout (terminal)
-
Ancillary Functionality: For testing and proof-of-concept pruposes, the application was first bulit using a View (i.e., an AJAX-ified web form) contained within an
index.php
file. However, this backend-end form processing logic has been left insidemmmr.php
after project completion. The "leftover" form processing logic may aid in using this excercise as a platform for other applications as well as for educational purposes. See.gitignore
for the full list of testing files used. -
Core Functionality: The Core API functionallty is controlled by this block of code:
} else { //API on!
$data_stream = file_get_contents('php://input'); //capture incoming data stream
if ( is_JSON( $data_stream ) ) {
$array_of_numbers = json_decode( $data_stream, true );
//print_r($array_of_numbers['numbers']);
$statistics_for_api = new Statistics( $array_of_numbers['numbers'], 'API' );
$server_response['result'] = $statistics_for_api->get_all_statistics();
echo json_encode( $server_response );
} else {
generate_500_error();
}
}
Rewrite used for deploying on a live server are below. These rules manage extensionless files names.That is, the api may be accessed via /mmmr
.
RewriteEngine On
RewriteBase /
# remove .php; use THE_REQUEST to prevent infinite loops
RewriteCond %{THE_REQUEST} ^GET\ (.*)\.php\ HTTP
RewriteRule (.*)\.php$ $1 [R=301]
# remove index
RewriteRule (.*)/index$ $1/ [R=301]
# remove slash if not directory
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /$
RewriteRule (.*)/ $1 [R=301]
# add .php to access file, but don't redirect
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_URI} !/$
RewriteRule (.*) $1\.php [L]
A client has asked you to write a simple PHP library that will calculate the mean, median, mode, and range of a set of numbers. Your methods should accept an array of numbers and implement methods for mean, median, mode and range independently. All returned values should be rounded to a maximum of 3 decimal places. If a return value does not exist, your methods should return NULL.
Your client has asked you to make this library available via an API. Your API should implement a single endpoint called "/mmmr" with no query string parameters. When a POST request is called to "/mmmr", a single JSON object will be passed with an attribute called "numbers". "numbers" is a JSON array of n numbers that should be processed. The script should process the mean, median, mode and range of the numbers and return back a JSON object.
- If any value does not exist, an empty string should be returned.
- Any system errors should be handled gracefully with a JSON response and a 500 error.
- If a request is sent to "/mmmr" that are is not a POST request, a JSON response and a 404 error should be returned.
1 Representational State Transfer Application Programming Interface