Skip to content

Commit

Permalink
feat: add support for passing in a request method or URL to simulate
Browse files Browse the repository at this point in the history
  • Loading branch information
rkaiser0324 committed Feb 8, 2022
1 parent e9025f0 commit aa35d14
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 13 deletions.
36 changes: 25 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
# php-fpm-cli

Running PHP-FPM, especially for website hosts using NGINX, is missing an important functionality to execute PHP scripts directly from the command-line.
Running PHP-FPM, especially for website hosts using NGINX, is missing the important ability to execute PHP scripts directly from the command-line while simulating the website context.

With this simple script, one can execute PHP scripts directly from CLI. It is convenient to test PHP in CLI, run batch operations with PHP and for cronjobs.
With this simple script, one can execute PHP scripts that are normally called via PHP-FPM, directly from CLI. This can be used for testing, batch operations, or cronjobs.

This script is based on [Mathias Leppich's gist][1], with added support for loading the script from a file (instead of input code as CLI argument), query-string parameters and verification of not only the exit code of the script - but also http-status-code.
This script is based on [Mathias Leppich's gist][1], with added support for:
* loading the script from a file (instead of input code as CLI argument)
* query-string parameters
* verification of not only the exit code of the script, but also http-status-code.
* guessing of `$_SERVER` variables given a URL to simulate

See more details in: https://elisegev.medium.com/running-php-fpm-in-cli-e1f0f4b4f59a
See more details in [this Medium post](https://elisegev.medium.com/running-php-fpm-in-cli-e1f0f4b4f59a).

## Requirements

Expand All @@ -24,7 +28,7 @@ apt-get install libfcgi0ldbl

### Setup

PHP script needs to be executable and owned by an allowed user (ACL):
The PHP script being executed needs to be executable and owned by an user allowed by the PHP-FPM configuration, so you may need to update it:
```shell script
vi /etc/php-fpm.d/www.conf
# add your ACL user to the comma-delimited list: listen.acl_users
Expand All @@ -34,19 +38,29 @@ systemctl restart php-fpm

## Usage

Run PHP script:
The script will send the given PHP file to the PHP-FPM process and echo the response to STDOUT.

```shell script
./php-fqm-cli -f <path_to_php_file>
./php-fpm-cli -f </path/to/php/file> -q "<query_params>" [-connect <connection>] [-m <GET|POST>] [-u <URL>]
```

Run PHP script with query params:
Parameters:
| Flag | Description | Default | Example |
| ---- | ----------- | ------- | ------- |
| `-f` | Path to the PHP file | | `/var/www/html/index.php` |
| `-connect` | PHP-FPM host and port, or path to a socket | `/run/php-fpm/www.sock` | `127.0.0.1:9000` |
| `-m` | Request method, GET or POST | GET | |
| `-u` | URL to simulate. This must return an status code 200, so make sure this is the canonical URL (i.e., it will not redirect) | | `https://www.mydomain.com/` |


Using query parameters:
```shell script
./php-fqm-cli -f <path_to_php_file> -q "<query_params>"
./php-fpm-cli -f myscript.php -q "param1=val1&param2=val2"
```

Example:
Using a URL:
```shell script
./php-fqm-cli -f myscript.php -q "param1=val1&param2=val2"
./php-fpm-cli -f /var/www/html/index.php -connect 127.0.0.1:9000 -u https://www.mydomain.com/
```

[1]: https://gist.github.com/muhqu/91497df3a110f594b992
59 changes: 57 additions & 2 deletions php-fpm-cli
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,67 @@ Options:
-f <code> Run PHP file without using script tags
-q <code> query string for running the php file
-q <code> Query string for running the php file
-m <GET|POST> request method
Default: GET
-u <url> Full URL to simulate; this will try to set $_SERVER variables appropriately.
Only PHP files directly under the document root are currently supported.
You may need to include "/index.php" since we don't have use of Apache
RewriteRules.
example: https://www.mydomain.com/index.php
USAGE
}

main() {
res=0

if [ -n $PHP_URL ]
then
# URL parsing code from https://stackoverflow.com/a/6174447/1282424

# extract the protocol
proto="$(echo $PHP_URL | grep :// | sed -e's,^\(.*://\).*,\1,g')"

if [[ $proto =~ https ]]
then
https="on"
fi;

# remove the protocol -- updated
url_no_proto=$(echo $PHP_URL | sed -e s,$proto,,g)

# extract the user (if any)
user="$(echo $url_no_proto | grep @ | cut -d@ -f1)"

# extract the host and port -- updated
hostport=$(echo $url_no_proto | sed -e s,$user@,,g | cut -d/ -f1)

# by request host without port
host="$(echo $hostport | sed -e 's,:.*,,g')"

# by request - try to extract the port
port="$(echo $hostport | sed -e 's,^.*:,:,g' -e 's,.*:\([0-9]*\).*,\1,g' -e 's,[^0-9],,g')"

# extract the path (if any)
path="$(echo $url_no_proto | grep / | cut -d/ -f2-)"

# Assume the document root is the directory containing $PHP_FILE_PATH
document_root=`dirname $PHP_FILE_PATH`
fi;

#Execute PHP
SCRIPT_NAME=/$path \
DOCUMENT_ROOT=$document_root \
HTTP_HOST=$host \
SERVER_NAME=$host \
REQUEST_URI=/$path \
SCRIPT_FILENAME=$PHP_FILE_PATH \
HTTPS=$https \
QUERY_STRING=$PHP_QUERY_STRING \
REQUEST_METHOD=GET \
REQUEST_METHOD=$PHP_REQUEST_METHOD \
cgi-fcgi -bind -connect "$CONN" > $TMP_OUTPUT_FILE_PATH #without dumping to file, cgi-fcgi hides "Status"

#Get successful-execution indications
Expand All @@ -68,6 +117,8 @@ main() {
CONN="/run/php-fpm/www.sock"
PHP_FILE_PATH=""
PHP_QUERY_STRING=""
PHP_URL=""
PHP_REQUEST_METHOD="GET"
TMP_OUTPUT_FILE_PATH="/tmp/php_fpm_cli_output.tmp"
init() {
until [ -z "$1" ]; do
Expand All @@ -78,6 +129,10 @@ init() {

-q) shift; PHP_QUERY_STRING="$1"; shift; ;;

-m) shift; PHP_REQUEST_METHOD="$1"; shift; ;;

-u) shift; PHP_URL="$1"; shift; ;;

help|-h|-help|--help)
usage;
exit 0
Expand Down

0 comments on commit aa35d14

Please sign in to comment.